16

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?

  • 1
    Are you having different "version" (like one threaded, one static, etc.) of the same library, or is it multiple really different libraries all put into a single directory? – Some programmer dude Jun 27 '16 at 12:17
  • Multiple different libraries –  Jun 27 '16 at 12:18
  • For linux (at least Debian and Kubuntu with siblings), install apt-file and try 'apt-file search'. I hope the rpm-based distros like suse and redhat have something similar. – Erik Alapää Jun 27 '16 at 12:19
  • 2
    Use `dump` utilities described, for example, [here](http://stackoverflow.com/questions/1237575/how-do-i-find-out-what-all-symbols-are-exported-from-a-shared-object) and [here](http://stackoverflow.com/questions/305287/how-to-see-the-contents-of-windows-library-lib) – mvidelgauz Jun 27 '16 at 12:21
  • 1
    Linux: strings libName.so | grep symbol (maybe a more sophisticated script) –  Jun 27 '16 at 12:25
  • 6
    If you have multiple different and unrelated libraries in a single non-system directory, and don't know which one to use, then I think you have a bigger problem. If you know what you are supposed to do, you have your requirement, your design, then you find the libraries that will help you reach the goal of your program, and you ***should know*** what libraries you are using and therefore which ones to link with. – Some programmer dude Jun 27 '16 at 12:29
  • when linker say about unresolved external symbols - it print it name( in decorated and undecorated form) - need binary search this name(root of name) in ANSI form in libraries. if you not mistake with function declaration (including calling conversions, c or c++ mangling) - decorated function name must exactly in this form in library found (possible with "__imp_" prefix), however some time was mistake in function declaration - in this case - you found only root of name in library, but with another decoration – RbMm Jun 29 '16 at 12:29

4 Answers4

5

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.

Community
  • 1
  • 1
Ranger Wu
  • 401
  • 2
  • 6
2

"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.

iammilind
  • 68,093
  • 33
  • 169
  • 336
0

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

Community
  • 1
  • 1
Alexandr
  • 154
  • 1
  • 7
0

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.

Garf365
  • 3,619
  • 5
  • 29
  • 41
apoh
  • 31
  • 4