mirror of
https://github.com/dlang/dmd.git
synced 2025-04-25 12:40:11 +03:00
377 lines
16 KiB
YAML
377 lines
16 KiB
YAML
# Github action to test for C++ interoperability
|
|
#
|
|
# Most tests in the test-suite run on the CI when it comes to cross-platform testing.
|
|
# However, the dlang auto-tester uses somewhat old host C/C++ compiler.
|
|
# This is good for testing compatibility with e.g. LTS distributions,
|
|
# but becomes problematic when we want to test more cutting-edge features,
|
|
# such as newer C++ standards (C++17, C++20, etc...).
|
|
#
|
|
# This is the reason why we have this action: we have full control over the toolchain,
|
|
# and it is cross platform. The supported platforms are whatever Github Actions support,
|
|
# which is usually whatever the vendor (Canonical, Apple, Microsoft) supports.
|
|
#
|
|
# Notes:
|
|
# - Some patterns used here have been developed through a lot of trial and error
|
|
# In particular, the build matrix approach, with two rows, and a large list of
|
|
# excludes, ended up being the most useful approach.
|
|
# - Additionally, the check for the compiler version will save you a lot of trouble.
|
|
# Having the wrong path added to the $PATH and ending up with the wrong compiler
|
|
# being used can make debugging very painful.
|
|
# - Try to use the native Github action syntax (${{ expression }}) when possible,
|
|
# as they are substituted with their value in the logs, unlike env variable.
|
|
# For example use `${{ github.workspace }}` over `${GITHUB_WORKSPACE}`
|
|
#
|
|
# TODO:
|
|
# - Implement Windows + MSVC support
|
|
# - Implement Windows + clang support
|
|
# - Implement Linux + Clang 32 bits support (if possible)
|
|
name: C++ interop tests
|
|
|
|
# Only triggers on pushes to master & stable, as well as PR to master and stable
|
|
# Sometimes reverts appear in the upstream repository (e.g. when the revert button
|
|
# is clicked by a contributor with commit access), this should be tested as PR).
|
|
#
|
|
# Also note that Github actions does not retrigger on target branch changes,
|
|
# hence the check on push.
|
|
on:
|
|
pull_request:
|
|
branches:
|
|
- master
|
|
- stable
|
|
push:
|
|
branches:
|
|
- master
|
|
- stable
|
|
# Use this branch name in your fork to test changes
|
|
- github-actions
|
|
|
|
jobs:
|
|
main:
|
|
name: Run
|
|
if: github.repository == 'dlang/dmd'
|
|
|
|
strategy:
|
|
# Since those tests takes very little time, don't use `fail-fast`.
|
|
# If runtime expand, we might want to comment this out,
|
|
# as most failing PRs do so because they don't compile / something is broken,
|
|
# very few PRs actually benefit from this.
|
|
fail-fast: false
|
|
matrix:
|
|
os: [ macos-13, ubuntu-22.04, windows-2019 ]
|
|
|
|
target: [
|
|
# Versions of clang earlier than 11 are not available on 22.04, but are on macOS 13
|
|
clang-13.0.0, clang-12.0.0, clang-11.0.0, clang-10.0.0, clang-9.0.0, clang-8.0.0,
|
|
# For g++, we test the oldest compiler on Ubuntu 22.04, which is GCC-9
|
|
g++-11, g++-10, g++-9,
|
|
# Finally, we test MSVC 2013 - 2019
|
|
msvc-2019, msvc-2017, msvc-2015, msvc-2013
|
|
]
|
|
|
|
# Exclude target compilers not supported by the host
|
|
# Note: Pattern matching is not supported so this list is quite long,
|
|
# and brittle, as changing an msvc entry would break on OSX, for example.
|
|
exclude:
|
|
# 22.04 only has g++-9 through to 11, and clang-11.0.0 through to 13.0.0
|
|
- { os: ubuntu-22.04, target: clang-10.0.0 }
|
|
- { os: ubuntu-22.04, target: clang-9.0.0 }
|
|
- { os: ubuntu-22.04, target: clang-8.0.0 }
|
|
- { os: ubuntu-22.04, target: msvc-2019 }
|
|
- { os: ubuntu-22.04, target: msvc-2017 }
|
|
- { os: ubuntu-22.04, target: msvc-2015 }
|
|
- { os: ubuntu-22.04, target: msvc-2013 }
|
|
# OSX only supports clang
|
|
- { os: macos-13, target: g++-11 }
|
|
- { os: macos-13, target: g++-10 }
|
|
- { os: macos-13, target: g++-9 }
|
|
- { os: macos-13, target: msvc-2019 }
|
|
- { os: macos-13, target: msvc-2017 }
|
|
- { os: macos-13, target: msvc-2015 }
|
|
- { os: macos-13, target: msvc-2013 }
|
|
# We don't test g++ on Windows as DMD only mangles for MSVC
|
|
- { os: windows-2019, target: g++-11 }
|
|
- { os: windows-2019, target: g++-10 }
|
|
- { os: windows-2019, target: g++-9 }
|
|
|
|
# TODO: Implement support for clang and MSVC2017 on Windows
|
|
# Currently those are still being run by the auto-tester
|
|
# We can hardly test below 2017 in the CI because there's
|
|
# no way to install it via command line
|
|
# (TODO: Test with 2015 as the blog post is slightly ambiguous)
|
|
# https://devblogs.microsoft.com/cppblog/introducing-the-visual-studio-build-tools/
|
|
- { os: windows-2019, target: msvc-2017 }
|
|
- { os: windows-2019, target: msvc-2015 }
|
|
- { os: windows-2019, target: msvc-2013 }
|
|
- { os: windows-2019, target: clang-13.0.0 }
|
|
- { os: windows-2019, target: clang-12.0.0 }
|
|
- { os: windows-2019, target: clang-11.0.0 }
|
|
- { os: windows-2019, target: clang-10.0.0 }
|
|
- { os: windows-2019, target: clang-9.0.0 }
|
|
- { os: windows-2019, target: clang-8.0.0 }
|
|
|
|
# This sets the configuration for each jobs
|
|
# There's a bit of duplication involved (e.g. breaking down g++-9.3 into 2 strings),
|
|
# but some items are unique (e.g. clang-9.0.0 and 4.0.1 have differences in their naming).
|
|
include:
|
|
# Clang boilerplate
|
|
- { target: clang-13.0.0, compiler: clang, cxx-version: 13.0.0 }
|
|
- { target: clang-12.0.0, compiler: clang, cxx-version: 12.0.0 }
|
|
- { target: clang-11.0.0, compiler: clang, cxx-version: 11.0.0 }
|
|
- { target: clang-10.0.0, compiler: clang, cxx-version: 10.0.0 }
|
|
- { target: clang-9.0.0, compiler: clang, cxx-version: 9.0.0 }
|
|
- { target: clang-8.0.0, compiler: clang, cxx-version: 8.0.0 }
|
|
# g++ boilerplace
|
|
- { target: g++-11, compiler: g++, cxx-version: 11.2.0, major: 11 }
|
|
- { target: g++-10, compiler: g++, cxx-version: 10.3.0, major: 10 }
|
|
- { target: g++-9, compiler: g++, cxx-version: 9.4.0, major: 9 }
|
|
# Platform boilerplate
|
|
- { os: ubuntu-22.04, arch: x86_64-linux-gnu-ubuntu-20.04 }
|
|
- { os: macos-13, arch: x86_64-apple-darwin }
|
|
# Clang 9.0.0 have a different arch for OSX
|
|
- { os: macos-13, target: clang-9.0.0, arch: x86_64-darwin-apple }
|
|
# Those targets will generate artifacts that can be used by other testers
|
|
- { storeArtifacts: false }
|
|
- { os: ubuntu-22.04, target: g++-9, storeArtifacts: true }
|
|
- { os: macos-13, target: clang-9.0.0, storeArtifacts: true }
|
|
#- { os: windows-2019, target: msvc-2019, storeArtifacts: true }
|
|
|
|
# We're using the latest available images at the time of this commit.
|
|
# Using a specific version for reproductibility.
|
|
# Feel free to update when a new release has matured.
|
|
runs-on: ${{ matrix.os }}
|
|
steps:
|
|
|
|
- name: Set environment variable N (parallelism)
|
|
shell: bash
|
|
run: echo "N=$(${{ runner.os == 'macOS' && 'sysctl -n hw.logicalcpu' || 'nproc' }})" >> $GITHUB_ENV
|
|
|
|
########################################
|
|
# Setting up the host D compiler #
|
|
########################################
|
|
- name: Prepare compiler
|
|
uses: dlang-community/setup-dlang@v1
|
|
|
|
##############################################
|
|
# Find out which branch we need to check out #
|
|
##############################################
|
|
- name: Determine base branch
|
|
id: base_branch
|
|
shell: bash
|
|
run: |
|
|
# For pull requests, base_ref will not be empty
|
|
if [ ! -z ${{ github.base_ref }} ]; then
|
|
echo "branch=${{ github.base_ref }}" >> $GITHUB_OUTPUT
|
|
# Otherwise, use whatever ref we have:
|
|
# For branches this in the format 'refs/heads/<branch_name>',
|
|
# and for tags it is refs/tags/<tag_name>.
|
|
else
|
|
echo "branch=${{ github.ref }}" >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
#########################################
|
|
# Checking out up DMD, druntime, Phobos #
|
|
#########################################
|
|
- name: Checkout DMD
|
|
uses: actions/checkout@v4
|
|
with:
|
|
path: dmd
|
|
persist-credentials: false
|
|
- name: Checkout Phobos
|
|
uses: actions/checkout@v4
|
|
with:
|
|
path: phobos
|
|
repository: dlang/phobos
|
|
ref: ${{ steps.base_branch.outputs.branch }}
|
|
persist-credentials: false
|
|
|
|
|
|
########################################
|
|
# Setting up the host C++ compiler #
|
|
########################################
|
|
- name: '[Posix] Load cached clang'
|
|
id: cache-clang
|
|
if: matrix.compiler == 'clang' && runner.os != 'Windows'
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: ${{ github.workspace }}/clang+llvm-${{ matrix.cxx-version }}-${{ matrix.arch }}/
|
|
key: ${{ matrix.cxx-version }}-${{ matrix.arch }}-2022-09-25-2121
|
|
|
|
- name: '[Posix] Setting up clang ${{ matrix.cxx-version }}'
|
|
if: matrix.compiler == 'clang' && runner.os != 'Windows' && steps.cache-clang.outputs.cache-hit != 'true'
|
|
run: |
|
|
if [ "${{ matrix.cxx-version }}" == "8.0.0" -o "${{ matrix.cxx-version }}" == "9.0.0" ]; then
|
|
wget --quiet --directory-prefix=${{ github.workspace }} https://releases.llvm.org/${{ matrix.cxx-version }}/clang+llvm-${{ matrix.cxx-version }}-${{ matrix.arch }}.tar.xz
|
|
else
|
|
wget --quiet --directory-prefix=${{ github.workspace }} https://github.com/llvm/llvm-project/releases/download/llvmorg-${{ matrix.cxx-version }}/clang+llvm-${{ matrix.cxx-version }}-${{ matrix.arch }}.tar.xz
|
|
fi
|
|
tar -x -C ${{ github.workspace }} -f ${{ github.workspace }}/clang+llvm-${{ matrix.cxx-version }}-${{ matrix.arch }}.tar.xz
|
|
TMP_CC='${{ github.workspace }}/clang+llvm-${{ matrix.cxx-version }}-${{ matrix.arch }}/bin/clang'
|
|
# On OSX, the system header are installed via `xcode-select` and not distributed with clang
|
|
# Since some part of the testsuite rely on CC and CXX being only a binary (not a command),
|
|
# and config files where only introduced from 6.0.0, use a wrapper script.
|
|
if [ "${{ matrix.os }}" == "macos-13" ]; then
|
|
# Note: heredoc shouldn't be indented
|
|
cat << 'EOF' > ${TMP_CC}-wrapper
|
|
#!/bin/bash
|
|
# Note: We need to use this because github.workspace is not stable
|
|
SCRIPT_FULL_PATH=$(dirname "$0")
|
|
${SCRIPT_FULL_PATH}/clang -isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/ $@
|
|
EOF
|
|
# Invoking clang with `clang++` will link the C++ standard library
|
|
# Make sure we got two separate wrapper for this
|
|
cat << 'EOF' > ${TMP_CC}++-wrapper
|
|
#!/bin/bash
|
|
SCRIPT_FULL_PATH=$(dirname "$0")
|
|
${SCRIPT_FULL_PATH}/clang++ -isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/ $@
|
|
EOF
|
|
chmod +x ${TMP_CC}-wrapper ${TMP_CC}++-wrapper
|
|
fi
|
|
|
|
- name: 'macOS 13: Switch to Xcode v14.3.1' # to work around '-macosx_version_min has been renamed to -macos_version_min' with some clang versions
|
|
if: matrix.os == 'macos-13'
|
|
run: sudo xcode-select -switch /Applications/Xcode_14.3.1.app
|
|
|
|
- name: '[Posix] Setup environment variables'
|
|
if: matrix.compiler == 'clang' && runner.os != 'Windows'
|
|
run: |
|
|
TMP_CC='${{ github.workspace }}/clang+llvm-${{ matrix.cxx-version }}-${{ matrix.arch }}/bin/clang'
|
|
if [ "${{ matrix.os }}" == "macos-13" ]; then
|
|
echo "CC=${TMP_CC}-wrapper" >> $GITHUB_ENV
|
|
echo "CXX=${TMP_CC}++-wrapper" >> $GITHUB_ENV
|
|
echo "SDKROOT=$(xcrun --show-sdk-path)" >> $GITHUB_ENV
|
|
else
|
|
echo "CC=${TMP_CC}" >> $GITHUB_ENV
|
|
echo "CXX=${TMP_CC}++" >> $GITHUB_ENV
|
|
fi
|
|
|
|
# On OSX and Linux, clang is installed by default and in the path,
|
|
# so make sure ${CC} works
|
|
- name: '[Posix] Verifying installed clang version'
|
|
if: matrix.compiler == 'clang' && runner.os != 'Windows'
|
|
run: |
|
|
set -e
|
|
if ${CXX} --version | grep -q 'version ${{ matrix.cxx-version }}'; then
|
|
${CXX} --version
|
|
else
|
|
echo "Expected version ${{ matrix.cxx-version }}, from '${CXX}', got:"
|
|
${CXX} --version
|
|
exit 1
|
|
fi
|
|
|
|
# G++ is only supported on Linux
|
|
- name: '[Linux] Setting up g++ ${{ matrix.cxx-version }}'
|
|
if: matrix.compiler == 'g++'
|
|
run: |
|
|
# Workaround bug in Github actions
|
|
wget https://cli-assets.heroku.com/apt/release.key
|
|
sudo apt-key add release.key
|
|
# Make sure we have the essentials
|
|
sudo apt-get update
|
|
sudo apt-get install ca-certificates
|
|
sudo apt-get install build-essential software-properties-common -y
|
|
# This ppa provides multiple versions of g++
|
|
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
|
|
sudo apt-get update
|
|
sudo apt-get install -y ${{ matrix.target }} ${{ matrix.target }}-multilib
|
|
echo "CC=${{ matrix.target }}" >> $GITHUB_ENV
|
|
echo "CXX=${{ matrix.target }}" >> $GITHUB_ENV
|
|
|
|
# Make sure ${CC} works and we don't use the $PATH one
|
|
- name: '[Linux] Verifying installed g++ version'
|
|
if: matrix.compiler == 'g++'
|
|
run: |
|
|
set -e
|
|
if ${CXX} --version | grep -q '${{ matrix.target }} (Ubuntu '; then
|
|
${CXX} --version
|
|
else
|
|
echo "Expected version ${{ matrix.target }}, from '${CXX}', got:"
|
|
${CXX} --version
|
|
exit 1
|
|
fi
|
|
|
|
- name: '[Windows] Add VC toolset to PATH'
|
|
if: runner.os == 'Windows'
|
|
uses: ilammy/msvc-dev-cmd@v1
|
|
|
|
- name: '[Windows] Set environment variables'
|
|
if: runner.os == 'Windows'
|
|
shell: bash
|
|
run: |
|
|
echo "HOST_DMD=${{ env.DC }}" >> $GITHUB_ENV
|
|
|
|
########################################
|
|
# Building DMD, druntime, Phobos #
|
|
########################################
|
|
- name: '[Posix] Build compiler & standard library'
|
|
if: runner.os != 'Windows'
|
|
run: |
|
|
# All hosts are 64 bits but let's be explicit
|
|
./dmd/compiler/src/build.d -j$N MODEL=64
|
|
make -C dmd/druntime -j$N MODEL=64
|
|
make -C phobos -j$N MODEL=64
|
|
# Both version can live side by side (they end up in a different directory)
|
|
# However, since clang does not provide a multilib package, only test 32 bits with g++
|
|
if [ ${{ matrix.compiler }} == "g++" ]; then
|
|
./dmd/compiler/src/build.d install -j$N MODEL=32
|
|
make -C dmd/druntime install -j$N MODEL=32
|
|
make -C phobos install -j$N MODEL=32
|
|
fi
|
|
|
|
- name: '[Windows] Build compiler & standard library'
|
|
if: runner.os == 'Windows'
|
|
shell: bash
|
|
run: |
|
|
dmd -run dmd/compiler/src/build.d -j$N MODEL=64
|
|
if [ $? -ne 0 ]; then return 1; fi
|
|
# Note: Only CC for druntime and AR for Phobos are required ATM,
|
|
# but providing all three to avoid surprise for future contributors
|
|
# Those should really be in the path, though.
|
|
make -j$N -C dmd/druntime
|
|
if [ $? -ne 0 ]; then return 1; fi
|
|
make -j$N -C phobos
|
|
if [ $? -ne 0 ]; then return 1; fi
|
|
|
|
########################################
|
|
# Running the test suite #
|
|
########################################
|
|
- name: '[Posix] Run C++ test suite'
|
|
if: runner.os != 'Windows'
|
|
env:
|
|
# Reset LD_LIBRARY_PATH when running the tests, so they use the newly built libphobos2.so.
|
|
LD_LIBRARY_PATH: ''
|
|
run: |
|
|
./dmd/compiler/test/run.d --environment runnable_cxx dshell/dll_cxx.d MODEL=64
|
|
if [ ${{ matrix.compiler }} == "g++" ]; then
|
|
./dmd/compiler/test/run.d clean
|
|
./dmd/compiler/test/run.d --environment runnable_cxx dshell/dll_cxx.d MODEL=32
|
|
fi
|
|
|
|
- name: '[Windows] Run C++ test suite'
|
|
if: runner.os == 'Windows'
|
|
shell: bash
|
|
run: |
|
|
make -j$N -C dmd/druntime test/stdcpp/.run
|
|
if [ $? -ne 0 ]; then return 1; fi
|
|
|
|
########################################
|
|
# Run C++ frontend unittests #
|
|
########################################
|
|
- name: Run C++ frontend unittests
|
|
if: matrix.compiler == 'g++'
|
|
run: |
|
|
./dmd/compiler/src/build.d cxx-unittest MODEL=64
|
|
|
|
- name: Run C++ frontend unittests (32-bit)
|
|
if: matrix.compiler == 'g++'
|
|
run: |
|
|
./dmd/compiler/src/build.d cxx-unittest MODEL=32
|
|
|
|
########################################
|
|
# Store generated artifacts #
|
|
########################################
|
|
- name: Store artifacts
|
|
if: ${{ matrix.storeArtifacts }}
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: dmd-${{ matrix.os }}
|
|
path: install
|