共享库Side-by-Side之Windows Shared Assembly
最近在设计一个编译系统的依赖管理部分,如果一个project的dependency closure(所有直接和间接的依赖)中有某个相同的library的不同版本,我们就认为这里有一个版本冲突, 那么在检测到版本冲突的时候,是报一个warning让警告用户,还是报一个错误直接退出,要求用户先解决版本冲突呢? 事实上,无论在windows上,还是在linux中,我们都有相应的机制来保证不同版本的library是可以在同一个程序中工作的,在windows上是side-by-side assembly,通过manifest和activation context实现,而在linux下则是通过设置RPATH。 所以我们编译系统的行为应该是报一个warning,让用户判断这个版本冲突究竟是个问题,还是可以接受的,并提供机制让用户抑制这种warning - 然后,针对不同平台产生side-by-side的library。
对于底层side-by-side如何实现,这里有三个方面:
- Windows下shared assembly: 对于用VC++ build的,有CRT, ATL, MFC以及OpenMP,这些library是与compiler对应的,所以用不同版本的VC++编译时会插入不同的manifest来表明依赖的library到底是哪里来的。这个用户基本不用做什么工作。
- Windows下private assembly:用户自己的library,想要side-by-side,这个需要用户提供相应的manifest,并且library必须放置在application的子目录下面,Microsoft提供了文档
- Linux下RPath,binary中有一个section让设置RPATH,需找library的时候,会从该path找。
这里是第一个例子,Windows下shared assembly:源码地址
foo是一个DLL, 用vs2008编译,依赖于vscrt90,bar是一个exe,用vs2010编译,自然依赖于vscrt100, 另外它还依赖foo。项目都用premake描述,生成visual studio文件后用msbuild编译。
编译步骤如下:
1. build foo
* cd foo
* premake4 vs2008
* "C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat"
* msbuild foo.sln
2. build bar
* cd bar
* premake4 vs2010
* "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Tools\vsvars32.bat"
* msbuild bar.sln
3. Copy foo.dll to bar/
运行bar.exe, 然后打开procexp查看该进程:
我们可以看到, vscrt90和vscrt100的library同时被加载到同一进程。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述