Does order of libs matter?

Hi

I observed that the order of the libraries
in the link command seems to matter:

Whereas this order works
1
2
3
4
----8X-------
	-L $(GEOINFO)  -lGeoInfo \
	-L $(COMMON)   -lCommon \
-----8X------
this oder does not:
1
2
3
4
----8X-------
	-L $(COMMON)   -lCommon \
	-L $(GEOINFO)  -lGeoInfo \
----8X-------
the error being several lines of the form
../geoinfo/libGeoInfo.a(GridProjection.o): In function `calcArcPlane(double, double, double, double, Vec3D**)':
/home/jody/newprogs/QHG2/geoinfo/GridProjection.cpp:199: undefined reference to `Vec3D::Vec3D(double, double, double)'
/home/jody/newprogs/QHG2/geoinfo/GridProjection.cpp:200: undefined reference to `Vec3D::Vec3D(double, double, double)'
...

(where 'Vec3D' is in libCommon.a, and GridProjection is in libGeoInfo.a)

- Should the order of the libraries really matter?
- If this is he case, how can i determine the correct order without experimenting?
- Why does it work if the library containing Vec3D comes after the library referencing it?
(And, by the way, why do the error messages talk about GridProjection.cpp instead of GridProjectio.o?)

Thank You
Jody
Last edited on
- Should the order of the libraries really matter?

Yes.

- If this is he case, how can i determine the correct order without experimenting?

One should know the dependencies of all of the libraries one uses. What you are doing is "software engineering" after all. Dependency management is a key part of this discipline.

- Why does it work if the library containing Vec3D comes after the library referencing it?

Because the linker builds up lists of unresolved dependencies and tries to resolve them. It only processes one file at a time. When the linker links in libCommon, it is just resolving the known, unresolved dependencies at that point in time. And then it forgets everything about libCommon that wasn't needed at that point. When it gets to libGeoInfo, new unresolved dependencies appear.

(And, by the way, why do the error messages talk about GridProjection.cpp instead of GridProjectio.o?)

Because it is trying to be helpful by pointing out what line number in the source file is referencing the unresolved symbol.
Remember that the linker throws away the symbols it doesn't need. So in your second case it reads libCommon, sees Vec3D, sees that it's not needed (nothing references it yet) and throws it away. It then gets to libGeoInfo, makes a note that it's now looking for Vec3D, continues through the list of libraries until it reaches the end (obviously doesn't find Vec3D because its already processed libCommon) and gives you a missing symbol error.

This is one of those annoying linux niggles that you just have to get used to I'm afraid.

As for the error message, it is talking about GridProtection.o (first line of error) it's just using the extra information it has to help you find the error. If you take all the debugging information out of GridProtection.o then it won't be able to give you the filename/line number.
Thanks for the explanations.

I haven't yet fully digested the fact that the linker throws away the things he hasn't needed so far.

Being aware of this, i see now that it is clear that the order does matter,
and what the order should be.

Please note the fact there are compilers other than GCC which does not have this incovenience. Of course, there are not for linux platform.
Last edited on
Topic archived. No new replies allowed.