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

[Bug]: Transforming backslashes to slashes next to a property value on macOS #9200

Open
ivanpovazan opened this issue Sep 1, 2023 · 3 comments
Labels

Comments

@ivanpovazan
Copy link
Member

Issue Description

This is maybe not a bug, but I did not manage to find a way to get a single trailing backslash when building up a relative path in a project file (please see the repro steps).

PS If there is an existing/proper way to do this, I would like to know the way. Thank you!

Steps to Reproduce

  1. Create a simple project:
<Project>
    <PropertyGroup>
        <RelativePath1>mydir\$(MyFileName)\</RelativePath1>
        <RelativePath2>mydir\$(MyFileName)/////////\</RelativePath2>
        <RelativePath3>mydir\$(MyFileName)\\</RelativePath3>
    </PropertyGroup>
    <Target Name="Print">
        <Message Text="RelativePath1: $(RelativePath1)" Importance="high"/>
        <Message Text="RelativePath2: $(RelativePath2)" Importance="high"/>
        <Message Text="RelativePath3: $(RelativePath3)" Importance="high"/>
    </Target>
</Project>
  1. Build the project
dotnet msbuild -p:MyFileName=file

Expected Behavior

Not sure what is the expected behaviour, but I wanted to achieve to get a single trailing backslash:

mydir\file\

Actual Behavior

The build prints out:

MSBuild version 17.8.0-preview-23367-03+0ff2a83e9 for .NET
  RelativePath1: mydir\file/
  RelativePath2: mydir\file/
  RelativePath3: mydir\file\\

Analysis

No response

Versions & Configurations

dotnet sdk version: 8.0.100-preview.7.23376.3
machine/OS: MacBookPro M1 - macOS Ventura: Version 13.5.1 (22G90)

@ivanpovazan ivanpovazan added bug needs-triage Have yet to determine what bucket this goes in. labels Sep 1, 2023
@ivanpovazan
Copy link
Member Author

Workaround: it seem that doing

<RelativePath1>mydir\$(MyFileName)%5C</RelativePath1>

would make it print:

RelativePath1: mydir\file\

@jrdodds
Copy link
Contributor

jrdodds commented Sep 1, 2023

PS If there is an existing/proper way to do this, I would like to know the way. Thank you!

I suspect there is a bug but it's minor because MSBuild will accept both \ (Windows) and / (U*nix) in a path.

Because the directory separator is different between OSes, if you want paths to be consistent within a build, consider avoiding hard coding the directory separator.

You can use Path.Combine() and EnsureTrailingSlash, e.g.

    <PropertyGroup>
        ...
        <RelativePath4>$([MSBuild]::EnsureTrailingSlash($([System.IO.Path]::Combine('mydir', '$(MyFileName)'))))</RelativePath4>
    </PropertyGroup>
    <Target Name="Print">
        ...
        <Message Text="RelativePath4: $(RelativePath4)" Importance="high"/>
    </Target>

These functions will use the native directory separator.

You can get the native directory separator with $([System.IO.Path]::DirectorySeparatorChar()).

    <PropertyGroup>
        <DirectorySeparator>$([System.IO.Path]::DirectorySeparatorChar())</DirectorySeparator>
    </PropertyGroup>

When the build runs on Windows the paths will use \ and when the build runs on macOS the paths will use /.

(Similarly and also related to OS portability, with MSBuild v17.3 and later you can use $([System.Environment]::NewLine) and avoid hard coding line endings.)

@ivanpovazan
Copy link
Member Author

ivanpovazan commented Sep 5, 2023

@jrdodds thank you for your suggestions!

However, I did not provide enough context to explain why using Path.Combine() (and other MSBuild's path related APIs) would not work in our case.

With the support of Xamarin.iOS SDK there is a setup where development for iOS platforms is enabled on Windows. In this configuration a Windows machine is used for building the project and is paired with a Mac to use the native build tools and connect to the target device for the app deployment.

Within the SDK, we need to construct a relative path, which the runtime will use to lookup files during the app execution. Since the build host (where MSBuild is running) is Windows, and the target platforms is iOS (Unix) the constructed relative path will be invalid if Path.Combine()is used, as the path will contain \ as separators (instead of expected /).

Having said all this, as a workaround we use: .Replace('\','/')
For this cross-platform scenario it is probably better to use / everywhere.


In any case, the issue reported here is still very much reproducible and is not tied to path manipulation. It is just a use case where it occurred, but I agree it is probably a niche one.

@AR-May AR-May added backlog Priority:3 Work that is nice to have and removed needs-triage Have yet to determine what bucket this goes in. labels Sep 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants