24

Why is it that some static libraries (lib*.a) can be linked in the same way that shared libraries (lib*.so) are linked (ld -l switch), but some can not?

I had always been taught that all libraries, static or not, can be linked with -l..., however I've run into one library so far (GLFW), which does nothing but spew "undefined reference" link errors if I attempt to link it this way.

According to the response on this question, the "proper" way to link static libraries is to include them directly, along with my own object files, rather than using -l. And, in the case of the GLFW library, this certainly solves the issue. But every other static library I'm using works just fine when linked with -l.

So:

  • What could cause this one library to not work when linked rather than included directly? If I knew the cause, maybe I could edit and recompile the library to fix the issue.
  • Is it true that you're not supposed to link static libraries the same way you link shared libraries? (And if not, why not?)
  • Is the linker still able to eliminate unused library functions from the output executable when the library is directly included in this way?
Community
  • 1
  • 1
Nairou
  • 3,585
  • 5
  • 29
  • 47

4 Answers4

28

Thanks for the replies! Turns out the problem was due to link order. Apparently, if you use a library which in turn has other library dependencies, those other dependencies must be listed after the library, not before as I had been doing. Learned something new!

Nairou
  • 3,585
  • 5
  • 29
  • 47
  • Doesn't answer the question. Yes, it solves some specific problem which perhaps prompted you to ask this general question. Unfortunately, most people will come here to get an answer for the question as asked (and the sub-questions). – BeeOnRope Sep 23 '18 at 19:33
  • Incidentally, I googled this because I *thought* I was linking incorrectly, but it turns out the order was wrong. So, this ended up being the answer for me, too – Suchipi Dec 02 '22 at 03:52
7

Have you cared to indicate to GCC the path of your library (using -L) ? By using -l solely, GCC will only be able to link libraries available in standard directories.

-L[path] -l[lib]
Vincent L.
  • 122
  • 3
  • Yes, the paths to each library are provided using -L, before the corresponding -l flag. GCC can find the library, but gives a large number of undefined reference errors from within the library. – Nairou Mar 31 '12 at 01:40
6

The correct way to link a static library is using -l, but that only works if the library can be found on the search path. If it's not then you can add the directory to the list using -L or name the file by name, as you say.

The same is true for shared libraries, actually, although they're more likely to be found, perhaps.

ams
  • 24,923
  • 4
  • 54
  • 75
  • What's the difference though, between linking the static library with `-l` and putting in on the link line without any `-l` prefix, as `.o` are? See the questions the OP asks at the end of his question. – BeeOnRope Sep 23 '18 at 19:38
  • There's no difference, apart from skipping the search process. – ams Sep 23 '18 at 20:05
2

The reason is historical. The "ar" tool was original the file archive tool on PDP11 unix, though it was later replaced entirely by "tar" for that purpose. It stores files (object files, in this case) in a package. And there's a separate extension containing the symbol table for the linker to use. It's possible if you are manually managing files in the archive that the symbol table can get out of date.

The short answer is that you can use the "ranlib" tool on any archive to recreate the symbol table. Try that. More broadly, try to figure out where the corrupt libraries are coming from and fix that.

Andy Ross
  • 11,699
  • 1
  • 34
  • 31