Skip to content

build.sh fails when run in a directory that contains spaces #73327

Description

@MichalPetryka

Running in such directory results in:

<path with a space>/runtime/eng/build.sh: line 156: <path with a space up to the space>: No such file or directory

It looks like this line is the cause:
https://github.com/dotnet/runtime/blob/main/eng/build.sh#L156

Activity

  1. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Aug 3, 2022
  2. MichalPetryka commented on Aug 3, 2022

    @MichalPetryka
    ContributorAuthor

    It seems like fixing that line leads to more errors later on.

  3. ViktorHofer commented on Aug 3, 2022

    @ViktorHofer
    Member

    Thanks for brining this to our attention. Would you mind submitting a PR with the fix? And can you please post the failures that happen when this line is fixed?

  4. jkotas commented on Aug 3, 2022

    @jkotas
    Member

    Related:
    #42397
    #13740

  5. MichalPetryka commented on Aug 3, 2022

    @MichalPetryka
    ContributorAuthor

    Thanks for brining this to our attention. Would you mind submitting a PR with the fix? And can you please post the failures that happen when this line is fixed?

    I've already moved my repo to a path without spaces and closed the terminal so I can't tell exactly but it was an error when invoking msbuild, so changing that one line for sure is not enough. I'll try fixing it again tomorrow.

  6. removed
    untriagedNew issue has not been triaged by the area owner
    on Aug 10, 2022
  7. added this to the Future milestone on Aug 10, 2022
  8. MichalPetryka commented on Aug 20, 2022

    @MichalPetryka
    ContributorAuthor

    Thanks for brining this to our attention. Would you mind submitting a PR with the fix? And can you please post the failures that happen when this line is fixed?

    Looked into this again, the following error appears after fixing the first one, I don't really know how to fix it though:

    MSBUILD : error MSB1008: Only one project can be specified.
     Full command line: „/media/ewa/Samsung USB/runtime/.dotnet/sdk/7.0.100-preview.7.22377.5/MSBuild.dll -maxcpucount -verbosity:m /m /nologo /clp:Summary /v:minimal /nr:true /warnaserror /p:TreatWarningsAsErrors=true /p:ContinuousIntegrationBuild=false /home/ewa/.nuget/packages/microsoft.dotnet.arcade.sdk/7.0.0-beta.22416.1/tools/Build.proj /p:Configuration=Release /p:RepoRoot=/media/ewa/Samsung USB/runtime/ /p:Restore=true /p:Build=true /p:ArcadeBuildFromSource=false /p:Rebuild=false /p:Test=false /p:Pack=false /p:IntegrationTest=false /p:PerformanceTest=false /p:Sign=false /p:Publish=false /p:Subset=clr+libs /p:TargetArchitecture=x64 /p:BuildArchitecture=x64 /p:CMakeArgs="" -distributedlogger:Microsoft.DotNet.Tools.MSBuild.MSBuildLogger,/media/ewa/Samsung USB/runtime/.dotnet/sdk/7.0.100-preview.7.22377.5/dotnet.dll*Microsoft.DotNet.Tools.MSBuild.MSBuildForwardingLogger,/media/ewa/Samsung USB/runtime/.dotnet/sdk/7.0.100-preview.7.22377.5/dotnet.dll“
     Switches appended by response files: 
    Switch: USB/runtime/
    
    For switch syntax, type "MSBuild -help"
  9. jkotas commented on Aug 20, 2022

    @jkotas
    Member

    Try to wrap

    /p:RepoRoot=$RepoRoot `
    in quotes, like "/p:RepoRoot=$RepoRoot"

  10. MichalPetryka commented on Aug 20, 2022

    @MichalPetryka
    ContributorAuthor

    Try to wrap

    /p:RepoRoot=$RepoRoot `

    in quotes, like "/p:RepoRoot=$RepoRoot"

    Already tried, the same error.

  11. 14 remaining items

  12. ivdiazsa commented on Aug 25, 2022

    @ivdiazsa
    Contributor

    This is a bottomless Pandora's box. Manish also spent some time on this but to my knowledge no-one has yet made this work end to end. I think that in general it's a worthwhile effort so if you have some fixes that let the build proceed further, just get them merged in; once we're sure we're no longer able to make progress due to internal issues in components like MSBuild, we can follow up with the partner teams.

    Alright then it's settled! I'll get a PR with fixes on our part, i.e. until the failure falls onto MSBuild.

  13. ivdiazsa commented on Aug 25, 2022

    @ivdiazsa
    Contributor

    It's possible the machine is locked down such that they can't do that kind of thing?

    This is a thing in some companies so unfortunately that workaround wouldn't work for them. It's not a huge amount of places, but there are some locked down out there.

  14. modified the milestones: 8.0.0, Future on Jul 17, 2023
  15. ApparentlyPlus commented on Aug 24, 2026

    @ApparentlyPlus
    Contributor

    This has been quiet for a while, but I hit this exact issue today on my box and checked to see if it was documented, which brought me here. It seemed interesting, so I dug into it to see how far the rabbit hole gets.

    Everything you see below was reproduced locally on linux-x64 (Fedora 44), in a worktree at a path containing a space. Take all of this with a grain of salt, since I didn't test any fixes on windows or macOS at all. Also as a side note, the line referenced in the discussion above is outdated, now eng/build.sh:169 rather than 156.

    In the time I spent digging, I was able to find 5 failure points downstream, and locally fix the first four, which gets ./build.sh -subset libs.native -c Release to exit 0 at a path with a space. Here's the gist of it:

    # Location Cause
    1 eng/build.sh:169 unquoted source $scriptroot/...
    2 eng/common/build.sh:277 MSBuild $_InitializeToolset word-splits, giving MSB1008: Only one project can be specified
    3 eng/native/functions.cmake:265-276 unquoted ${exports_filename} in set_exports_linker_option
    4 System.IO.Compression.Native/CMakeLists.txt:95 LINK_FLAGS cannot carry a path with spaces
    5 src/coreclr/build-runtime.sh:176 path is quoted, but eval re-parses the string and splits on the space

    In light of this, I think I now get why this hasn't moved forward in a while:

    1. Part of the fix is not in this repo, specifically, Item 2. It lives in eng/common/, which afaik is mirrored from dotnet/arcade and is explicitly off limits here. So even the minimal path to a working libs.native needs an arcade PR and a version flow before the runtime side can be completed. I did not see this mentioned anywhere in the thread.

    2. Item 4 is actually not a quoting problem. LINK_FLAGS is a raw string that CMake passes to the linker as is, so quoting the variable in CMake source changes nothing. I confirmed that and got the identical clang: no such file or directory error. What does work is switching to target_link_options, which CMake escapes properly:

      -set_property(TARGET X APPEND_STRING PROPERTY LINK_FLAGS ${EXPORTS_LINKER_OPTION})
      +target_link_options(X PRIVATE "${EXPORTS_LINKER_OPTION}")

    I'm mentioning this specifically for anyone who tried solving this before, since quoting looks like the obvious fix and produces no visible change as far as I could tell. On top of that, I confirmed 10 sites using this exact exports pattern and 23 APPEND_STRING PROPERTY LINK_FLAGS uses in total.

    Is it a pandora's box like @trylek said? Kinda, but the scope isn't insane. The fix seems to be a finite set of mechanical patterns, spread across two repos and most native components. The pattern was unquoted $var in shell, unquoted ${VAR} in CMake, and the LINK_FLAGS to target_link_options migration.

    @ivdiazsa is still assigned from 2022. I wonder whether anyone is actively on this? Given @trylek's earlier point about landing partial fixes that let the build proceed further, I would be happy to help out incrementally, starting with the libs.native fix above, if that is still the preferred approach and nobody else has it in flight.

    What I am most worried about is regressions and testing, especially since this could be breaking. @danmoseley already said that nothing in CI covers this, so it will keep regressing regardless of how far the fixes get.

  16. akoeplinger commented on Sep 7, 2026

    @akoeplinger
    Member

    @ApparentlyPlus we can make incremental progress :) the first two are easy ones and can be just fixed, one in dotnet/runtime and one in dotnet/arcade. Feel free to send a PR.

  17. ApparentlyPlus commented on Sep 7, 2026

    @ApparentlyPlus
    Contributor

    @ApparentlyPlus we can make incremental progress :) the first two are easy ones and can be just fixed, one in dotnet/runtime and one in dotnet/arcade. Feel free to send a PR.

    Awesome. I'll take this up asap. I'll draft a PR either tonight or tomorrow morning.

  18. ApparentlyPlus commented on Sep 8, 2026

    @ApparentlyPlus
    Contributor

    Jesus christ. I was completely wrong, and @trylek was right in 2022. This is a pandora's box. Forget everything I said above. This goes way deeper than I gave it credit for. I'm waiting to coordinate on the open PRs first before I dive deeper.

  19. ApparentlyPlus commented on Sep 10, 2026

    @ApparentlyPlus
    Contributor

    Howdy again, and thanks for merging both PRs @akoeplinger! Shorter comment this time, I promise. I deleted my prior ones because they were absolute and misleading, so here's a revised, hopefully better assessment.

    Since iterating is back on the table, I mapped the rest of it by fixing faults one at a time, until I managed to make it compile locally. I got a full ./build.sh -c Release to complete from scratch at a path with a space on linux-x64 and macos-arm64. This is good news, but I am not gonna claim what I have is the full scope. Every time I did so far, more things surfaced.

    Turns out, this is almost purely a quoting problem. Every failure downstream is the same mistake repeated: a path handed off as a bare $var / $(Prop) / %(Meta) into something that word splits, and each one eluded me until the one before it was fixed. That's why the file count skyrocketed.

    A full fix breaks down in 3 steps:

    1. We need another arcade PR, this time for the installers package

    Still a quoting problem, and macOS needs this. When the build packages the product on macOS it shells out to pkgbuild and productbuild. Those are macOS system tools, but the targets driving them aren't in this repo, they ship inside the Microsoft.DotNet.Build.Tasks.Installers NuGet package, which comes from arcade. Both assemble a flat command string and hand it to Exec, so every path in it needs quoting:

    Important

    This is not eng/common, so there is no mirror. It has to merge in arcade, get a package release, and then that version has to flow back into runtime before macOS CI can go green. That's gonna take a while (I'd love it if someone shed some light on how long), and nothing else waits on it, so it should go up first while the rest moves.

    2. The eval in build-commons.sh should change

    build-commons.sh:209 plus the four callers. It's different in kind from the rest, and it has to happen before the other quoting fixes.

    The script builds the whole gen-buildsys.sh invocation as a string and runs it through eval, so it gets parsed twice and $cmakeArgs splits on that second pass. You can't fix it from the calling side either, since a caller's quotes get eaten by the first parse. The fix is to drop the string, cmakeArgs becomes a bash array and gen-buildsys.sh is invoked directly with "${cmakeArgs[@]}".

    Btw, this is the only real behaviour change in the set, since some values leaned on that second parse. The iOS armv7;armv7s one splits on the ; and would have taken out the armv7 leg if I hadn't re-quoted it. It's risky, but anything I miss, the current CI will catch.

    I built both halves separately to check the order. Quoting without this dies at CMake configure before a single object compiles, on a line that is already quoted correctly, because the eval ate the -D before CMake saw it. The eval alone gets 1100 of 2877 objects in and dies at link. So, quoting first would look like it did nothing.

    3. Quotes everywhere, a full sweep of the same thing

    This is 21 files, but they're all the same fix:

    Oh, and coincidentally, sdk-task.sh:37-41 is the same $binaryLogArg bug dotnet/arcade#17509 fixed in build.sh this morning, sitting one file over. I didn't see it before, otherwise I'd have fixed that too. Again, quotes.

    So, the arcade PR should go up next, along with the eval fix here. If you green light it, that's another 2 relatively small PRs, then the quoting sweep and some patience until the arcade package flows into runtime. Bear in mind that green CI only confirms no regressions, not the fix itself. The fix can only be tested locally, and it will break again unless we add CI after everything.

    Waiting on the okay and I'm on it.

  20. akoeplinger commented on Sep 11, 2026

    @akoeplinger
    Member

    @ApparentlyPlus

    1. arcade changes look reasonable to me, feel free to open a PR. once the change is merged there it will flow to dotnet/dotnet and then to dotnet/runtime, you can watch for codeflow PRs like [main] Source code updates from dotnet/dotnet #133655
    2. sounds reasonable. About the armv7/armv7s, that's actually dead code since we no longer build for ios/iossimulator for those platforms or i386 anymore. Logic like that can be cleaned up separately.
    3. sure
  21. ApparentlyPlus commented on Sep 11, 2026

    @ApparentlyPlus
    Contributor

    @akoeplinger First 2 are up, one in arcade and one in runtime. I'll do the third one once these two are green and land. Thanks for the quick replies!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions