-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Fix out-of-tree testing symlinks on Windows #1699
Fix out-of-tree testing symlinks on Windows #1699
Conversation
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.
If this makes it works, ok. But please get a review from someone who actually knows Windows.
@@ -67,7 +67,11 @@ function(link_to_source base_name) | |||
if (CMAKE_HOST_UNIX) | |||
set(command ln -s ${target} ${link}) | |||
else() | |||
set(command cmd.exe /c mklink /j ${link} ${target}) | |||
if (IS_DIRECTORY ${target}) |
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.
The documentation of mklink
tells me that /j
“Creates a Directory Junction”, but I have no idea why you'd use one as opposed to the default mode. It does sound like it wouldn't work for non-directories. Why is /j
used for directories?
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 clued up on the intricacies of exactly how junctions works, but Windows differentiates between symlinks for files and directories. I'll do a deeper dive into the documentation.
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 no expret, but I believe junctions can only be to folders, but symbolic links can be to either folders or files. On some systems, you may be able to create a junction where you couldn't create any symbolic links due to permissions issues (fewer permissions required for junction making), but on our test system we seem to have permission enough to make symlinks.
Since we can make symlinks, was using the /d
option to mklink
considered? It creates a directory symbolic link.
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.
It's not just for our test systems. #688 changed from /d
to /j
for permission reasons.
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.
This may introduce a regression, then. Since it goes back to using symbolic links for files, the permissions elevation may be required again.
Since the sh
files aren't needed by Windows anyway, could we avoid making links for them and get away with only making junctions?
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.
Some of the .sh
files are needed by Windows. They're how the Windows tests are invoked. We don't currently run SSL tests in an out-of-tree CMake build on Windows on our CI, but this should work for the sake of users who build on Windows and use CMake. We tend to use CMake in-tree on our CI, but that's not the way most people use CMake.
If we can't make symbolic links work on Windows, then we should copy the files. This has the downside that the build directory will contain stale copies if the original file has been edited, so the build scripts should be modified to make the a build product of the original that gets rebuilt (copied) when the original is updated, preferably only on Windows.
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.
As defined by MSDN, there are three different types of links as you can read here and here. To do a very dumb and very quick summary, they are:
We originally had symbolic links, which were changed to junctions in #688 to remove the need for Admin privileges, because it they didn't work on some development machines. This PR is changing the junction to a symbolic link. e.g. from making a junction :
to a symbolic link:
(Please see the mklink definition). I think that line needs to be changed to the following to form a hardlink:
|
CMakeLists.txt
Outdated
if (IS_DIRECTORY ${target}) | ||
set(command cmd.exe /c mklink /j ${link} ${target}) | ||
else() | ||
set(command cmd.exe /c mklink ${link} ${target}) |
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.
This line needs to be a hardlink, not a symbolic link, to avoid requiring local Admin privileges. e.g.:
set(command cmd.exe /c mklink /h ${link} ${target})
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 don't think a hard link is reasonable. A legitimate, realistic use case. is to have a read-only source tree (whether for permission or performance reasons) and to do the build on a different, read-write filesystem.
If a symbolic link is not possible, we should copy.
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 think that's the argument for #1496. What we want to do now is to get the build working again. Symbolic links are a regression, and will break the build on machines where it previously built.
What you're suggesting is reasonable, but not a regression, and therefore is an enhancement, which I think will be fixed by #1496.
I therefore see no reason to delay merging this fix assuming it passes the CI, for the sake of an enhancement.
cc: @Patater
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.
Changing to a hard link is a regression from #1470. It passes on the CI by luck because of how we set up the directory structure for the builds, just like symbolic links pass on the CI by luck because our build environment happens to have the required permission.
This passes the internal release and Windows CI, and is the change I requested, so I approve. |
if (IS_DIRECTORY ${target}) | ||
set(command cmd.exe /c mklink /j ${link} ${target}) | ||
else() | ||
set(command cmd.exe /c mklink /h ${link} ${target}) |
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 be fine with this as either symlink or hardlink, although symlink gives a better experience in certain use cases IF you have the permissions to use them.
@dgreen-arm - I don't believe this needs backports, as the breaking change was never backported. You marked it as needing backports, so can you please confirm? |
In the interest of getting CI working again, we should merge this now and fix 2.1 and 2.7 in the PRs that would break them instead of waiting to break them and fixing them with a backport of this PR. |
Merged into |
Merged PR into |
Some of the symlinks in PR #1470 were being accidentally created as directory symlinks on Windows, this adds a check to create the symlink of the correct type.
Backports will be needed for 2.7 and 2.1