Msbuild: [MSBuild]::MakeRelative fails with Unix paths

Created on 16 Jan 2016  ·  5Comments  ·  Source: dotnet/msbuild

This simple project:

<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="Build">
        <Warning Text="$([MSBuild]::MakeRelative('/bar/baz', '/foo'))" />
    </Target>
</Project>

Fails (on Linux/CoreCLR) with this error:

test.proj(3,12): error MSB4184: The expression "[MSBuild]::MakeRelative(/bar/baz, /foo)" cannot be evaluated. Invalid URI: The format of the URI could not be determined.

If the path is a valid Windows/DOS path, this error isn't thrown:

<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="Build">
        <Warning Text="$([MSBuild]::MakeRelative('c:\bar\baz', '/foo'))" />
    </Target>
</Project>
test.proj(3,3): warning : ../../foo

Thanks to @joperezr for the report.

.NET Core

Most helpful comment

This is because of dotnet/corefx/issues/1745--System.Uri doesn't understand absolute Unix paths. We use Uri.MakeRelativeUri as the implementation of MakeRelative (which seems to be the “standard” way of getting a relative path in .NET), and it throws when we try to construct an absolute Uri out of a rooted Unix path.

Unfortunately, the logic of constructing relative paths is complicated; reimplementing it here is likely to be error prone (and/or behave in a subtly different way than other implementations). Ideally something like https://github.com/dotnet/corefx/issues/2836 would be available to us.

All 5 comments

This is because of dotnet/corefx/issues/1745--System.Uri doesn't understand absolute Unix paths. We use Uri.MakeRelativeUri as the implementation of MakeRelative (which seems to be the “standard” way of getting a relative path in .NET), and it throws when we try to construct an absolute Uri out of a rooted Unix path.

Unfortunately, the logic of constructing relative paths is complicated; reimplementing it here is likely to be error prone (and/or behave in a subtly different way than other implementations). Ideally something like https://github.com/dotnet/corefx/issues/2836 would be available to us.

Prepend file://?

Looks like https://github.com/dotnet/corefx/pull/11689 created a Path.GetRelativePath, which is exciting.

@rainersigwald As far as I can tell, this is working now, at least on OSX.

Yup, looks like it should have been fixed with https://github.com/dotnet/corefx/commit/7df6b74cc4aeebc86e76b5c7901a59fa7fa793f6 on .NET Core 2.0.0 and higher.

Was this page helpful?
0 / 5 - 0 ratings