尝试调试一些链接器错误,我打开/ VERBOSE,我试图弄清楚输出。在我看来,我真的不知道如何阅读它。
例如:
1>Compiling version info
1>Linking...
1>Starting pass 1
1>Processed /DEFAULTLIB:mfc80.lib
1>Processed /DEFAULTLIB:mfcs80.lib
1>Processed /DEFAULTLIB:msvcrt.lib
1>Processed /DEFAULTLIB:kernel32.lib
1>Processed /DEFAULTLIB:user32.lib
....
1>Processed /DEFAULTLIB:libgslcblasMD.lib
1>Searching libraries
1> Searching V:\Src\Solutions\\..\..\\Common\Win32\Lib\PlxApi.lib:
1> Searching ..\..\..\..\out\win32\release\lib\camerageometry.lib:
1> Searching ..\..\..\..\out\win32\release\lib\geometry.lib:
1> Found "public: __thiscall VisionMap::Geometry::Box2d::operator class VisionMap::Geometry::Box2DInt(void)const " (??BBox2d@Geometry@VisionMap@@QBE?AVBox2DInt@12@XZ)
1> Referenced in FocusDlg.obj
1> Loaded geometry.lib(Box2d.obj)
1>Processed /DEFAULTLIB:CGAL-vc80-mt.lib
1>Processed /DEFAULTLIB:boost_thread-vc80-mt-1_33_1.lib
这里发生了什么?
我想我理解这一点:
1>Processed /DEFAULTLIB:libgslcblasMD.lib
1>Searching libraries
1> Searching V:\Src\Solutions\\..\..\\Common\Win32\Lib\PlxApi.lib:
1> Searching ..\..\..\..\out\win32\release\lib\camerageometry.lib:
1> Searching ..\..\..\..\out\win32\release\lib\geometry.lib:
1> Found "public: __thiscall VisionMap::Geometry::Box2d::operator class VisionMap::Geometry::Box2DInt(void)const " (??BBox2d@Geometry@VisionMap@@QBE?AVBox2DInt@12@XZ)
1> Referenced in FocusDlg.obj
1> Loaded geometry.lib(Box2d.obj)
它试图找到上面运算符的实现,它在FocusDlg.cpp中的某个地方使用,并在geometry.lib中找到它。
但1>Processed /DEFAULTLIB:libgslcblasMD.lib
是什么意思?是什么决定了符号解析的顺序?为什么在处理libgslcblasMD.lib
(第三方库)时加载此特定符号?或者我读错了吗?
似乎链接器正在浏览项目的各种目标文件中引用的符号,但我不知道它的顺序是什么。然后它搜索项目使用的静态库 - 通过项目引用,显式导入和自动默认库导入;但它是按照这样的顺序进行的,这对我来说似乎是武断的。
当它找到一个符号时,例如在geometry.lib中,它会继续从同一个lib中找到一堆其他符号:
1> Searching V:\Src\Solutions\\..\..\\Common\Win32\Lib\PlxApi.lib:
1> Searching ..\..\..\..\out\win32\release\lib\camerageometry.lib:
1> Searching ..\..\..\..\out\win32\release\lib\geometry.lib:
1> Found "public: __thiscall VisionMap::Geometry::Box2d::operator class VisionMap::Geometry::Box2DInt(void)const " (??BBox2d@Geometry@VisionMap@@QBE?AVBox2DInt@12@XZ)
1> Referenced in FocusDlg.obj
1> Loaded geometry.lib(Box2d.obj)
1>Processed /DEFAULTLIB:CGAL-vc80-mt.lib
1>Processed /DEFAULTLIB:boost_thread-vc80-mt-1_33_1.lib
1> Found "public: __thiscall VisionMap::Geometry::Box2DInt::Box2DInt(int,int,int,int)" (??0Box2DInt@Geometry@VisionMap@@QAE@HHHH@Z)
1> Referenced in FocusDlg.obj
1> Referenced in ImageView.obj
1> Referenced in geometry.lib(Box2d.obj)
1> Loaded geometry.lib(Box2DInt.obj)
1> Found "public: virtual __thiscall VisionMap::Geometry::Point3d::~Point3d(void)" (??1Point3d@Geometry@VisionMap@@UAE@XZ)
1> Referenced in GPSFrm.obj
1> Referenced in MainFrm.obj
1> Loaded geometry.lib(Point3d.obj)
1> Found "void __cdecl VisionMap::Geometry::serialize<class boost::archive::binary_oarchive>(class boost::archive::binary_oarchive &,class VisionMap::Geometry::Point3d &,unsigned int)" (??$serialize@Vbinary_oarchive@archive@boost@@@Geometry@VisionMap@@YAXAAVbinary_oarchive@archive@boost@@AAVPoint3d@01@I@Z)
1> Referenced in GPSFrm.obj
1> Referenced in MainFrm.obj
1> Loaded geometry.lib(GeometrySerializationImpl.obj)
但是,由于某种原因,它继续查找在其他库中定义的符号,并在稍后返回几何(很多次)。
很明显,它并没有“查看几何体并加载项目中引用的每个符号,然后继续使用其他库”。但是我不清楚是符号查找的顺序。
在链接器的工作开始时处理所有这些库的处理是什么,但没有找到任何符号从它们加载?该项目是否真的不使用msvcrt.lib
,kernel32.lib
中的任何内容?似乎不太可能。
所以基本上我正在寻找解码链接器操作中的基础顺序。
答案 0 :(得分:5)
搜索要链接的符号从您的应用入口点(主要或WinMain)开始。从那里链接器获取入口点所依赖的所有符号,加载它们自己的依赖项,依此类推,直到没有依赖项为止。
在较旧的链接器中,主项目中包含的任何.obj都必须链接,因此它们的依赖项应该存在于项目中以使链接成功。今天,大多数链接器删除了从未使用过的代码,即使它包含在明确链接的obj文件中。
关于1>Processed /DEFAULTLIB:libgslcblasMD.lib
:这只是意味着扫描了库文件,并将其符号附加到字典中,以便稍后将其用于依赖项解析。
解决方案发生的顺序与处理库文件的顺序无关。当链接器处理lib时,它只是将其符号添加到字典中。依赖性解析是在填充该字典之后进行的,从主入口点开始,如上所述。