Update Changes #59
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build with MSVC | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} | |
| cancel-in-progress: true | |
| on: | |
| push: | |
| branches: | |
| - '4.**' | |
| - '5.**' | |
| - 'trunk' | |
| pull_request: | |
| env: | |
| # Fully print commands executed by Make | |
| # MAKEFLAGS: V=1 | |
| # Disable 'cold' tests | |
| OCAMLTEST_COLD_TESTS: 0 | |
| defaults: | |
| run: | |
| shell: bash -eo pipefail -o igncr {0} | |
| jobs: | |
| config: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.matrix.outputs.result}} | |
| full-matrix: ${{ steps.matrix.outputs.full-matrix }} | |
| skip-testsuite: ${{ steps.skip.outputs.result }} | |
| steps: | |
| - name: Compute matrix for the "build" job | |
| id: matrix | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| // # Always test cl and clang-cl | |
| let compilers = ['clang-cl']; | |
| // # Also test i686 MSVC | |
| let include = [ | |
| {os: 'windows-latest', cc: 'cl', arch: 'i686', opam: 'false', prefix: '$PROGRAMFILES/Бактріан🐫', libdir: 'relative'}, | |
| {os: 'windows-2025', cc: 'cl', arch: 'x86_64', opam: 'true', prefix: 'C:\\\\Бактріан🐫'}, | |
| {os: 'windows-2025', cc: 'cl', arch: 'i686', opam: 'true', prefix: 'C:\\\\Бактріан🐫'}]; | |
| let libdir = ['absolute']; | |
| // # If this is a pull request, see if the PR has the | |
| // # 'CI: Full matrix' label. This is done using an API request, | |
| // # rather than from context.payload.pull_request.labels, since we | |
| // # want the _current_ list of labels. This allows the labelling to | |
| // # be changed, and then forcing a re-run of the workflow, rather | |
| // # than having labelling triggering a fresh workflow event (which | |
| // # is wasteful). | |
| let full_matrix = false; | |
| if (context.payload.pull_request) { | |
| const { data: labels } = | |
| await github.rest.issues.listLabelsOnIssue({...context.repo, issue_number: context.payload.pull_request.number}); | |
| full_matrix = labels.some(label => label.name === 'CI: Full matrix'); | |
| if (full_matrix) { | |
| console.log('Full matrix requested'); | |
| // # Test Cygwin as well | |
| compilers.push('gcc'); | |
| // # Test bytecode-only Cygwin | |
| include.push({os: 'windows-latest', prefix: '$PROGRAMFILES/Бактріан🐫', opam: ['false'], cc: 'gcc', arch: 'x86_64', libdir: 'absolute', config_arg: '--disable-native-toplevel --disable-native-compiler'}); | |
| // # Test i686 MSVC absolute | |
| include.push({os: 'windows-latest', prefix: '$PROGRAMFILES/Бактріан🐫', opam: ['false'], cc: 'cl', arch: 'i686', libdir: 'absolute'}); | |
| // # Expand the main matrix to include relative testing | |
| libdir.push('relative'); | |
| } | |
| } | |
| core.setOutput('full-matrix', full_matrix); | |
| return {os: ['windows-latest'], prefix: ['$PROGRAMFILES/Бактріан🐫'], opam: ['false'], config_arg: [''], arch: ['x86_64'], cc: compilers, libdir: libdir, include: include}; | |
| - name: Determine if the testsuite should be skipped | |
| id: skip | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| let skip_testsuite = false; | |
| if (context.payload.pull_request) { | |
| const { data: labels } = | |
| await github.rest.issues.listLabelsOnIssue({...context.repo, issue_number: context.payload.pull_request.number}); | |
| skip_testsuite = labels.some(label => label.name === 'CI: Skip testsuite'); | |
| } | |
| console.log('Skip testsuite: ' + skip_testsuite); | |
| return skip_testsuite; | |
| build: | |
| permissions: {} | |
| runs-on: ${{ matrix.os }} | |
| needs: config | |
| timeout-minutes: ${{ matrix.cc == 'gcc' && 90 || 60 }} | |
| name: ${{ matrix.cc == 'cl' && 'MSVC' || matrix.cc == 'gcc' && 'Cygwin' || 'clang-cl' }} ${{ matrix.arch }} ${{ matrix.libdir }} ${{ matrix.config_arg != '' && format('({0})', matrix.config_arg) || '' }} | |
| strategy: | |
| matrix: ${{ fromJSON(needs.config.outputs.matrix) }} | |
| fail-fast: ${{ needs.config.outputs.full-matrix != 'true' }} | |
| steps: | |
| - name: Fetch OCaml | |
| uses: actions/checkout@v6 | |
| with: | |
| submodules: true | |
| - name: Restore Cygwin cache | |
| uses: actions/cache/restore@v5 | |
| with: | |
| path: | | |
| D:\cygwin-packages | |
| key: cygwin-packages | |
| - name: Install Cygwin | |
| uses: cygwin/cygwin-install-action@v6 | |
| with: | |
| packages: make,${{ matrix.cc != 'gcc' && 'mingw64-x86_64-' || 'gcc-g++,gcc-fortran,' }}gcc-core,rsync,unzip | |
| install-dir: 'D:\cygwin' | |
| - name: Save Cygwin cache | |
| uses: actions/cache/save@v5 | |
| with: | |
| path: | | |
| D:\cygwin-packages | |
| key: cygwin-packages | |
| - name: Set up MSVC | |
| uses: ilammy/msvc-dev-cmd@v1 | |
| with: | |
| arch: ${{ matrix.arch == 'x86_64' && 'x64' || 'x86' }} | |
| if: matrix.cc != 'gcc' | |
| - name: Install opam | |
| if: matrix.opam == 'true' | |
| shell: pwsh | |
| run: | | |
| winget install opam --accept-source-agreements | |
| Add-Content -Path $env:GITHUB_PATH -Value "$env:LOCALAPPDATA\Microsoft\WinGet\Links" | |
| - name: Compute a key to cache configure results | |
| id: autoconf-cache-key | |
| env: | |
| HOST: ${{ format('{0}-pc-{1}', matrix.arch, (matrix.cc == 'gcc' && 'cygwin' || 'windows')) }} | |
| run: | | |
| echo "key=${{ env.HOST }}-${{ matrix.cc }}-${{ hashFiles('configure') }}" >> $GITHUB_OUTPUT | |
| - name: Restore Autoconf cache | |
| uses: actions/cache/restore@v5 | |
| with: | |
| path: | | |
| config.cache | |
| key: ${{ steps.autoconf-cache-key.outputs.key }} | |
| - name: Configure tree | |
| env: | |
| CONFIG_ARGS: >- | |
| --cache-file=config.cache | |
| --prefix ${{ matrix.cc != 'gcc' && format('"{0}/_opam"', matrix.prefix) || format('"$(cygpath "{0}")"', matrix.prefix) }} | |
| --docdir ${{ format((matrix.cc != 'gcc' && '"{0}/_opam/doc/ocaml"' || '"$(cygpath "{0}/doc/ocaml")"'), matrix.prefix) }} | |
| ${{ matrix.cc != 'gcc' && format('--host={0}-pc-windows', matrix.arch) || '' }} | |
| ${{ matrix.cc != 'gcc' && format('CC={0}', matrix.cc) || '' }} | |
| --enable-ocamltest | |
| ${{ endsWith(matrix.arch, '64') && '--enable-native-toplevel' || '--disable-native-toplevel' }} | |
| ${{ matrix.libdir == 'relative' && '--with-relative-libdir' || '--without-relative-libdir' }} | |
| ${{ matrix.libdir == 'relative' && '--enable-runtime-search --enable-runtime-search-target=fallback' || '--disable-runtime-search --disable-runtime-search-target' }} | |
| ${{ matrix.config_arg }} | |
| run: | | |
| eval $(tools/msvs-promote-path) | |
| if ! ./configure ${{ env.CONFIG_ARGS }} ; then | |
| rm -rf config.cache | |
| failed=0 | |
| ./configure ${{ env.CONFIG_ARGS }} || failed=$? | |
| if ((failed)) ; then | |
| echo | |
| echo "::group::config.log content ($(wc -l config.log) lines)" | |
| cat config.log | |
| echo '::endgroup::' | |
| exit $failed | |
| fi | |
| fi | |
| - name: Save Autoconf cache | |
| uses: actions/cache/save@v5 | |
| with: | |
| path: | | |
| config.cache | |
| key: ${{ steps.autoconf-cache-key.outputs.key }} | |
| - name: Build OCaml | |
| run: | | |
| eval $(tools/msvs-promote-path) | |
| make -j || failed=$? | |
| if ((failed)) ; then make -j1 V=1 ; exit $failed ; fi | |
| test -e runtime/libcamlrun.lib || tools/check-symbol-names runtime/*.a otherlibs/*/lib*.a | |
| runtime/ocamlrun ocamlc -config | |
| - name: Assemble backend with mingw-w64 GASM and compare | |
| run: | | |
| x86_64-w64-mingw32-gcc -c -I./runtime -I ./flexdll -D__USE_MINGW_ANSI_STDIO=0 -DUNICODE -D_UNICODE -DWINDOWS_UNICODE=1 -DCAMLDLLIMPORT= -DIN_CAML_RUNTIME -DNATIVE_CODE -DTARGET_amd64 -DMODEL_default -DSYS_mingw64 -o runtime/amd64.o runtime/amd64.S | |
| dumpbin /disasm:nobytes runtime/amd64nt.obj > runtime/amd64nt.dump | |
| awk -f tools/ci/actions/canonicalize-dumpbin.awk runtime/amd64nt.dump runtime/amd64nt.dump > runtime/amd64nt.canonical | |
| dumpbin /disasm:nobytes runtime/amd64.o > runtime/amd64.dump | |
| awk -f tools/ci/actions/canonicalize-dumpbin.awk runtime/amd64.dump runtime/amd64.dump > runtime/amd64.canonical | |
| git diff --no-index -- runtime/amd64*.canonical | |
| wc -l runtime/amd64*.dump runtime/amd64*.canonical | |
| # ^ The final wc is there to make sure that the canonical files are | |
| # reasonable cleaned-up versions of the raw dumpbins and not simply | |
| # empty | |
| if: endsWith(matrix.arch, '64') && matrix.cc != 'gcc' | |
| - name: Run the test suite | |
| if: ${{ needs.config.outputs.skip-testsuite != 'true' }} | |
| run: | | |
| eval $(tools/msvs-promote-path) | |
| make tests | |
| - name: Install the compiler | |
| if: matrix.opam != 'true' | |
| run: make install | |
| - name: Create opam switch | |
| if: matrix.opam == 'true' | |
| env: | |
| OPAMSWITCH: ${{ matrix.prefix }} | |
| run: | | |
| make OPAM_PACKAGE_NAME=ocaml-variants INSTALL_MODE=opam install | |
| opam init --cli=2.4 --bare --yes --disable-sandboxing --auto-setup --cygwin-local-install | |
| # These commands intentionally run using opam's "default" CLI | |
| opam switch create '${{ env.OPAMSWITCH }}' --empty | |
| opam pin add --no-action --kind=path ocaml-variants . | |
| opam pin add --no-action flexdll flexdll | |
| opam install --yes flexdll | |
| opam install --yes --assume-built ocaml-variants | |
| opam exec -- ocamlc -v | |
| - name: Test in prefix | |
| run: | | |
| eval $(tools/msvs-promote-path) | |
| make -f Makefile.test -C testsuite/in_prefix test-in-prefix |