2012-12-06 33 views
9

20個以上のプロジェクトがあるVS2010ソリューションファイルがあり、その中にはソリューション内の他のプロジェクトに依存するものがあります。MSBuild 4.5はプロジェクトの依存関係を無視しています

さまざまな目的で複数のビルド構成が設定されていますが、最小限のプロジェクト数だけを含めるようにビルドするプロジェクトをトリミングしました。

たとえば、3つのライブラリ(A、B、C)、Webサイトプロジェクト、およびWebサイト展開プロジェクト(VS2010)があります。 WebサイトにはライブラリAとBの参照があり、BにはCへの参照があります。私のビルド構成には、Webサイトとデプロイメントプロジェクトのみがチェックされています。ソリューションのプロパティからプロジェクトの依存関係をチェックすると、Webサイトはライブラリを正しくリストし、BはCを期待通りに表示します。

VS2010内からビルド設定に対してビルドを実行すると、完全に正常に動作しますが、自分の設定を指定するソリューションでMSBuildを実行すると、エラーが発生します。

msbuild.exe mysolution.sln /t:Build /p:configuration=MyConfig

ここで私が得るエラーの例です:

Services\IService.cs(11,63): error CS0246: The type or namespace name 'Priority' could not be found (are you missing a using directive or an assembly reference?)

私は私のビルドサーバー(チームシティーのV7.1.2)にこの出来事に気づいたが、私は複数のマシン上でそれを再現することができます私はそれをMSBuild自体の問題に絞り込んだ。

.NET 4.5(および2つのセキュリティパッチ)をインストールした後で起きているだけなので、アンインストールしてから.NET 4.0(パッチあり)を再インストールしたので、同じコマンドを試してみました。良い。

これは、.NET 4.5でMSBuildで何かが変更されたり壊れたりしたと考えていますが、ドキュメントにはこのような変更については何も言わないようです。

MSBuildの4.5ドキュメント:http://msdn.microsoft.com/en-us/library/hh162058.aspx

私もMSBuildのにBuildProjectDependencies=trueを渡して試してみた、そしてそれは彼らが正しいと意図的である構成マネージャで選択されなかったので、それが他のプロジェクトをスキップしていることを知らせるアップします。

私がMSBuild 4.5で動作させる唯一の方法は、スキップされていたプロジェクトを選択して戻すことでしたが、実際のソリューションは依存関係のチェーンでもう少し複雑なので、新しいプロジェクトや依存関係を使用してソリューションを更新するたびに、手動で設定を管理しようとします。それは自動であるべきである(SHOULD)。

私は何をしているのですか?

答えて

3

あなたはまだこの問題が解決しない場合は、いくつかのブラインドショット試すことができます:それは時々続く依存関係に基づいて、間違ったビルド順序を生成するとき

  1. MSBuildのバグを確認しています。ソリューション全体ではなく、構築したいと思う正確なプロジェクト(例えば、msbuild.exe YourWebsiteProject.csproj /t:Clean;Build /p:configuration=MyConfig)を構築してみてください。問題は依然として持続していますか?

  2. あなたのWebサイトプロジェクトとあなたのライブラリ(BとC)が適切な参照を持っていることを確認してください。プロジェクトではなく、別のプロジェクトフォルダのdllでなくてください(修正する最も簡単な方法 - Bの参照をCに置き換えて、単にプロジェクト参照を追加し、bin \ Debugには非常にC.dllを参照しないようにしてください)。それでも問題はありますか?

あなたは、詳細な、あるいは診断MSBuildのログを提供することができれば(スイッチ/ DS/v以下のあなたのMSBuildのコマンドラインに追加します。DIAGして、どこかに共有チームシティー完全なビルドログまたはファイルにパイプコマンドラインログ)またはいくつか私がこの振る舞いを再現することができるサンプルプロジェクトが設定されています。問題解決のお手伝いをすることができます。

+0

+1の2つ目の理由です。 –

+0

MSBuildに確認済みのバグがあるとはどういう意味ですか? MSDNにこの問題へのリンクがありますので、それを追跡してMicrosoftにガイダンスがあるかどうか確認してください。 –

+0

ここにいた http://connect.microsoft.com/VisualStudio/feedback/details/586875/msbuild-4-0-incorrectly-processes-project-dependencies-specified-in-solutions-file 4.5で修正されました –

2

まったく同じ問題が発生しました。私が見つけた2つの回避策は、どちらも長期的に受け入れられませんが、新しい4.5スタックを使ってビルドプロセスを古いものにするという初期の問題を克服しています。ファイル参照とプロジェクト参照が

  • 、私は#2を選んだき
  • 化合物のビルド構成を作成し、ファイルの参照が意味として、開発者は、リアルタイムのインテリセンスなどに出失うことになる

    1. スワップ

      化合物の構成は、単にこのです:

      • リリースサーバー - >すべてのサーバーのプロジェクト
      • リリース消費者 - >「リリースサーバー」+クライアントが

      をプロジェクトは、問題があれば、プロジェクトが現在の/アクティブなビルドに含まれていないこと、のようですそれが参照される依存関係として含まれないことを意味します。したがって、構成に依存関係を追加することによって、プロジェクトは少なくともコンパイルされます。

      どちらも醜いですが、少なくともそれは私を窮地から救い出してくれます。

      マット

    4

    私はこの問題に私自身の回避策を作成する多くの時間と労力を費やしてきたように、私は、私の以前の回答を更新しようと思いました。回避策は単に問題を抱えて生活するよりも少し包括的ですが、私は問題を取り除き、このような将来のショックから身を守ることを試みました。

    MSBuildは、ソリューション、コンフィギュレーションなどの作業から降格しました。 MSBuildはプロジェクトを単独でコンパイルするよう求められます。これが起きる順序は、Just-In-Timeビルドの実行計画を立てるために私たちのソリューションとプロジェクトを解析するPowershellスクリプトによって計算されます。

    これにキー(と私はあなたが参考かもしれないと思う)以下抜粋されています

    私の解決策を特定するには、私は私のプラットフォームのすべてのソリューションのリストを持っている、と私は基本的に繰り返しますこれらのそれぞれの上に。

    $buildPlan = (
    @{ 
        solutions = (
         @{ 
          name  = "DataStorage" 
          namespace = "Platform.Databases" 
         }, 
         @{ 
          name  = "CoreFramework" 
         }, 
         @{ 
          namespace = "Platform.Server" 
          name  = "Application1" 
         }, 
         @{ 
          namespace = "Platform.Server" 
          name  = "Application2" 
         }, 
         @{ 
          namespace = "Platform.Client" 
          name  = "Application1" 
         } 
        ) 
    }) 
    

    は、私は、実際の物理パスにこれを翻訳するのに役立ちますが、私たちのニーズにその非常にオーダーメイドのいくつかのロジックを持っているので、私はそれをここに表示されません。このリストから、私が解析する必要のある.slnファイルを見つけることができるとうまくいきました。各ソリューションのプロジェクト

    のためのソリューションファイルを解析

    、私はの.slnファイルを読んで、私は、後に構築する必要がありますその中に含まれるすべてのプロジェクトを展開しようとします。

    だから、まず、私の

    $solutionContent = Get-Content $solutionFile 
    
    $buildConfigurations += Get-Content $solutionFile | Select-String "{([a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12})}\.(Release.*)\|Any CPU\.Build" | % { 
         New-Object PSObject -Property @{ 
          Name = $_.matches[0].groups[3].value.replace("Release ",""); 
          Guid = $_.matches[0].groups[1].value 
          } 
    
        } | Sort-Object Name,Guid -unique 
    

    内のすべてのプロジェクトを特定し、その後、私は後で反復処理することができ、プロジェクトの素敵なリストにこれを翻訳。

    $projectDefinitions = $solutionContent | 
         Select-String 'Project\(' | 
         ForEach-Object { 
          $projectParts = $_ -Split '[,=]' | ForEach-Object { $_.Trim('[ "{}]') }; 
          $configs = ($buildConfigurations | where {$_.Guid -eq $projectParts[3]} | Select-Object Name) 
    
          foreach ($config in $configs) 
          { 
           $santisiedConfig = if ([string]::IsNullOrEmpty($config.Name)){"Release"}else{$config.Name} 
           if ($projectParts[1] -match "OurCompanyPrefix.") 
           { 
            New-Object PSObject -Property @{ 
            Name = $projectParts[1]; 
            File = $projectParts[2]; 
            Guid = $projectParts[3]; 
            Config = $santisiedConfig 
            } 
           } 
          } 
        } 
    

    ソリューションファイルの私の解析からのVisual Studioプロジェクト

    をロードし、私は今、決定的に見つけるために、ソリューションのルートからの相対ファイルパスを含む溶液あたりのプロジェクトのリストを持っていますプロジェクト。外部プロジェクトを特定

    $projectDefinition = [xml](Get-Content $csProjectFileName) 
    $ns = @{ e = "http://schemas.microsoft.com/developer/msbuild/2003" } 
    $references = @(); 
    

    1)

    $references += Select-Xml -Xml $projectDefinition -XPath "//e:Project/e:ItemGroup/e:Reference" -Namespace $ns | % {$_.Node} | where {$_.Include -match "OurCompanyPrefix" -and $_.HintPath -notmatch "packages"} | % {$_.Include} 
    

    2を参照)内部のプロジェクトを特定の外部参照として "ポスト・ビルド" のイベントに続き

    $references += Select-Xml -Xml $projectDefinition -XPath "//e:Project/e:ItemGroup/e:ProjectReference" -Namespace $ns | % { $_.Node.Name } 
    

    3)を参照

    $references += Select-Xml -Xml $projectDefinition -XPath "//e:Project/e:PropertyGroup/e:PostBuildEvent" -Namespace $ns | where {(!([String]::IsNullOrEmpty($_.Node.InnerText)))} | % { 
    
          $postBuildEvents = $_.Node.InnerText.Split("`n") 
          $projectsReferencedInPostBuildEvents = $postBuildEvents | Select-String "\(SolutionDir\)((\w|\.)*)" | % {$_.Matches[0].Groups[1].Value} 
          if ($projectsReferencedInPostBuildEvents -ne $null) 
          { 
           Write-Output $projectsReferencedInPostBuildEvents | % { $matchedProject = $_; ($releaseConfiguation | ? {$_.File -match $matchedProject}).Name } 
          } 
    
         } 
    

    そして、我々はそれをしているので、いくつかの基本的な出力情報を取得し、あまりにも

    それが構築するために、プロジェクトの私のリストを反復処理するために来るときどこの出力をプッシュするために知っているように、これは、便利です、または依存関係の出力をどこで見つけるか。

    $assemblyName = (Select-Xml -Xml $projectDefinition -XPath "//e:Project/e:PropertyGroup/e:AssemblyName" -Namespace $ns).Node.InnerText 
    $outputPath = (Select-Xml -Xml $projectDefinition -XPath "//e:Project/e:PropertyGroup[contains(@Condition,'Release|')]/e:OutputPath" -Namespace $ns).Node.InnerText 
    

    そして

    私達はちょうど私たちはどんな重複を持っていないので、私は、この特定のコードプロジェクトのちょうど明確な依存関係を記録を確認する必要があり

    それをすべての終わりに

    $dependendents = @(); 
    if ($references -ne $null) 
    { 
        $buildAction.project.dependencies += $references | where {(!([string]::IsNullOrEmpty($_))) -and ($_ -match "OurCompanyPrefix\.(.*)")} | % { $_.ToLower()} | Select -unique 
    }  
    

    これは、SLNファイルとPROJファイルを解析するのに十分な情報を提供したいと考えています。どのようにあなたが私はあなた次第であると思うこの情報をキャプチャして保存するかを選択します。

    私は、これについてかなり深いブログ記事を書いている途中です。これには、上に隠したすべてのトリミングとフレームワークが含まれています。投稿はまだ準備ができていませんが、私は以前の投稿からそれにリンクします:http://automagik.piximo.me/2013/02/just-in-time-compilation.html - Microsoftによるこの変更がこの仕事をほぼ無くしたためです!

    乾杯。 .NET 4.5では

    3

    は、CでOnlyReferenceAndBuildProjectsEnabledInSolutionConfigurationプロパティのデフォルト値:\ WINDOWS \ Microsoft.NET \ Frameworkの\ v4.0.30319ののの\ Microsoft.Common.targetsはtruefalseから変更されました。その名前が示すように、このプロパティにより、MSBuildはビルド構成から除外されたプロジェクトへの参照を無視します。

    (それは私が変更がビルドを壊すことにそれらを警告していても、MicrosoftはConnect bug I filed against MSBuild 4.0に応答して、この変更を行っている可能性があります。)

    回避策は簡単です:最初<PropertyGroup>に戻っfalseにプロパティを設定しますそれぞれのプロジェクトのセクション:

    <PropertyGroup> 
        ... 
        <OnlyReferenceAndBuildProjectsEnabledInSolutionConfiguration>false</OnlyReferenceAndBuildProjectsEnabledInSolutionConfiguration> 
    </PropertyGroup> 
    
    +0

    Connectのバグへのリンクが何らかの理由で壊れています。 Bingにはまだ[キャッシュされたバージョン]があります(http://cc.bingj.com/cache.aspx?q=OnlyReferenceAndBuildProjectsEnabledInSolutionConfiguration&d=4756437099940543&mkt=en-US&set=ja6I4RMi2T9y-j5M_jzlnbwuu4wnvbzd)。 –

    0

    この問題には複数の原因があります。私はここでほとんどのソリューションを試しました。私はPSスクリプトを使用するようにビルドサーバーを変更することはできませんので、解決策はありませんでした。私が試してみることはできませんでした。

    最後に、解決策を削除して新しいものを開始しました。新しいソリューションが機能しました。作業中の解決策と壊れた解決策を分けた後、元の解決策は欠落していることがわかりました。

    {A93FB559-F0DB-4F4D-9569-E676F59D6168}.Release|Any CPU.Build.0 = Release|Any CPU 
    

    注1:GUIDは、依存関係に依存から変わるコンパイルされないでしょう各依存性は、このラインがありませんでした。

    注2:このような行は、ソリューションファイルの「GlobalSection(ProjectConfigurationPlatforms)= postSolution」の下にあります。

    私のbuild.projファイルには、「任意のCPU」プラットフォームを使用してビルド「リリース」と記載されています。 MSBuildはこの行を見つけることができなかったので、この依存関係は構築されませんでした。この結果、 "エラーCS0246:型または名前空間が見つかりませんでした"というメッセージが表示されます。

    好奇心が強い人は、このソリューションを「x86」プラットフォームに設定していました(これは間違いです)。私はそれを "Any CPU"に変更しました(他のいくつかの変更と共に)。 Visual Studioは、対応する行をソリューションファイルに追加しませんでした。 IDEのすべてがうまく構築されましたが、MSBuildはエラーを投げ始めました。

    0

    私はMSBuildが.slnファイルで宣言されている順序でソリューションからプロジェクトをビルドしていることがわかりました。したがって、テキストエディタで並べ替えると、MSBuildの注文を修正できます。

    関連する問題