共享库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同时被加载到同一进程。

posted @   lzprgmr  阅读(1013)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述

黄将军

点击右上角即可分享
微信分享提示