1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
|
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
defaults:
run:
shell: bash -eo pipefail -o igncr {0}
jobs:
config:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.matrix.outputs.result}}
skip-testsuite: ${{ steps.skip.outputs.result }}
steps:
- name: Compute matrix for the "build" job
id: matrix
uses: actions/github-script@v7
with:
script: |
// # Always test cl and clang-cl
let compilers = ['cl', 'clang-cl'];
// # Also test i686 MSVC
let include = [
{cc: 'cl', arch: 'i686'}];
// # 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).
if (context.payload.pull_request) {
const { data: labels } =
await github.rest.issues.listLabelsOnIssue({...context.repo, issue_number: context.payload.pull_request.number});
if (labels.some(label => label.name === 'CI: Full matrix')) {
console.log('Full matrix requested');
// # Test Cygwin as well
compilers.push('gcc');
// # Test bytecode-only Cygwin
include.push({cc: 'gcc', arch: 'x86_64', config_arg: '--disable-native-compiler'});
}
}
return {config_arg: [''], arch: ['x86_64'], cc: compilers, include: include};
- name: Determine if the testsuite should be skipped
id: skip
uses: actions/github-script@v7
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: windows-latest
needs: config
timeout-minutes: ${{ matrix.cc == 'gcc' && 90 || 60 }}
name: ${{ matrix.cc == 'cl' && 'MSVC' || matrix.cc == 'gcc' && 'Cygwin' || 'clang-cl' }} ${{ matrix.arch }} ${{ matrix.config_arg != '' && format('({0})', matrix.config_arg) || '' }}
strategy:
matrix: ${{ fromJSON(needs.config.outputs.matrix) }}
fail-fast: true
steps:
- name: Fetch OCaml
uses: actions/checkout@v4
with:
submodules: true
- name: Restore Cygwin cache
uses: actions/cache/restore@v4
with:
path: |
C:\cygwin-packages
key: cygwin-packages
- name: Install Cygwin
uses: cygwin/cygwin-install-action@v3
with:
packages: make,${{ matrix.cc != 'gcc' && 'mingw64-x86_64-' || 'gcc-fortran,' }}gcc-core
install-dir: 'D:\cygwin'
- name: Save Cygwin cache
uses: actions/cache/save@v4
with:
path: |
C:\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: 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@v4
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' && '$PROGRAMFILES/Бактріан🐫' || '$(cygpath "$PROGRAMFILES/Бактріан🐫")'}}"
${{ matrix.cc != 'gcc' && format('--host={0}-pc-windows', matrix.arch) || '' }}
${{ matrix.cc != 'gcc' && format('CC={0}', matrix.cc) || '' }}
${{ 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@v4
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
run: make install
|