Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong path for build tools when multitargeting #29

Closed
daveaglick opened this issue Oct 31, 2017 · 12 comments
Closed

Wrong path for build tools when multitargeting #29

daveaglick opened this issue Oct 31, 2017 · 12 comments

Comments

@daveaglick
Copy link
Collaborator

Seeing this error on CI builds:

C:\Program Files\dotnet\sdk\2.0.2\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.props(29,3): error MSB4019: The imported project "C:\Program Files\dotnet\sdk\2.0.2\2.0\Microsoft.Common.props" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.

The import in Sdk.props looks like this:

<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />

It appears that MSBuildToolsVersion is getting set to "2.0" instead of "15.0" for some reason.

Found a related issue in DocFx that perfectly describes this behavior here: dotnet/docfx#1752 (comment) (Buildalyzer already sets the MSBuildExtensionsPath).

@daveaglick
Copy link
Collaborator Author

Interestingly, this only appears to affect loading of one project. One of the only differences between that project and the others is that it's multi-targeted:

<TargetFrameworks>net46;netstandard1.6</TargetFrameworks>

So some combination of multi-targeting and the CI server appears to cause the issue.

@jp2masa
Copy link

jp2masa commented Nov 3, 2017

I think that's the error message I was getting when I reported #16, so I'll close it.

@daveaglick
Copy link
Collaborator Author

@jp2masa Thanks - good to consolidate issues whenever we can. I've been working on this and have a failing test for it so hopefully I'll figure it out soon.

@ReubenBond
Copy link
Contributor

Currently I'm working around this with a particularly nasty hack inspired by one of the linked threads:

// HACK: https://github.com/daveaglick/Buildalyzer/issues/29

var dotnetSdkVersion = "2.0.0";
var extensionsPath = $@"C:\Program Files\dotnet\sdk\{dotnetSdkVersion}";
var msbuildSdkPath = $@"{extensionsPath}\SDKs";
Environment.SetEnvironmentVariable("VisualStudioVersion", "15.0");
Environment.SetEnvironmentVariable("MSBuildExtensionsPath", extensionsPath);
Environment.SetEnvironmentVariable("MSBuildSDKsPath", msbuildSdkPath);
Environment.SetEnvironmentVariable("VSINSTALLDIR", @"C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\");

// END

@daveaglick
Copy link
Collaborator Author

Interesting clue: when running from the test runner under .NET Core I get the following error

C:\Program Files\dotnet\sdk\2.1.2\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.targets(41,3): error MSB4019: The imported project "E:\NuGet\microsoft.testplatform.testhost\15.5.0\lib\netstandard1.5\Microsoft.CSharp.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.

It's the same message but the path where it's looking for Microsoft.CSharp.targets looks like it's relative to the working path.

@daveaglick
Copy link
Collaborator Author

Getting closer - dumped a binary log of the failing build and noticed this:

2018-01-07_16h25_49

However, MSBuildToolsVersion is set when the build begins:

2018-01-07_16h27_01

@daveaglick
Copy link
Collaborator Author

And this seems to confirm my initial thought - it's specifically multitargeting that resets the tools version. It's set correctly to "15.0" in the outer build but then the inner builds for each target use "2.0":

2018-01-07_16h47_52

@daveaglick daveaglick changed the title Wrong path for build tools Wrong path for build tools when multitargeting Jan 8, 2018
@daveaglick
Copy link
Collaborator Author

Opened an upstream issue at dotnet/msbuild#2846

@daveaglick
Copy link
Collaborator Author

A thought: maybe it makes sense to convert a multi-targeted project to a single target for Buildalyzer purposes. Is there a benefit to running the build with all the targets - if we're mainly looking for MSBuild properties like source files and csc arguments maybe we don't care about all the targets.

@daveaglick
Copy link
Collaborator Author

Found this in Microsoft.Common.CrossTargeting.targets:

  <Target Name="DispatchToInnerBuilds"
          DependsOnTargets="_ComputeTargetFrameworkItems"
          Returns="@(InnerOutput)">
    <!-- If this logic is changed, also update Clean -->
    <MSBuild Projects="@(_InnerBuildProjects)"
             Condition="'@(_InnerBuildProjects)' != '' "
             Targets="$(InnerTargets)"
             BuildInParallel="$(BuildInParallel)">
      <Output ItemName="InnerOutput" TaskParameter="TargetOutputs" />
    </MSBuild>
  </Target>

The MSBuild task is described here: https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-task. It doesn't look like the optional Properties parameter is being used to pass the current properties down to the inner build(s). That means anything we tweak in the outside build by setting properties via the MSBuild APIs probably isn't making it to the inner builds.

@jp2masa
Copy link

jp2masa commented Jan 9, 2018

I don't think that the properties need to be passed to the task, I already had some problems related to that. At least TargetFramework is set as a global property by the MSBuild task, so I assume that all properties are "inherited" as global properties from the project that calls the MSBuild task.

@daveaglick
Copy link
Collaborator Author

Resolved with the latest commit - ended up stripping multiple targets from project files and just building the first target.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants