-
Notifications
You must be signed in to change notification settings - Fork 25
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
MSYS / cygwin symlinks #246
base: main
Are you sure you want to change the base?
Conversation
Also note that MSYS2 can emulate symbolic links in at least three ways (see this blog for more information). For example:
Maybe we also need to check the content of the |
I added a new commit that I hope is more accurate, in that it tests for this case specifically on Cygwin and MSYS2 |
if ($nativesymlink) { | ||
# NOTE: On linux, it is OK to create broken symlinks, but it is not allowed on | ||
# windows MSYS2/Cygwin when nativestrict is used. | ||
die "cannot create native symlink to nonexistent file $target on $^O"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why this is necessary? Trying to create the broken symlink already fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trying to create the broken symlink already fails.
I think there were two things I was trying to do here. First, if the target does exist relative to the source we still need to temporarily create an empty file relative to the destination, see line 91 below, since the file might not be copied by File::Find::find() yet. Second I was trying to provide some more context for the error message, and maybe document in the code that we actually have thought about the issue, hopefully making the code more maintainable.
To solve the issue with the destination, I create a temporarily empty file relative to the destination, but in doing this the symlink call on line 97 will no longer fail. I think that is one reason why I included the check here..
$dst->parent->child($target)->touchpath; | ||
} | ||
} | ||
my $curdir = Path::Tiny->cwd; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For AB I usually use File::chdir
to avoid clutter of tracking temporary directory changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, I will update the code to use File::chdir
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my $curdir = Path::Tiny->cwd; |
line can be removed now.
lib/Alien/Build/Util.pm
Outdated
} | ||
my $curdir = Path::Tiny->cwd; | ||
# CD into the directory, such that symlink will work on MSYS2 | ||
chdir $dst->parent or die "could not chdir to $src->parent : $!"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like more illumination on why we are changing into the destination directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For a relative target, the symlink
call will fail if the target does not exist. The existence check is done relative to the current directory (tested this now).
This patch seems invasive for a |
} | ||
} | ||
if ($nativesymlink) { | ||
$dst->parent->child($target)->touchpath; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is assuming that the target will later be updated as part of the copy? There is a corner case here though when the link really should be broken at the destination because of relative links, will leave an empty file instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will leave an empty file instead.
That should not happen since we do the check of existence relative to the source at line 83. So if the target does not exist relative to the source, the code dies at line 87.
Be more specific/accurate when testing the cases that cannot create broken symlinks.
016196c
to
aa4787c
Compare
@@ -65,7 +80,37 @@ sub _mirror | |||
{ unlink "$dst" } | |||
my $target = readlink "$src"; | |||
Alien::Build->log("ln -s $target $dst") if $opt->{verbose}; | |||
symlink($target, $dst) || die "unable to symlink $target => $dst"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to keep this simplified behavior when $^O is not msys
or cygwin
.
my $newdir = $tmp1->child("lib"); | ||
my $savedir = Path::Tiny->cwd; | ||
# CD into the the $newdir such that symlink will work on MSYS2 | ||
chdir $newdir->stringify or die "unable to chdir to $newdir: $!"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my $newdir = $tmp1->child("lib"); | |
my $savedir = Path::Tiny->cwd; | |
# CD into the the $newdir such that symlink will work on MSYS2 | |
chdir $newdir->stringify or die "unable to chdir to $newdir: $!"; | |
local $CWD = $tmp1->child("lib")->stringify; |
} | ||
chdir $savedir or die "unable to chdir to $savedir: $!"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
chdir $savedir or die "unable to chdir to $savedir: $!"; |
I think this is close. Aside from a couple of very minor nits mentioned above, I would like to keep the original simple one-statement call to symlink on UNIX and only delve into the msys/cygwin logic if we are on that platform. |
Thanks for the comments! In the meantime I have found some more accurate information about the behavior of symlinks on Windows when working on this issue. Unfortunately it is quite complicated. The plan is to come back to this PR later and update it.. |
This fixes issue #213 on my machine.