diff --git a/.github/workflows/cxx.yml b/.github/workflows/cxx.yml new file mode 100644 index 0000000000..cb65a90bd9 --- /dev/null +++ b/.github/workflows/cxx.yml @@ -0,0 +1,247 @@ +# Github action to test for C++ interoperability +# +# This file is modeled after DMD's Github action definition (`runnable_cxx.yml`). +# Its goal is to test interaction with the C++ standard library on multiple platforms. +# Look up the DMD file for more information about reasoning, patterns, caveats, etc... +# +# TODO: +# - Implement Windows + MSVC support +# - Implement Windows + clang support +# - Implement Linux + Clang 32 bits support (if possible) +name: stdcpp + +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 + strategy: + fail-fast: false + # Matches the matrix in DMD to support the same platforms + matrix: + os: [ macOS-10.15, ubuntu-16.04, windows-2019 ] + target: [ + clang-9.0.0, clang-8.0.0, clang-7.0.0, + clang-6.0.0, clang-5.0.2, clang-4.0.0, clang-3.9.0, + g++-9, g++-8, g++-7, g++-6, g++-5, + msvc-2019, msvc-2017, msvc-2015, msvc-2013 + ] + + exclude: + # Ubuntu supports clang and g++ + - { os: ubuntu-16.04, target: msvc-2019 } + - { os: ubuntu-16.04, target: msvc-2017 } + - { os: ubuntu-16.04, target: msvc-2015 } + - { os: ubuntu-16.04, target: msvc-2013 } + # FIXME: Can't test clang+Linux because DMD assume g++ + - { os: ubuntu-16.04, target: clang-9.0.0 } + - { os: ubuntu-16.04, target: clang-8.0.0 } + - { os: ubuntu-16.04, target: clang-7.0.0 } + - { os: ubuntu-16.04, target: clang-6.0.0 } + - { os: ubuntu-16.04, target: clang-5.0.2 } + - { os: ubuntu-16.04, target: clang-4.0.0 } + - { os: ubuntu-16.04, target: clang-3.9.0 } + # OSX only supports clang + - { os: macOS-10.15, target: g++-9 } + - { os: macOS-10.15, target: g++-8 } + - { os: macOS-10.15, target: g++-7 } + - { os: macOS-10.15, target: g++-6 } + - { os: macOS-10.15, target: g++-5 } + - { os: macOS-10.15, target: msvc-2019 } + - { os: macOS-10.15, target: msvc-2017 } + - { os: macOS-10.15, target: msvc-2015 } + - { os: macOS-10.15, target: msvc-2013 } + # We don't test g++ on Windows as DMD only mangles for MSVC + - { os: windows-2019, target: g++-9 } + - { os: windows-2019, target: g++-8 } + - { os: windows-2019, target: g++-7 } + - { os: windows-2019, target: g++-6 } + - { os: windows-2019, target: g++-5 } + + # TODO: Implement support for clang and MSVC on Windows + # Currently those are still being run by the auto-tester + - os: windows-2019 + + include: + # Clang boilerplate + - { target: clang-9.0.0, compiler: clang, cxx-version: 9.0.0 } + - { target: clang-8.0.0, compiler: clang, cxx-version: 8.0.0 } + - { target: clang-7.0.0, compiler: clang, cxx-version: 7.0.0 } + - { target: clang-6.0.0, compiler: clang, cxx-version: 6.0.0 } + - { target: clang-5.0.2, compiler: clang, cxx-version: 5.0.2 } + - { target: clang-4.0.0, compiler: clang, cxx-version: 4.0.0 } + - { target: clang-3.9.0, compiler: clang, cxx-version: 3.9.0 } + # g++ boilerplace + - { target: g++-9, compiler: g++, cxx-version: 9.3.0 } + - { target: g++-8, compiler: g++, cxx-version: 8.4.0 } + - { target: g++-7, compiler: g++, cxx-version: 7.5.0 } + - { target: g++-6, compiler: g++, cxx-version: 6.5.0 } + - { target: g++-5, compiler: g++, cxx-version: 5.5.0 } + # Platform boilerplate + - { os: ubuntu-16.04, arch: x86_64-linux-gnu-ubuntu-16.04 } + - { os: macOS-10.15, arch: x86_64-apple-darwin } + # Clang 9.0.0 have a different arch for OSX + - { os: macOS-10.15, target: clang-9.0.0, arch: x86_64-darwin-apple } + + runs-on: ${{ matrix.os }} + steps: + + ######################################## + # Setting up the host D compiler # + ######################################## + - name: Prepare compiler + uses: mihails-strasuns/setup-dlang@v0.5.0 + with: + compiler: dmd-2.091.0 + gh_token: ${{ secrets.GITHUB_TOKEN }} + + ######################################### + # Checking out up DMD, druntime, Phobos # + ######################################### + - name: Checkout DMD + uses: actions/checkout@v2 + with: + path: dmd + repository: dlang/dmd + ref: ${{ github.base_ref }} + persist-credentials: false + - name: Checkout druntime + uses: actions/checkout@v2 + with: + path: druntime + persist-credentials: false + - name: Checkout Phobos + uses: actions/checkout@v2 + with: + path: phobos + repository: dlang/phobos + ref: ${{ github.base_ref }} + persist-credentials: false + + + ######################################## + # Setting up the host C++ compiler # + ######################################## + - name: '[Posix] Setting up clang ${{ matrix.cxx-version }}' + if: matrix.compiler == 'clang' && runner.os != 'Windows' + run: | + wget --quiet --directory-prefix=${{ github.workspace }} https://releases.llvm.org/${{ matrix.cxx-version }}/clang+llvm-${{ matrix.cxx-version }}-${{ matrix.arch }}.tar.xz + 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 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-10.15" ]; then + # Note: heredoc shouldn't be indented + cat < ${TMP_CC}-wrapper + #!/bin/bash + ${TMP_CC} -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 < ${TMP_CC}++-wrapper + #!/bin/bash + ${TMP_CC}++ -isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/ \$@ + EOF + chmod +x ${TMP_CC}-wrapper ${TMP_CC}++-wrapper + echo ::set-env name=CC::${TMP_CC}-wrapper + echo ::set-env name=CXX::${TMP_CC}++-wrapper + else + # Note: druntime's tests use `CXX` and DMD uses `CC` + echo ::set-env name=CC::${TMP_CC} + echo ::set-env name=CXX::${TMP_CC}++ + 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 + ${CXX} -print-search-dirs -print-libgcc-file-name + else + echo "Expected version ${{ matrix.cxx-version }}, from '${CC}', 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 + curl https://cli-assets.heroku.com/apt/release.key | sudo apt-key add - + # Make sure we have the essentials + sudo apt-get update + 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 ${{ matrix.target }} ${{ matrix.target }}-multilib + echo ::set-env name=CC::${{ matrix.target }} + echo ::set-env name=CXX::${{ matrix.target }} + + # 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 + + ######################################## + # Building DMD, druntime, Phobos # + ######################################## + - name: '[Posix] Build compiler & standard library' + run: | + # All hosts are 64 bits but let's be explicit + ./dmd/src/build.d -j2 MODEL=64 + make -C druntime -f posix.mak -j2 MODEL=64 + make -C phobos -f posix.mak -j2 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/src/build.d -j2 MODEL=32 + make -C druntime -f posix.mak -j2 MODEL=32 + make -C phobos -f posix.mak -j2 MODEL=32 + fi + + ######################################## + # Running the test suite # + ######################################## + - name: Run C++ test suite + run: | + make -C druntime -f posix.mak test/stdcpp/.run MODEL=64 + if [ ${{ matrix.compiler }} == "g++" ]; then + ./dmd/test/run.d clean + make -C druntime -f posix.mak test/stdcpp/.run MODEL=32 + fi + + ######################################## + # Dump symbols on link failure # + ######################################## + - name: '[Posix,Fail] Dump C++ / D binary symbols' + if: failure() && runner.os != 'Windows' + run: | + ls -l druntime/generated/*/release/*/ + for file in druntime/generated/*/release/*/*.o*; do + echo "========== Symbols for '$file' ==========" + nm $file + done diff --git a/posix.mak b/posix.mak index b3b80a1311..6d9833a197 100644 --- a/posix.mak +++ b/posix.mak @@ -51,7 +51,7 @@ endif ifeq (osx,$(OS)) DOTDLL:=.dylib DOTLIB:=.a - export MACOSX_DEPLOYMENT_TARGET=10.7 + export MACOSX_DEPLOYMENT_TARGET=10.9 else DOTDLL:=.so DOTLIB:=.a diff --git a/test/common.mak b/test/common.mak index eb1839eab1..b4ea48f4eb 100644 --- a/test/common.mak +++ b/test/common.mak @@ -30,7 +30,3 @@ else endif CXXFLAGS_BASE := $(CFLAGS_BASE) CXXFLAGS:=$(CFLAGS) -ifeq (osx,$(OS)) - CXXFLAGS+=-stdlib=libc++ - CXXFLAGS_BASE+=-stdlib=libc++ -endif diff --git a/test/stdcpp/Makefile b/test/stdcpp/Makefile index 4ade1458cb..4bed868171 100644 --- a/test/stdcpp/Makefile +++ b/test/stdcpp/Makefile @@ -29,14 +29,6 @@ endif .PHONY: all clean -# osx32 does not link properly, nobody uses it anyway... -ifeq ($(OS)$(MODEL), osx32) - -all: - -clean: - -else all: $(addprefix $(ROOT)/,$(addsuffix .done,$(TESTS))) $(addprefix $(ROOT)/,$(addsuffix _11.done,$(TESTS11))) $(addprefix $(ROOT)/,$(addsuffix _17.done,$(TESTS17))) $(addprefix $(ROOT)/,$(addsuffix _old.done,$(OLDABITESTS))) $(addprefix $(ROOT)/,$(addsuffix _libcpp.done,$(LIBCPPTESTS))) # run C++98 tests @@ -83,4 +75,3 @@ $(ROOT)/%_old: $(SRC)/%.cpp $(SRC)/%_test.d clean: rm -rf $(GENERATED) -endif