Hi
We've been getting weird errors when building releases:
```
Compiling 42 files (.ex)
** (File.Error) could not remove files and directories recursively from "/home/brendan/dev/app/_build/prod/lib/shared_app/priv": file already exists
(elixir 1.13.2) lib/file.ex:1292: File.rm_rf!/1
(mix 1.13.2) lib/mix/utils.ex:444: Mix.Utils.symlink_or_copy/3
(mix 1.13.2) lib/mix/project.ex:738: anonymous fn/5 in Mix.Project.build_structure/2
(elixir 1.13.2) lib/enum.ex:2396: Enum."-reduce/3-lists^foldl/2-0-"/3
(mix 1.13.2) lib/mix/project.ex:737: Mix.Project.build_structure/2
(mix 1.13.2) lib/mix/tasks/compile.all.ex:34: Mix.Tasks.Compile.All.run/1
(mix 1.13.2) lib/mix/task.ex:397: anonymous fn/3 in Mix.Task.run_task/3
(mix 1.13.2) lib/mix/project.ex:396: Mix.Project.in_project/4
```
We build different releases concurrently after running a single `mix compile`.
It turns out that the different release builds were not running in isolated environments, but shared the filesystem. This is a very weird and confusing error especially since most devs didn't know why it was breaking and didn't know that releases were being run in a shared environment.
This seems like something that might happen fairly often in CI environments, so I really think it's in everyone's interest to improve this.
Most good build systems/compilers implement some kind of file lock for operations that can't be done concurrently. I think implementing this would be a minimal acceptable solution. Ideally the file lock is used to wait until the operation can be performed, but even just an error saying you can't run operations in parallel would be better than what we have now.
Thoughts?
Kind regards
Brendan Ball