diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..9f0fff59 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,117 @@ + +name: Windows Implementation Library CI + +on: + pull_request: + push: + branches: + - master + +jobs: + format: + name: Format Check + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check Formatting + shell: cmd + run: | + REM The architecture is not important; we just need VCINSTALLDIR set + call scripts\call-vcvars.cmd x64 + call scripts\format-changes.cmd origin/master + if %ERRORLEVEL% neq 0 ( + echo ::error::ERROR: This branch contains changes that have not been formatted with 'clang-format' + echo NOTE: To resolve this issue, you can run 'clang-format' in the following ways: + echo * Run `scripts/format-changes.cmd ^` where '^' is either 'origin/master' or 'upstream/master' + echo depending on whether or not this is a fork. This will only format the changes you made relative to the + echo master branch in the 'microsoft/wil' repo. + echo * Run `scripts/run-clang-format.cmd` which will run 'clang-format' on _all_ source files. This script is + echo simpler to run, however there's a chance it may touch additional files you never changed due to you having + echo a mis-matched version of 'clang-format'. This may require you to manually revert changes made by + echo 'clang-format' to the locations where you made no code changes. + echo * Build the 'format' target ^(e.g. `ninja format`^). This is equivalent to running the second option above. + echo. + echo For more information, please see https://github.com/microsoft/wil?tab=readme-ov-file#formatting + echo. + echo NOTE: As an additional note, given that different versions of 'clang-format' may have different behaviors, this + echo may be a false positive. If you believe that to be the case ^(e.g. none of the above resulted in modifications + echo to the code you have changed^), please note this in your PR. + echo ---------------------------------------------- + echo See below for the file^(s^) that have changed: + git diff + exit /b 1 + ) + + build_and_test: + name: Build and Test + strategy: + matrix: + host: [ windows-latest, windows-11-arm ] + arch: [ x64, x64_x86, arm64 ] + compiler: [ msvc, clang ] + config: [ debug, relwithdebinfo ] + exclude: + - host: windows-latest + arch: arm64 + - host: windows-11-arm + arch: x64 + - host: windows-11-arm + arch: x64_x86 + + runs-on: ${{matrix.host}} + steps: + - uses: actions/checkout@v4 + + - name: Install/Update Clang + if: matrix.compiler == 'clang' + shell: cmd + run: | + choco upgrade llvm -y + if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL% + + REM This is somewhat of a hack... we want to use the path to LLVM instead of MSVC's LLVM installation, but + REM _only_ when we're actually building with Clang. This is taking advantage of the fact that we're only + REM setting this variable when 'matrix.compiler' is 'clang'. + echo LLVM_PATH=C:\Program Files\LLVM\bin >> %GITHUB_ENV% + + - name: Initialize CMake + shell: cmd + run: | + call scripts\call-vcvars.cmd ${{matrix.arch}} + if %ERRORLEVEL% NEQ 0 goto :eof + + REM vcvarsall likes to stick it's dirty fingers into the root of the PATH, which means we'll pick up the + REM version of LLVM installed with VS, which we _don't_ want. + set PATH=%LLVM_PATH%;%PATH% + + call scripts\init.cmd -c ${{matrix.compiler}} -b ${{matrix.config}} + + - name: Build Tests + shell: cmd + run: | + call scripts\call-vcvars.cmd ${{matrix.arch}} + if %ERRORLEVEL% NEQ 0 goto :eof + + REM vcvarsall likes to stick it's dirty fingers into the root of the PATH, which means we'll pick up the + REM version of LLVM installed with VS, which we _don't_ want. + set PATH=%LLVM_PATH%;%PATH% + + call scripts\build_all.cmd + + - name: Run Tests + shell: cmd + run: | + call scripts\call-vcvars.cmd ${{matrix.arch}} + if %ERRORLEVEL% NEQ 0 goto :eof + + REM vcvarsall likes to stick it's dirty fingers into the root of the PATH, which means we'll pick up the + REM version of LLVM installed with VS, which we _don't_ want. + set PATH=%LLVM_PATH%;%PATH% + + REM NOTE: You can add '-s' to display detailed information about passing assertions, which can be helpful for diagnosing + REM hanging tests, however the callstack logic has mostly rendered this unnecssary for most scenarios. + REM That said, we do pass '-d yes' so that it's easier to see which tests were run immediately before a hanging/crashing test + call scripts\runtests.cmd ~[LocalOnly] -d yes diff --git a/scripts/call-vcvars.cmd b/scripts/call-vcvars.cmd index 2e9aa1ca..924276b3 100644 --- a/scripts/call-vcvars.cmd +++ b/scripts/call-vcvars.cmd @@ -8,10 +8,10 @@ if NOT EXIST "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxili echo ERROR: Could not locate 'vcvars' batch file. This script is intended to be run from a build machine & exit /B 1 ) -if /I "%1"=="x86" ( - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64_x86 -) else if /I "%1"=="x64" ( - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 -) else if /I "%1"=="arm64" ( - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" arm64 -) else echo ERROR: Requires one of 'x86', 'x64', or 'arm64' & exit /B 1 +set ARCH=%1 +if /I "%ARCH%"=="x86" ( + REM Use the x64 toolchain + set ARCH=x64_x86 +) + +call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" %ARCH% diff --git a/scripts/init.cmd b/scripts/init.cmd index d13b17cd..eb7699f2 100644 --- a/scripts/init.cmd +++ b/scripts/init.cmd @@ -268,7 +268,9 @@ goto :init set ASAN_DLL_PATH= if %COMPILER%==clang ( set CLANG_CL_PATH= - for /f "delims=" %%c in ('where clang-cl 2^> NUL') do set CLANG_CL_PATH=%%~dpc + for /f "delims=" %%c in ('where clang-cl 2^> NUL') do ( + if "!CLANG_CL_PATH!"=="" set CLANG_CL_PATH=%%~dpc + ) :: Arguably an error if we can't find it, but just to be safe... if "!CLANG_CL_PATH!" NEQ "" ( for /f "delims=" %%d in ('where /R "!CLANG_CL_PATH!\..\lib" clang_rt.asan_dynamic-%ARCH_NAME%.dll 2^> NUL') do set ASAN_DLL_PATH=%%d