Reputation:
Suppose we have several header and library files in the same directory. If I don't know which library I should link against, can I programmatically determine which library must be used.
Lets say I tried to compile my code, and the linker complained about unresolved external symbols, Is there anything I can do, knowing that the correct library exists in the same directory?
Upvotes: 16
Views: 2182
Reputation: 31
I have been learning more C++ recently and I had a similar question. Most libraries and headers seem to at least share a similar name, but the differences between "libm" and "math.h" really got me wondering how to more systematically determine this.
For both static and dynamic libraries, a tool I found helpful is readelf
and the command I like is this:
readelf --symbols <elf_file> | sed -ne '/FUNC/p'
So for my motivating example:
$ readelf --symbols /lib/libm.so.5 | sed -ne '/FUNC/p'
2: 0000000000000000 476 FUNC WEAK DEFAULT UND __cxa_finalize@FBSD_1.0 (8)
4: 0000000000000000 62 FUNC GLOBAL DEFAULT UND __isinf@FBSD_1.0 (8)
5: 0000000000000000 310 FUNC GLOBAL DEFAULT UND ldexp@FBSD_1.0 (8)
6: 0000000000000000 41 FUNC GLOBAL DEFAULT UND __isinff@FBSD_1.0 (8)
9: 0000000000000000 8 FUNC GLOBAL DEFAULT UND __tls_get_addr@FBSD_1.0 (8)
11: 0000000000000000 16 FUNC GLOBAL DEFAULT UND __stack_chk_fail@FBSD_1.0 (8)
12: 0000000000000000 53 FUNC GLOBAL DEFAULT UND __isinfl@FBSD_1.0 (8)
14: 0000000000000000 84 FUNC GLOBAL DEFAULT UND memset@FBSD_1.0 (8)
16: 0000000000004ed0 6 FUNC GLOBAL DEFAULT 12 lrintf@@FBSD_1.0
17: 0000000000019930 405 FUNC GLOBAL DEFAULT 12 log10l@@FBSD_1.3
18: 0000000000016590 600 FUNC GLOBAL DEFAULT 12 floorl@@FBSD_1.0
...
This command also works for ar
archive files like libcurl.a.
So here you can see the functions defined in the library. From there I visually compared the names in the final column like "log10l" with the ones in the header file /usr/include/math.h and found a high correspondence. It seems feasible to me to write a program based on this. Parse the final column of the readelf command above, and do a grep for all .h
files in /usr/include. I did not take it that far, though.
After doing some experiments related to my answer, I found that the sed
command could probably be refined a bit more for your needs as well. When I used readelf
on libcurl.a, non-global functions (so, ones that do not need to be included in header files) are also output.
Upvotes: 0
Reputation: 401
I think the answer of this question may help you a lot: Tools for inspecting .lib files?.
You may write a simple script, which loop through all lib files in the directory, and call dumpbin to dump symbols of all the libs out to a file started with the lib name, so later you can search symbol you need in the generated file to get the correct lib.
Upvotes: 5
Reputation: 164
Maybe its better to use the dll GetProcAddress function in C++ or if you write lib itself you can add code in header like this: '#'pragma comment( lib, "libname.lib" ) hope its help
Upvotes: 0
Reputation: 69988
"Can I programmatically determine which library must be used."
Not within the same program/codebase. The "programmatic" (say template
tricks etc.) ability remains till the compilation stage. Once the linking starts (as of today), the control is gone.
"Is there anything I can do, knowing that the correct library exists in the same directory?"
Again No. I don't intend to demotivate you, but what you are asking is not going to be helpful anyways. Suppose, somehow you manage to find a way to know if the library exists in the same directory. What purpose will it serve? Because practically a library can reside in any path. One has to simply set the path variables in the MSVC or -L
option in gcc. So the question of having the library in the same directory is moot.
Probably you may want to ask, how to know if the library exists in your system & where.
Well, this is ofcourse not possible programmatically in the same code base. Because you have to run that codebase to find if the library exists somewhere in your system. To run that codebase, you have to link it. Chicken-Egg problem.
Either you check manually or write your own separate script/code to do this task.
Upvotes: 2