build.ps1 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. param([switch]$NoTests)
  2. Set-StrictMode -Version Latest
  3. $ErrorActionPreference = 'Stop'
  4. $ProgressPreference = 'SilentlyContinue'
  5. $env:CONFIGURATION -match '^(?<compiler>\w+)_(?<bits>32|64)(?:-(?<option>\w+))?$'
  6. $compiler = $Matches.compiler
  7. $compileOption = if ($Matches -contains 'option') {$Matches.option} else {''}
  8. $bits = $Matches.bits
  9. $cmakeBuildType = $(if ($env:CMAKE_BUILD_TYPE -ne $null) {$env:CMAKE_BUILD_TYPE} else {'RelWithDebInfo'});
  10. $buildDir = [System.IO.Path]::GetFullPath("$(pwd)")
  11. $depsCmakeVars = @{
  12. CMAKE_BUILD_TYPE = $cmakeBuildType;
  13. }
  14. $nvimCmakeVars = @{
  15. CMAKE_BUILD_TYPE = $cmakeBuildType;
  16. BUSTED_OUTPUT_TYPE = 'nvim';
  17. DEPS_PREFIX=$(if ($env:DEPS_PREFIX -ne $null) {$env:DEPS_PREFIX} else {".deps/usr"});
  18. }
  19. if ($env:DEPS_BUILD_DIR -eq $null) {
  20. $env:DEPS_BUILD_DIR = ".deps";
  21. }
  22. $uploadToCodeCov = $false
  23. function exitIfFailed() {
  24. if ($LastExitCode -ne 0) {
  25. exit $LastExitCode
  26. }
  27. }
  28. if (-not $NoTests) {
  29. node --version
  30. npm.cmd --version
  31. }
  32. if (-Not (Test-Path -PathType container $env:DEPS_BUILD_DIR)) {
  33. write-host "cache dir not found: $($env:DEPS_BUILD_DIR)"
  34. mkdir $env:DEPS_BUILD_DIR
  35. } else {
  36. write-host "cache dir $($env:DEPS_BUILD_DIR) size: $(Get-ChildItem $env:DEPS_BUILD_DIR -recurse | Measure-Object -property length -sum | Select -expand sum)"
  37. }
  38. if ($compiler -eq 'MINGW') {
  39. if ($bits -eq 32) {
  40. $arch = 'i686'
  41. }
  42. elseif ($bits -eq 64) {
  43. $arch = 'x86_64'
  44. }
  45. if ($compileOption -eq 'gcov') {
  46. $nvimCmakeVars['USE_GCOV'] = 'ON'
  47. $uploadToCodecov = $true
  48. $env:GCOV = "C:\msys64\mingw$bits\bin\gcov"
  49. # Setup/build Lua coverage.
  50. $env:USE_LUACOV = 1
  51. $env:BUSTED_ARGS = "--coverage"
  52. }
  53. # These are native MinGW builds, but they use the toolchain inside
  54. # MSYS2, this allows using all the dependencies and tools available
  55. # in MSYS2, but we cannot build inside the MSYS2 shell.
  56. $cmakeGenerator = 'Ninja'
  57. $cmakeGeneratorArgs = '-v'
  58. $mingwPackages = @('ninja', 'cmake', 'diffutils').ForEach({
  59. "mingw-w64-$arch-$_"
  60. })
  61. # Add MinGW to the PATH
  62. $env:PATH = "C:\msys64\mingw$bits\bin;$env:PATH"
  63. # Avoid pacman "warning" which causes non-zero return code. https://github.com/open62541/open62541/issues/2068
  64. & C:\msys64\usr\bin\mkdir -p /var/cache/pacman/pkg
  65. # Build third-party dependencies
  66. C:\msys64\usr\bin\bash -lc "pacman --verbose --noconfirm -Syu" ; exitIfFailed
  67. # Update again in case updating pacman changes pacman.conf
  68. C:\msys64\usr\bin\bash -lc "pacman --verbose --noconfirm -Syu" ; exitIfFailed
  69. C:\msys64\usr\bin\bash -lc "pacman --verbose --noconfirm --needed -S $mingwPackages" ; exitIfFailed
  70. }
  71. elseif ($compiler -eq 'MSVC') {
  72. $cmakeGeneratorArgs = '/verbosity:normal'
  73. $cmakeGenerator = 'Visual Studio 16 2019'
  74. }
  75. if ($compiler -eq 'MSVC') {
  76. $installationPath = vswhere.exe -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
  77. if ($installationPath -and (test-path "$installationPath\Common7\Tools\vsdevcmd.bat")) {
  78. & "${env:COMSPEC}" /s /c "`"$installationPath\Common7\Tools\vsdevcmd.bat`" -arch=x${bits} -no_logo && set" | foreach-object {
  79. $name, $value = $_ -split '=', 2
  80. set-content env:\"$name" $value
  81. }
  82. }
  83. }
  84. if (-not $NoTests) {
  85. python -m ensurepip
  86. python -m pip install pynvim ; exitIfFailed
  87. # Sanity check
  88. python -c "import pynvim; print(str(pynvim))" ; exitIfFailed
  89. gem.cmd install --pre neovim
  90. Get-Command -CommandType Application neovim-ruby-host.bat
  91. npm.cmd install -g neovim
  92. Get-Command -CommandType Application neovim-node-host.cmd
  93. npm.cmd link neovim
  94. }
  95. function convertToCmakeArgs($vars) {
  96. return $vars.GetEnumerator() | foreach { "-D$($_.Key)=$($_.Value)" }
  97. }
  98. cd $env:DEPS_BUILD_DIR
  99. if ($compiler -eq 'MSVC') {
  100. if ($bits -eq 32) {
  101. cmake -G $cmakeGenerator -A Win32 $(convertToCmakeArgs($depsCmakeVars)) "$buildDir/third-party/" ; exitIfFailed
  102. } else {
  103. cmake -G $cmakeGenerator -A x64 $(convertToCmakeArgs($depsCmakeVars)) "$buildDir/third-party/" ; exitIfFailed
  104. }
  105. } else {
  106. cmake -G $cmakeGenerator $(convertToCmakeArgs($depsCmakeVars)) "$buildDir/third-party/" ; exitIfFailed
  107. }
  108. cmake --build . --config $cmakeBuildType -- $cmakeGeneratorArgs ; exitIfFailed
  109. cd $buildDir
  110. # Build Neovim
  111. mkdir build
  112. cd build
  113. if ($compiler -eq 'MSVC') {
  114. if ($bits -eq 32) {
  115. cmake -G $cmakeGenerator -A Win32 $(convertToCmakeArgs($nvimCmakeVars)) .. ; exitIfFailed
  116. } else {
  117. cmake -G $cmakeGenerator -A x64 $(convertToCmakeArgs($nvimCmakeVars)) .. ; exitIfFailed
  118. }
  119. } else {
  120. cmake -G $cmakeGenerator $(convertToCmakeArgs($nvimCmakeVars)) .. ; exitIfFailed
  121. }
  122. cmake --build . --config $cmakeBuildType -- $cmakeGeneratorArgs ; exitIfFailed
  123. .\bin\nvim --version ; exitIfFailed
  124. # Ensure that the "win32" feature is set.
  125. .\bin\nvim -u NONE --headless -c 'exe !has(\"win32\").\"cq\"' ; exitIfFailed
  126. if ($env:USE_LUACOV -eq 1) {
  127. & $env:DEPS_PREFIX\luarocks\luarocks.bat install cluacov
  128. }
  129. if (-not $NoTests) {
  130. # Functional tests
  131. # The $LastExitCode from MSBuild can't be trusted
  132. $failed = $false
  133. # Run only this test file:
  134. # $env:TEST_FILE = "test\functional\foo.lua"
  135. cmake --build . --config $cmakeBuildType --target functionaltest -- $cmakeGeneratorArgs 2>&1 |
  136. foreach { $failed = $failed -or
  137. $_ -match 'functional tests failed with error'; $_ }
  138. if ($uploadToCodecov) {
  139. if ($env:USE_LUACOV -eq 1) {
  140. & $env:DEPS_PREFIX\bin\luacov.bat
  141. }
  142. bash -l /c/projects/neovim/ci/common/submit_coverage.sh functionaltest
  143. }
  144. if ($failed) {
  145. exit $LastExitCode
  146. }
  147. # Old tests
  148. # Add MSYS to path, required for e.g. `find` used in test scripts.
  149. # But would break functionaltests, where its `more` would be used then.
  150. $OldPath = $env:PATH
  151. $env:PATH = "C:\msys64\usr\bin;$env:PATH"
  152. & "C:\msys64\mingw$bits\bin\mingw32-make.exe" -C $(Convert-Path ..\src\nvim\testdir) VERBOSE=1 ; exitIfFailed
  153. $env:PATH = $OldPath
  154. if ($uploadToCodecov) {
  155. bash -l /c/projects/neovim/ci/common/submit_coverage.sh oldtest
  156. }
  157. }
  158. # Ensure choco's cpack is not in PATH otherwise, it conflicts with CMake's
  159. if (Test-Path -Path $env:ChocolateyInstall\bin\cpack.exe) {
  160. Remove-Item -Path $env:ChocolateyInstall\bin\cpack.exe -Force
  161. }
  162. # Build artifacts
  163. cpack -C $cmakeBuildType