Skip to content

Visual Studio solution: check for updates of vcpkg #2424

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

Closed

Conversation

PhilipOakley
Copy link

The Microsoft vcpkg package manager recieves continual updates. The
pre-built vs/master git.sln Visual Studio solution would clone and
compile the vcpkg dependencies if missing, but did not check for
updates. Fix this.

Update the contrib/buildsystems/Generators/Vcxproj.pm.

Remove the condition on 'Pre-Build' event for installation, and thus
always check for updates if the vcpkg manager is already present.

The `vcpkg_install.bat' file name is retained to avoid churn. The batch
file now also handles the vcpkg update check.

See microsoft/vcpkg#9148 for update documentation,
however the use of "./vcpkg" is a bashism, not suited to a cmd.bat file.
Use vcpkg, no need for the .exe part, removing the ./ should be
sufficient.

Signed-off-by: Philip Oakley [email protected]


I have moderately tested this, and it's working on my VS2017 community edition by pulling and checking for updates, however I don't think there's been any major updates while I've been testing.

This follows the mailing list discussion with @SyntevoAlex https://public-inbox.org/git/?q=%3C021de37a-5317-6c96-eae3-d0228a193d8b%40iee.email%3E

Suggestion for driving the tesing would be helpful (e.g. best way / how to spoof the initial clone to be from say March 2019, so that updates would be needed on second compile.)

@PhilipOakley
Copy link
Author

Hmm two test fails, both for lacking vcpkg-root so not sure why that is. Maybe the pull request CI goes through a slightly different start process so that it doesn't show, but I'm, at the moment clueless why it's happened.

@PhilipOakley
Copy link
Author

hmm still the same problem.

Copy link
Member

@dscho dscho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A good first draft, thank you!

@@ -34,6 +34,12 @@ REM ================================================================
@FOR /F "delims=" %%D IN ("%~dp0") DO @SET cwd=%%~fD
cd %cwd%

SET arch=x64-windows
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really the correct thing to do? I'd rather have this as independent of the current architecture as possible.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really the correct thing to do? I'd rather have this as independent of the current architecture as possible.

It's the current way. That appears to be just the way it is (see lower down in the bat file).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned below, if we are already moving it, we should move it to the top, and add a good comment about the raison d'être for this variable.

@@ -34,6 +34,12 @@ REM ================================================================
@FOR /F "delims=" %%D IN ("%~dp0") DO @SET cwd=%%~fD
cd %cwd%

SET arch=x64-windows
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really the correct thing to do? I'd rather have this as independent of the current architecture as possible.

@@ -34,6 +34,12 @@ REM ================================================================
@FOR /F "delims=" %%D IN ("%~dp0") DO @SET cwd=%%~fD
cd %cwd%

SET arch=x64-windows

REM is vcpkg package installed and complied \\compat\\vcbuild\\vcpkg\\installed\\\$(VCPKGArch)\\include\\openssl\\ssl.h
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the indentation.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indentation

The current file uses single space after the REM. Was there an issue with the existing file, or is there something I can't see in the Github gui?

SET arch=x64-windows

REM is vcpkg package installed and complied \\compat\\vcbuild\\vcpkg\\installed\\\$(VCPKGArch)\\include\\openssl\\ssl.h
dir vcpkg\installed\%arch%\include\openssl\ssl.h >nul 2>nul && GOTO :check_for_updates
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oy. Should this not be IF EXIST "..." GOTO ...?

Relying on the exit status of dir when a file does, or does not exist, strikes me as odd in this context.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oy, oy, oy. I just realized that you copy-edited code already in the script... Tsk, tsk. Still, there is no good reason to copy flawed code, let's use IF EXIST instead.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try the IF EXIST approach. I never like success=0 with the wrong/poor && logic.

REM is vcpkg package installed and complied \\compat\\vcbuild\\vcpkg\\installed\\\$(VCPKGArch)\\include\\openssl\\ssl.h
dir vcpkg\installed\%arch%\include\openssl\ssl.h >nul 2>nul && GOTO :check_for_updates

REM is vcpkg package manager already cloned
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the indentation.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Local REM indentation is single space

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look at it on GitHub. There is a difference between the indentation of all your REMs vs the IF EXIST line. It's totally jagged.


:install_libraries
SET arch=x64-windows
REM SET arch=x64-windows
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that's where this comes from. Urgh.

So you are just moving the definition. But you're not, you're commenting out the old code, making it "dead code". Please don't.

And if you are moving the definition, please move it to the top, with a comment that the architecture is currently hard-coded, and that we will change that once we need to.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Dead code" - I'll keep it (typically) until we have working code (the point of requesting the support/review).

the architecture is currently hard-coded, and that we will change that once we need to

I can add your comment.

@dscho
Copy link
Member

dscho commented Dec 11, 2019

Hmm two test fails, both for lacking vcpkg-root so not sure why that is. Maybe the pull request CI goes through a slightly different start process so that it doesn't show

From https://dev.azure.com/Git-for-Windows/git/_build/results?buildId=46958&view=logs&jobId=2e71db62-524c-5004-06b5-96b7fc531cee (lines 25--36):

PreBuildEvent:
  Description: Initialize or update VCPKG
  call "..\compat\vcbuild\vcpkg_install.bat"
  :VCEnd
  Checking for vcpkg updates and upgrades to installed libraries
  You are not currently on a branch.
  Please specify which branch you want to merge with.
  See git-pull(1) for details.
  
      git pull <remote> <branch>
  
##[error]EXEC(0,0): Error : Could not detect vcpkg-root.
EXEC : error : Could not detect vcpkg-root. [D:\a\1\s\libgit\libgit.vcxproj]

I would wager a bet that the problem is that we copy the vcpkg build artifacts from https://dev.azure.com/git/git/_build?definitionId=9 and unpack them here, and the .git directory is not copied.

The reason is that it would be super wasteful to build the vcpkg artifacts every single time that a CI/PR build runs in gitgitgadget, git or git-for-windows.

Therefore, you will want to verify that there is, in fact, a .git directory inside compat\vcbuild\vcpkg, and if there is not, skip your new step.

@PhilipOakley
Copy link
Author

I would wager a bet that the problem is that we copy the vcpkg build artifacts from https://dev.azure.com/git/git/_build?definitionId=9 and unpack them here, and the .git directory is not copied.

Where is that all documented? I never found my way to anything that helped.

Isn't the 'right' solution for the CI to at least clone the repo shallow=1 to match the expected user experience? If the existing solution is retained how do other that fall into the same trap of an old vcpkg install find out /test what's happened.

@dscho
Copy link
Member

dscho commented Dec 13, 2019

I would wager a bet that the problem is that we copy the vcpkg build artifacts from https://dev.azure.com/git/git/_build?definitionId=9 and unpack them here, and the .git directory is not copied.

Where is that all documented? I never found my way to anything that helped.

It's in the CI definition: https://github.com/git-for-windows/git/blob/v2.24.0.windows.2/azure-pipelines.yml#L170-L177

Isn't the 'right' solution for the CI to at least clone the repo shallow=1 to match the expected user experience? If the existing solution is retained how do other that fall into the same trap of an old vcpkg install find out /test what's happened.

If you are saying that the "right" solution is to let vcpkg download and build all dependencies in all of those dozens of CI/PR builds that happen every day, then I heartily disagree.

@PhilipOakley
Copy link
Author

If you are saying that the "right" solution is to let vcpkg download and build all dependencies in all of those dozens of CI/PR builds that happen every day, then I heartily disagree.

So what do you suggest, seeing as we are trying to implement a method (for the user) that does download, build, test for update, all the dependencies?

The current setup is a catch22 that avoids any of those user issues, and bypasses the user based tests.

Given your suggestion as to what's happening, it looks as if we currently (without up-to-date-ness checks) have a Prebuild-Event that tests for the existence of the compilation products, allowing the CI to simply dump a prebuilt set of binaries (etc) into the requisite directories, so that no pre-build event is executed, avoiding the batch file.

In the new (up-to-date-ness check) case the Prebuild-Event condition has to be dropped as the check is no longer a valid indicator of up-to-date-ness, leaving the CI to mimic the user scenario.

If you can suggest an alternate sentinel that could be added by the CI then maybe an alternate pre-build condition could be used (I see a remove line for a .zip indicating tweaks but...).

I have zero experience or knowledge of Azure pipelines (those referenced lines look like gobbledygook at the moment)

@dscho
Copy link
Member

dscho commented Dec 13, 2019

If you can suggest an alternate sentinel that could be added by the CI then maybe an alternate pre-build condition could be used (I see a remove line for a .zip indicating tweaks but...).

To work around the failure, you could make this conditional on either the vcpkg directory not existing or vcpkg\.git existing.

To be honest, I am not a huge fan of always trying to update the dependencies. Sounds too forced, and too costly, to me.

@PhilipOakley
Copy link
Author

To be honest, I am not a huge fan of always trying to update the dependencies. Sounds too forced, and too costly, to me.

I'm also cautious that the cost should not be onerous (e.g. only one check per day or similar), but I do think that it can't be left forever without some form of dependency check.

we copy the vcpkg build artifacts from https://dev.azure.com/git/git/_build?definitionId=9 and unpack them here,

Are those build products also allowed to be very stale (half a year), or are the somehow auto built either by vcpkg or somewhere earlier in the git CI? (see earlier note about this being new territory for me, so a proper question)

To work around the failure, you could make this conditional on ...

I believe we do need the extra sentinel indicator that is special to the CI unpack, so we can use that in the VS PrebuildEvent. All the other options are between a rock and a hard place - we do need both the detections (of lack of vcpkg, and stale vcpkg) to also happen for the users machine, even if the stale vcpkg isn't an issue for the CI (see Q above).

I think I found that we could insert a [ps example!] command in the yml to create a vcpkg/NoPrebuildEvent.txt file, that replaces (stands in) the current if !exist() condition in the generators/vcxproj.pm, and consequently git.sln, so the CI never sees the vcpkg_install.bat, while the user does.

new-item -path C:\docs -name SS64.txt -type "file" -value "some text"

Obviously getting the path, name and text sorted ;-)

That then leaves the vcpkg_install.bat free to do any user based special checks for initial install, dependencies, and up to date(day), checks.

@dscho
Copy link
Member

dscho commented Dec 14, 2019

only one check per day or similar

It would seem that this should be possible (see SO post): something like Condition="!Exists('..\compat\vcbuild\vcpkg') || (Exists('..\compat\vcbuild\vcpkg\.git') && ($([System.DateTime]::Now().Ticks) > $([System.IO.File]::GetLastWriteTime('..\compat\vcbuild\vcpkg\.git\HEAD').Ticks))))"

This is untested, of course, as I wanted to leave a little bit of this work to you.

To work around the failure, you could make this conditional on ...

I believe we do need the extra sentinel indicator that is special to the CI unpack, so we can use that in the VS PrebuildEvent.

Well, there is one, and I already mentioned it: test for the presence of vcpkg without vcpkg\.git being present.

This would also have the further advantage of being the sentinel for the condition we actually care about: We couldn't care less whether this is a CI build or not. What we actually care about is whether we can update vcpkg or not.

The Microsoft vcpkg package manager recieves continual updates. The
pre-built vs/master git.sln Visual Studio solution would clone and
compile the vcpkg dependencies if missing, but did not check for
updates. Fix this user-land issue.

The Azure Continuous Integration (CI) system would pre-build the vcpkg
files and expand them in place rather than clone and rebuild them.

Unfortunately the CI logic and the update logic are in conflict as both
detect/use the presence/absence of the same files via the git.sln
Prebuild Event.

The .git directory is not present in the Azure-CI, which conflicts
with using a `git pull` update..

Add a sentinel file to the Azure-CI to indicate that the CI is in use,
and use that as the git.sln conditional PrebuildEvent for checking for
vcpkg updates in user-land.

Update the contrib/buildsystems/Generators/Vcxproj.pm.

Remove the condition on 'Pre-Build' event for installation, and thus
always check for updates if the vcpkg manager is already present.

The `vcpkg_install.bat' file name is retained to avoid churn. The batch
file now also handles the vcpkg update check.

See microsoft/vcpkg#9148 for update documentation,
however the use of "./vcpkg" is a bashism, not suited to a cmd.bat file.
Use `vcpkg`, no need for the .exe part, removing the `./` should be
sufficient.

Signed-off-by: Philip Oakley <[email protected]>
---
corrected some bad logic and confusion that success is zero
though logical true for the && cases, and the reverse
sequence of existance checks.

still contains residual artefacts for dev assistance.
@PhilipOakley
Copy link
Author

I have Addressed what I can, and hacked other parts with best guesses.

Arguably the changes could be split to:

  1. add the Azure sentinel file
  2. change the prebuild event condition
  3. update the vcpkg_install file to check for updates
  4. (tbd) add a 'once per day' semaphore into /vcpkg/, maybe even in the .git.

@PhilipOakley
Copy link
Author

Sorry, I missed your update that was just before I'd sent the hacked update (still some rough errors and leftover crud in the commit message, and it failed the tests..)

It would seem that this should be possible (see SO post): something like Condition="!Exists('..\compat\vcbuild\vcpkg') || (Exists('..\compat\vcbuild\vcpkg\.git') && ($([System.DateTime]::Now().Ticks) > $([System.IO.File]::GetLastWriteTime('..\compat\vcbuild\vcpkg\.git\HEAD').Ticks))))"

This is untested, of course, as I wanted to leave a little bit of this work to you.

Ok, I see where you are going there. I couldn't get my head around the checking logic before. The time check will need a tweak as it's almost always true (the last HEAD update was before Now() 😉 )

The one benefit of the sentinel was that a user could also set it, once they know about it.

One thing I don't see in VS, or the Azure builds is any reporting of the prebuild event condition. It doesn't appear to show in the logs or the VS properties - Do you see it?

@PhilipOakley
Copy link
Author

it failed the tests.

Looks like it's now passed.
Seems odd that the VS build appears to fail in the first few minutes but then changes to passing later.

I'm away for a few days ...

@@ -174,6 +174,7 @@ jobs:
(New-Object Net.WebClient).DownloadFile($downloadUrl, "compat.zip")
Expand-Archive compat.zip -DestinationPath . -Force
Remove-Item compat.zip
new-item -path "$(Build.SourcesDirectory)/compat/vcbuild" -name NoPrebuildEvent.txt -type "file" -value "Inhibit git.sln PrebuildEvent"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is incorrect.

What we need to figure out is not whether we run in a CI/PR build, but whether we can update vcpkg or not.

I am very much against introducing this change, as it is a clear "papering over" the actual problem: we are currently not figuring out whether vcpkg is initialized via cloning or, say, by copying the ready-built artifacts or not.

@@ -34,6 +34,12 @@ REM ================================================================
@FOR /F "delims=" %%D IN ("%~dp0") DO @SET cwd=%%~fD
cd %cwd%

SET arch=x64-windows
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned below, if we are already moving it, we should move it to the top, and add a good comment about the raison d'être for this variable.

REM is vcpkg package installed and complied \\compat\\vcbuild\\vcpkg\\installed\\\$(VCPKGArch)\\include\\openssl\\ssl.h
dir vcpkg\installed\%arch%\include\openssl\ssl.h >nul 2>nul && GOTO :check_for_updates

REM is vcpkg package manager already cloned
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look at it on GitHub. There is a difference between the indentation of all your REMs vs the IF EXIST line. It's totally jagged.

@@ -53,9 +62,18 @@ REM ================================================================
IF ERRORLEVEL 1 ( EXIT /B 1 )

echo Successfully installed %cwd%vcpkg\vcpkg.exe
GOTO :install_libraries
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should not squeeze the check_for_updates "routine" between the part of the script where vcpkg.exe is built and install_libraries? That this extra goto is now required all of a sudden is a pretty clear indicator that this is the wrong location for check_for_updates. It would be much better to move it to the end of the script, as it is a pretty independent piece of new code.

<PreBuildEvent Condition="!Exists('$cdup\\compat\\vcbuild\\vcpkg\\installed\\\$(VCPKGArch)\\include\\openssl\\ssl.h')">
<Message>Initialize VCPKG</Message>
<Command>del "$cdup\\compat\\vcbuild\\vcpkg"</Command>
<PreBuildEvent Condition="!Exists('$cdup\\compat\\vcbuild\\NoPrebuildEvent.txt')">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really, this is the wrong way to go about it.

@git-for-windows-ci git-for-windows-ci changed the base branch from master to main June 17, 2020 18:10
@dscho
Copy link
Member

dscho commented Oct 6, 2020

@PhilipOakley I'll just close this, okay?

If you're still interested in something like it, it will most likely make more sense to integrate it somehow with the CMake support we just completed.

@dscho dscho closed this Oct 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants