Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Visual studio MSBudioC++链接时间依赖性_Visual Studio_Msbuild_Linker - Fatal编程技术网

Visual studio MSBudioC++链接时间依赖性

Visual studio MSBudioC++链接时间依赖性,visual-studio,msbuild,linker,Visual Studio,Msbuild,Linker,我希望在以下场景中使用MSBuild提高生成的并行性: 有三个C++项目目标。第一个是称为a的静态库,第二个是称为B的动态库,它依赖于a,第三个是依赖于B的可执行C。所有项目都包含简单的源代码,没有头生成或其他诡计 此配置中没有任何东西会阻止并行编译所有转换单元,因为只有链接时才是真正的依赖项。但是,在MSBuild中设置引用和依赖项的标准方法强制A在B中开始构建任何内容之前构建所有内容,以此类推。这不必要地序列化了一些构建过程 项目和通用解决方案需要保持普通开发人员的可接近性,这意味着维护项目

我希望在以下场景中使用MSBuild提高生成的并行性:

有三个C++项目目标。第一个是称为a的静态库,第二个是称为B的动态库,它依赖于a,第三个是依赖于B的可执行C。所有项目都包含简单的源代码,没有头生成或其他诡计

此配置中没有任何东西会阻止并行编译所有转换单元,因为只有链接时才是真正的依赖项。但是,在MSBuild中设置引用和依赖项的标准方法强制A在B中开始构建任何内容之前构建所有内容,以此类推。这不必要地序列化了一些构建过程

项目和通用解决方案需要保持普通开发人员的可接近性,这意味着维护项目和构建设置应该完全可以在Visual Studio UI中实现。新库和可执行文件可能依赖于预先存在的属性表,但不需要手动编辑新项目。vcxproj文件,也不能手动写入MSBuild XML文件

我目前的想法是将所有代码从B和C转移到单独的静态库中,称为B'和C'。那么B将同时依赖于A和B’,从而允许它们并行编译。同样,由于C最终依赖于A、B'和C',这些都可以并行编译。正如预期的那样,剩下的唯一串行进程将是链接器步骤。这比我想象的要麻烦得多,也不是惯用语,尽管这不会是世界末日


我真的希望能够为项目的链接步骤创建依赖项,而不是作为项目的编译步骤的依赖项。在我熟悉的大多数其他构建系统中,这即使不是隐式的,也是微不足道的。在Visual Studio易于使用的需求下,MSBuild是否可以在C++项目中使用?如果是这样,怎么做?

最简单的方法是将三个项目放入visual studio解决方案文件中,即.*.sln。我知道这很难看,而且解决方案文件不是真正的msbuild文件。为了使其工作,还必须使用VisualStudio工具指定项目依赖项。i、 e.右键单击解决方案,选择“项目相关性…”

一旦您这样做了,在VisualStudio内部,它应该为所有项目并行执行编译步骤,但随后以正确的顺序链接它们

在命令行上,要实现相同的效果,必须将-m传递给msbuild.exe,还必须传递解决方案文件的名称


这还假设您在所有项目文件中也指定了-MP。

我发现了一个不理想的轮询解决方案,但它很有效而且很简单。在实施后的几分钟内,我们就能够将一个完整的重建从~17秒降到~14秒,并期望它能进一步下降。一旦我再次使用它,它就会更新

首先删除项目之间的依赖关系,以便它们同时生成。这将导致我们将手动修复的构建争用条件。在项目B和C至B的vcxproj底部,放置:

<Target Name="WaitForA" BeforeTargets="Link">
  <Exec Command="$(SolutionDir)Build\A.bat $(OutputPath)A.lib"/>
</Target>

我不完全确定我是否在跟随;我的所有项目都在一个.sln文件中,但它们并不是完全并行构建的。你是说我只需要使用项目依赖项,而不需要使用链接引用吗?这种方法在完全重建的情况下有效,但在执行部分构建、非并行构建和错误的情况下存在许多问题。致力于解决这些问题。至少说明了构建性能提高的可能性。我对这个答案不太满意,所以最终使用LoadLibrary和GetProcAddress延迟加载所有依赖项。这允许并行构建
param([string] $file)

$sleeps = 0
while($true)
{
    try
    {
        $lock = [System.IO.File]::Open($file,'Open','ReadWrite','None');
        $lock.dispose();
        break;
    }
    catch
    {
        $sleeps = $sleeps + 1
        Start-Sleep -m 100
    }
}

Write-Host ("Slept {0} times waiting for '{1}'" -f $sleeps,$file)