In fact, I have encountered this problem before, also stressed that gnu-g++ in the link stage is dependent on the input. O or the order of. a files. If the order error causes undefined reference error
See this essay: http://www.cnblogs.com/qrlozte/p/4137704.html
What was the problem I was having just now?
Code demo.cpp: Where Zj::open_max is declared in Util.h, in $ (path_one)/LIBUTIL.A; Err_sys declared in Apue.h, in $ (path_two)/ Libapue.a, here I use $ (path_xxx) in Makefile to represent the macro value of the path
#include"apue.h"#include"util.h"#include<iostream>intMainvoid){ Const LongOpmax =Zj::open_max (); Std::cout<<"Opmax ="<< Opmax <<Std::endl; Err_sys ("Test Err_sys"); return 0;}
The compile link is successful and can be run.
Where the link command is:
g++-l$ (Path_one)-l$ (path_two)-O bin/test_exe obj/demo.o-lapue-lutil
However, if the Err_sys line of code is deleted, and then the # include "Apue.h" deleted, makefile content unchanged, will be error:
$ (Path_one)/LIBUTIL.A (UTIL.O): in function ' Zj::open_max ()': util.cpp: (. text+0x56): undefined reference To ' Err_sys (char const*, ...) '
Here, I know is: Zj::open_max in the Err_sys of the call, I do not understand is: if there is undefined reference error, I did not delete the two lines when the error? I haven't changed makefile, what's the situation?
After several times of tossing, finally found this humble mistake, is in the makefile inside:
-lapue-lutil
The correct one should be:
-lutil-lapue
Why?
Because $ (path_one)/LIBUTIL.A contains 2 functions, Zj::open_max and ZJ::p Ath_max, both of which depend on Path_two in/libapue.a
In the case of-lapue-lutil, in the link, linker first see-LAPUE, in DEMO.O also see the call to Err_sys, then linker know in $ (path_two)/libapue.a can find Err_ SYS's entrance, the same, and then linker can also know should go to $ (path_one)/LIBUTIL.A to find the entrance of Zj::open_max
However, if you delete the declaration and invocation of Err_sys in Demo.cpp, then linker cannot directly know that Err_sys can be found in Path_two, so/LIBAPUE.A begins to find linker in order- Lutil
First linker begins to check the function call in DEMO.O, and in the first line of the main function, the call to Zj::open_max is found, obviously, at this point linker view-lapue (no, so skip),-lutil (found), so Linker goes to $ ( Path_one)/libutil.a to find the entrance to Zj::open_max, and then found the call to Err_sys in Zj::open_max, but at this point, because-lapue has been skipped by linker, So linker will only continue to find in the-lutil (of course not found), and then look at the back of the-lutil there is no-l parameter (no), so error undefined reference to Err_sys ( of course, g++ Linker implementation I don't know, I'm purely speculative here, and won't go back to see if-lapue can find Err_sys (and Microsoft's CL.EXE doesn't exist).
For the-lutil-lapue situation, the above problem does not exist, because linker found-lutil can not find Err_sys, will continue to look down, thus found-lapue in Err_sys
So much nonsense, summary: With gnu-gcc/g++, the link order must not be mistaken!
Undefined reference due to link sequence errors