c++ - 如何使用 msbuild 从 OBJS 生成导入 LIB
问题描述
我正在将一个古老的 C/C++ 构建系统从 VC98 转换为 VS2017。我们使用了我们自己的自定义 makefile,但现在我想使用标准的 VS2017 项目从命令行进行自动构建。引入代码不是问题。问题在于我们的旧构建系统以及我们之前如何构建东西以解决循环依赖关系 (CD)。 不要让我开始删除这些循环依赖项。:-) 我知道它们很糟糕,但删除它们将是一项非常艰巨的任务。
我们有两个主要步骤:make shared_lib 和 make all。make shared_lib 会将代码编译为静态或导入库(取决于文件夹的 makefile)并将库复制到共享 LIB 文件夹。然后 make all 将构建任何二进制文件 (DLL/EXE) 并放置在一个公共 BIN 文件夹中。要进行完整构建,我们将访问 50 多个文件夹中的每一个,并在每个文件夹中创建 shared_lib。然后我们会在每个文件夹中制作所有内容。例子:
- 文件夹A生成import lib A.lib和A.dll,需要import lib B.lib
- 文件夹B生成import lib B.lib和B.dll,需要import lib A.lib
- 我们在 A 中创建 shared_lib 并从 OBJ 生成 import lib A.lib。我们还不需要 B.lib,b/c 我们只需要导入库 A.lib。
- 我们在 B 中制作 shared_lib 并生成 import lib B.lib
- make all in A 生成 A.dll 并工作 b/c 我们在上一步中有 B.lib
- make all in B 生成 B.dll
我想这可以在 VS2017 项目文件中完成,但我想知道这有多容易......我可以将预链接构建事件放入文件夹 A 项目中以生成导入库 A.lib。但是项目 A 的主要输出是 A.dll,输出类型的唯一选项(我看到的)是 DLL。但是,我无法完成链接 A.dll b/c 我还没有 B.lib。
我创建了一个包含 all 和 shared_lib 目标的项目。然后这些目标使用 LINK 和 LIB msbuild 任务。如果只是这样,那还不算太糟糕。但我还需要将这些文件编译成 OBJ。那是我遇到麻烦的地方。当然,我正在使用 CL 任务,但是我必须指定大量选项。我指定了输入和输出,它主要工作。如果我修改 CPP 文件,则只重建该文件,然后生成 LIB,然后生成 DLL - 这就是我想要的。但问题是,如果我更改了这个 CPP 文件所依赖的 .H 文件怎么办?它不知道重建 CPP 文件。这可能是我可以指定给 CL 的另一个选项,但它已经失控了......
所以,归结为:在我的大部分工作的测试项目中,我完全控制了构建过程。我不想要这个负担。我想把它留给 msbuild/VS2017 来确定哪些文件需要重建。我想做一个“msbuild foo.sln /t:shared_lib”并让 msbuild 完成所有繁重的工作。
我也许可以在不同的项目中做到这一点,但这听起来效率低下且难以自动化。我可以手工制作项目文件,但我仍然希望 msbuild 处于控制之中(而不是我)。
解决方案
所以,这就是我所做的......我使用 $(GenerateImportLib) 选项创建了 A.vcxproj。它构建 A.lib 作为构建的一部分,但当然它无法生成 A.dll b/c 我缺少 B.lib。所以,我将 A.vcxproj 复制到 A_shared_lib.vcxproj (到另一个文件夹)。然后我调整了 A_shared_lib.vcxproj 以像这样删除 Link 任务:
<Target Name="Link">
<Message Text="Not doing a Link"/>
</Target>
所以,现在 A_shared_lib.vcxproj 只构建 A.lib。配置类型仍设置为“DynamicLibrary”。而且它不会产生错误(当它找不到 B.lib 时),因为我没有做链接。
推荐阅读
- identityserver4 - 撤销的令牌和身份验证 cookie
- java - 在java中的组中生成每个请求log4j
- r - 在大型数据表上执行时,如何防止 {data.table}foverlaps 将 NA 输入到它的 any(...) 调用中?
- javascript - 为什么光滑的滑块在循环的第二次迭代中刷新滑块项的 css
- angular - Angular - 总是在请求中出现“[Object object]”错误(即使请求有效)
- yii2 - 如何获取每个类别的订单数量?
- c++ - 我的 Qt5 程序如何从控制台获取参数?
- r - R bar_geom 千位分隔符
- css - 为什么我的高程阴影在本机反应中位于错误的一侧?
- c# - 使用 Moq 模拟接口时,方法会发生什么?