Skip to content

Commit 336cb99

Browse files
committed
Add a page about symlinks
1 parent fdf2fa1 commit 336cb99

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ nav:
109109
- docs/package-management-tips.md
110110
- docs/package-management-faq.md
111111
- docs/filesystem-paths.md
112+
- docs/symlinks.md
112113
- docs/configuration.md
113114
- Languages & Tools:
114115
- docs/cmake.md

web/docs/symlinks.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Symlinks
2+
3+
[Symlinks](https://en.wikipedia.org/wiki/Symbolic_link) are a way to create a
4+
reference to a file or directory in another location. They are quite common on
5+
Linux/Unix systems, and many Unix tools are using/depending on them. While
6+
symlinks also exist on Windows, they are not available to normal Windows users
7+
by default, which makes them less common on Windows.
8+
9+
In MSYS2 symlinks are by default avoided, and creating a symlink with Cygwin
10+
tools instead creates a deep-copy of the target. This makes sure that symlinking
11+
works on every Windows installation and for every Windows user and the result is
12+
readable by native Windows software.
13+
14+
The deep-copying has the downside that the symlink and the target are not
15+
actually linked, and due to the duplication it also takes up double the disk
16+
space. Another downside is that the target always needs to exist, otherwise it
17+
couldn't be copied.
18+
19+
We are planning to improve this in the future, see
20+
https://github.com/msys2/msys2-runtime/pull/114 for more information.
21+
22+
## Cygwin Symlink Modes
23+
24+
While MSYS2 is based on Cygwin, Cygwin has different default behavior for
25+
symlinks and tries to create "real" symlinks if possible, with the potential
26+
downside that they are not readable by native Windows applications.
27+
28+
See https://cygwin.com/cygwin-ug-net/using.html#pathnames-symlinks for details
29+
on the default behavior and all the different symlink modes that are available
30+
in Cygwin.
31+
32+
All these modes can also be enabled in MSYS2 by setting the `MSYS` environment
33+
variable instead of `CYGWIN`. For example `MSYS=winsymlinks:nativestrict` can be
34+
used to enable native Windows symlinks.
35+
36+
* `ln -s target link` - create a symlink to a file or directory
37+
38+
The default mode in MSYS2 is called `winsymlinks:deepcopy` and is only available
39+
in MSYS2 and not in Cygwin.
40+
41+
## Native Windows Symlinks
42+
43+
This is a short primer for native Windows symlinks in case you haven't used them
44+
before or are only familiar with them on Unix systems.
45+
46+
Symlink support in Windows existed for a long time, but creating them was
47+
initially only possible with administrator accounts. Starting with Windows 10
48+
(~2016) it is now possible to create symlinks with your normal user account if
49+
you have the ["Developer Mode"
50+
enabled](https://learn.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development).
51+
Existing symlinks that were created by an administrator account, or with the
52+
"Developer Mode" enabled, can be used and deleted by normal users without rights
53+
to create symlinks themselves.
54+
55+
Compare to Unix symlinks, the Windows symlinks come in a "directory" and a
56+
"file" type. If you create a file symlink to a directory, or vice versa, or if
57+
the target type changes after the symlink is created, the symlink will be
58+
broken.
59+
60+
Symlinks also only work on NTFS/ReFS filesystems, and not on FAT32 or exFAT.
61+
62+
To create a symlink on Windows in cmd you can use "mklink":
63+
64+
* `mklink link target` - create a symlink called "link" to a file called "target"
65+
* `mklink /d link target` - create a symlink called "link" to a directory called "target"
66+
67+
mklink ignores the type of any existing target and always creates a file
68+
symlink if not specified otherwise.
69+
70+
* When on an unsupported filesystem you will get: "The device does not support symbolic links".
71+
* Without developer mode enabled or administrative privileges you will get: "You do not have sufficient privilege to perform this operation."
72+
73+
Under PowerShell you can use "New-Item":
74+
75+
* `New-Item -ItemType SymbolicLink -Path link -Target target` - create a symlink called "link" to a file or directory called "target"
76+
77+
Unlike "mklink", "New-Item" will automatically create a directory symlink if the
78+
target is a directory and a file symlink if the target is a file. In case the
79+
target doesn't exist yet, the symlink will be a file symlink by default and, as
80+
far as I'm aware (??), there is no way to create a directory symlink to a
81+
non-existing target with "New-Item".
82+
83+
* When on an unsupported filesystem you will get: "Symbolic links are not supported for the specified path."
84+
* Without developer mode enabled or administrative privileges: "Administrator privilege required for this operation."
85+
86+
If you get the "Administrator privilege required" error despite having Developer
87+
Mode enabled, you might be using a too old version of Powershell, like the
88+
version included in Windows by default. You either need to [install a newer
89+
version of Powershell](https://winget.run/pkg/Microsoft/PowerShell), use mklink
90+
via `cmd /c mklink`, or use an elevated prompt. You can check your Powershell
91+
version with `$PSVersionTable.PSVersion`.
92+
93+
## Known Issues
94+
95+
As stated above, for the deep-copy to work the target needs to exist for the
96+
symlinking to work. While dangling symlinks are not that common, they can happen
97+
easily when unpacking a tar file that contains symlinks. If the symlinks is
98+
unpacked before the target, then creating the symlink will fail. A workaround
99+
for this is to unpack the tar file twice, first to create the target while
100+
ignoring any symlink creation errors and then to create the symlinks:
101+
102+
```bash
103+
bsdtar -xf "archive.tar.bz2" 2>/dev/null || bsdtar -xf "archive.tar.bz2"
104+
```

0 commit comments

Comments
 (0)