【问题标题】:How to generate import LIBs from OBJS using msbuild如何使用 msbuild 从 OBJS 生成导入 LIB
【发布时间】:2018-08-02 18:39:53
【问题描述】:

我正在将一个古老的 C/C++ 构建系统从 VC98 转换为 VS2017。我们使用了我们自己的自定义 makefile,但现在我想使用标准的 VS2017 项目从命令行进行自动构建。引入代码不是问题。问题在于我们的旧构建系统以及我们之前如何构建东西以解决循环依赖关系 (CD)。 不要让我开始删除这些循环依赖项。 :-) 我知道它们很糟糕,但删除它们将是一项非常艰巨的任务。

我们有两个主要步骤:制作 shared_lib 和制作全部。 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 生成导入库 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 处于控制之中(而不是我)。

【问题讨论】:

  • 所以,我偶然发现了 Microsoft.Cpp.Common.props 中的 $(GenerateImportLib)。当设置为 true 时,它​​将在执行链接之前生成导入库。这专门用于解决循环依赖关系 - 这接近我所需要的。所以,我可以生成 A.LIB,但它无法生成 A.DLL b/c 我还没有生成 B.LIB。我想避免它无法生成 A.DLL 的错误。有什么想法吗?在我完成所有工作之前,我可以阻止链接发生吗?
  • 您应该只需要手工制作一个调用解决方案或多个项目文件的 MSBuild 文件。不要更深入并自己调用 CL 和 Link。如果你在做后者,那就是有问题。在这种情况下,您需要退后一步,并可能进行多次传球。首先通过制作静态库。第二遍做其他事情。而且,您可以直接控制所有内容的编译位置。之后不要复制文件。这只是普通的低效。
  • 谢谢。我在复制到 LIB 文件夹时说错了。是的,我们确实指定了在适当的公共 LIB 文件夹中构建 LIB 的正确选项。是的,使用这个 $(GenerateImportLib) 选项意味着我们需要进行多次传递——这就是我们在旧系统中所做的。但是现在第一遍会产生错误。这不是世界末日,但我想找到一种方法来避免 A.DLL b/c 上的链接器错误,我们还没有 B.LIB(在第一遍中)。第二遍将在构建 A.DLL 时成功。
  • 如果你把自己画到一个角落里,唯一的出路就是穿过油漆。是时候修复你写的那种相互依赖了。

标签: c++ makefile msbuild visual-studio-2017


【解决方案1】:

所以,这就是我所做的...我使用 $(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 时),因为我没有做链接。

【讨论】:

    猜你喜欢
    • 2019-11-06
    • 1970-01-01
    • 2019-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-27
    • 1970-01-01
    相关资源
    最近更新 更多