diff --git a/.travis.yml b/.travis.yml index c1f9a626ae78..2e197b2c95ff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,12 @@ language: d d: - dmd - - gdc - ldc script: + - DMD_BIN="$DMD" - deactivate # deactivate d compiler + - export DMD="$DMD_BIN" - ./travis.sh sudo: false @@ -18,7 +19,6 @@ addons: env: - MODEL=32 - - MODEL=64 matrix: include: diff --git a/README.md b/README.md index b49ce515ec2d..f89f02f9e57f 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,9 @@ DMD [![Code coverage](https://img.shields.io/codecov/c/github/dlang/dmd.svg?maxAge=86400)](https://codecov.io/gh/dlang/dmd) [![license](https://img.shields.io/github/license/dlang/dmd.svg)](https://github.com/dlang/dmd/blob/master/LICENSE.txt) +[![CircleCI](https://circleci.com/gh/dlang/dmd/tree/master.svg?style=svg)](https://circleci.com/gh/dlang/dmd/tree/master) +[![Build Status](https://semaphoreci.com/api/v1/cybershadow/dmd/branches/master/badge.svg)](https://semaphoreci.com/cybershadow/dmd) + DMD is the reference compiler for the D programming language. To report a problem or browse the list of open bugs, please visit the diff --git a/ci.sh b/ci.sh new file mode 100755 index 000000000000..590e9063a29c --- /dev/null +++ b/ci.sh @@ -0,0 +1,154 @@ +#!/bin/bash + +set -uexo pipefail + +if [ -z ${N+x} ] ; then echo "Variable 'N' needs to be set."; exit 1; fi +if [ -z ${BRANCH+x} ] ; then echo "Variable 'BRANCH' needs to be set."; exit 1; fi +if [ -z ${OS_NAME+x} ] ; then echo "Variable 'OS_NAME' needs to be set."; exit 1; fi +if [ -z ${FULL_BUILD+x} ] ; then echo "Variable 'FULL_BUILD' needs to be set."; exit 1; fi +if [ -z ${MODEL+x} ] ; then echo "Variable 'MODEL' needs to be set."; exit 1; fi +if [ -z ${DMD+x} ] ; then echo "Variable 'DMD' needs to be set."; exit 1; fi + +CURL_USER_AGENT="DMD-CI $(curl --version | head -n 1)" + +# use faster ld.gold linker on linux +if [ "$OS_NAME" == "linux" ]; then + mkdir -p linker + rm -f linker/ld + ln -s /usr/bin/ld.gold linker/ld + NM="nm --print-size" + export PATH="$PWD/linker:$PATH" +else + NM=nm +fi + +# clone druntime and phobos +clone() { + local url="$1" + local path="$2" + local branch="$3" + for i in {0..4}; do + if git clone --depth=1 --branch "$branch" "$url" "$path"; then + break + elif [ $i -lt 4 ]; then + sleep $((1 << $i)) + else + echo "Failed to clone: ${url}" + exit 1 + fi + done +} + +# build dmd, druntime, phobos +build() { + source ~/dlang/*/activate # activate host compiler + make -j$N -C src -f posix.mak MODEL=$MODEL HOST_DMD=$DMD ENABLE_RELEASE=1 ENABLE_WARNINGS=1 all + make -j$N -C ../druntime -f posix.mak MODEL=$MODEL + make -j$N -C ../phobos -f posix.mak MODEL=$MODEL + deactivate # deactivate host compiler +} + +# self-compile dmd +rebuild() { + local build_path=generated/$OS_NAME/release/$MODEL + local compare=${1:-0} + # `generated` gets cleaned in the next step, so we create another _generated + # The nested folder hierarchy is needed to conform to those specified in + # the generated dmd.conf + mkdir -p _${build_path} + cp $build_path/dmd _${build_path}/host_dmd + cp $build_path/dmd.conf _${build_path} + make -j$N -C src -f posix.mak MODEL=$MODEL HOST_DMD=../_${build_path}/host_dmd clean + make -j$N -C src -f posix.mak MODEL=$MODEL HOST_DMD=../_${build_path}/host_dmd ENABLE_RELEASE=1 ENABLE_WARNINGS=1 all + + # compare binaries to test reproducible build + if [ $compare -eq 1 ]; then + if ! diff _${build_path}/host_dmd $build_path/dmd; then + $NM _${build_path}/host_dmd > a + $NM $build_path/dmd > b + diff -u a b + exit 1 + fi + fi +} + +# test druntime, phobos, dmd +test() { + test_dub_package + make -j$N -C ../druntime -f posix.mak MODEL=$MODEL unittest + make -j$N -C ../phobos -f posix.mak MODEL=$MODEL unittest + test_dmd +} + +# test dmd +test_dmd() { + # test fewer compiler argument permutations for PRs to reduce CI load + if [ "$FULL_BUILD" == "true" ] && [ "$OS_NAME" == "linux" ]; then + make -j$N -C test MODEL=$MODEL # all ARGS by default + else + make -j$N -C test MODEL=$MODEL ARGS="-O -inline -release" + fi +} + +# test dub package +test_dub_package() { + source ~/dlang/*/activate # activate host compiler + # GDC's standard library is too old for some example scripts + if [ "${DMD:-dmd}" == "gdmd" ] ; then + echo "Skipping DUB examples on GDC." + else + pushd test/dub_package + for file in *.d ; do + dub --single "$file" + done + popd + fi + deactivate +} + +setup_repos() { +for proj in druntime phobos; do + if [ $BRANCH != master ] && [ $BRANCH != stable ] && + ! git ls-remote --exit-code --heads https://github.com/dlang/$proj.git $BRANCH > /dev/null; then + # use master as fallback for other repos to test feature branches + clone https://github.com/dlang/$proj.git ../$proj master + else + clone https://github.com/dlang/$proj.git ../$proj $BRANCH + fi +done +} + +testsuite() { + date + for step in build test rebuild "rebuild 1" test_dmd; do + $step + date + done +} + +download_install_sh() { + local mirrors location + location="${1:-install.sh}" + mirrors=( + "https://dlang.org/install.sh" + "https://downloads.dlang.org/other/install.sh" + "https://nightlies.dlang.org/install.sh" + "https://github.com/dlang/installer/raw/master/script/install.sh" + ) + if [ -f "$location" ] ; then + return + fi + for i in {0..4}; do + for mirror in "${mirrors[@]}" ; do + if curl -fsS -A "$CURL_USER_AGENT" --connect-timeout 5 --speed-time 30 --speed-limit 1024 "$mirror" -O ; then + break 2 + fi + done + sleep $((1 << i)) + done +} + +activate_d() { + download_install_sh "$@" + CURL_USER_AGENT="$CURL_USER_AGENT" bash install.sh "$1" --activate +} diff --git a/semaphoreci.sh b/semaphoreci.sh new file mode 100755 index 000000000000..a4055a68dd88 --- /dev/null +++ b/semaphoreci.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +set -uexo pipefail + +################################################################################ +# Set by the Semaphore job runner +################################################################################ + +export MODEL=${MODEL:-64} # can be {32,64} +export DMD=${DMD:-dmd} # can be {dmd,ldc,gdc} + +################################################################################ +# Static variables or inferred from Semaphore +# See also: https://semaphoreci.com/docs/available-environment-variables.html +################################################################################ + +export N=4 +export OS_NAME=linux +export BRANCH=$BRANCH_NAME +export FULL_BUILD="${PULL_REQUEST_NUMBER+false}" + +source ci.sh + +################################################################################ +# Always source a DMD instance +################################################################################ + +source "$(activate_d "$DMD")" + +################################################################################ +# Define commands +################################################################################ + +case $1 in + setup) setup_repos ;; + testsuite) testsuite ;; +esac diff --git a/travis.sh b/travis.sh index f25f115cd905..760b6133be0a 100755 --- a/travis.sh +++ b/travis.sh @@ -2,114 +2,22 @@ set -uexo pipefail -N=2 +################################################################################ +# Static variables or inferred from Travis +# https://docs.travis-ci.com/user/environment-variables/ +################################################################################ -# use faster ld.gold linker on linux -if [ "$TRAVIS_OS_NAME" == "linux" ]; then - mkdir linker - ln -s /usr/bin/ld.gold linker/ld - NM="nm --print-size" - export PATH="$PWD/linker:$PATH" -else - NM=nm -fi +export N=2 +export OS_NAME="${TRAVIS_OS_NAME}" +export MODEL="${MODEL}" +export BRANCH="${TRAVIS_BRANCH}" +export FULL_BUILD=false -# clone druntime and phobos -clone() { - local url="$1" - local path="$2" - local branch="$3" - for i in {0..4}; do - if git clone --depth=1 --branch "$branch" "$url" "$path"; then - break - elif [ $i -lt 4 ]; then - sleep $((1 << $i)) - else - echo "Failed to clone: ${url}" - exit 1 - fi - done -} +source ci.sh -# build dmd, druntime, phobos -build() { - source ~/dlang/*/activate # activate host compiler - make -j$N -C src -f posix.mak MODEL=$MODEL HOST_DMD=$DMD ENABLE_RELEASE=1 ENABLE_WARNINGS=1 all - make -j$N -C ../druntime -f posix.mak MODEL=$MODEL - make -j$N -C ../phobos -f posix.mak MODEL=$MODEL - deactivate # deactivate host compiler -} +################################################################################ +# Commands +################################################################################ -# self-compile dmd -rebuild() { - local build_path=generated/$TRAVIS_OS_NAME/release/$MODEL - local compare=${1:-0} - # `generated` gets cleaned in the next step, so we create another _generated - # The nested folder hierarchy is needed to conform to those specified in - # the generated dmd.conf - mkdir -p _${build_path} - cp $build_path/dmd _${build_path}/host_dmd - cp $build_path/dmd.conf _${build_path} - make -j$N -C src -f posix.mak MODEL=$MODEL HOST_DMD=../_${build_path}/host_dmd clean - make -j$N -C src -f posix.mak MODEL=$MODEL HOST_DMD=../_${build_path}/host_dmd ENABLE_RELEASE=1 ENABLE_WARNINGS=1 all - - # compare binaries to test reproducibile build - if [ $compare -eq 1 ]; then - if ! diff _${build_path}/host_dmd $build_path/dmd; then - $NM _${build_path}/host_dmd > a - $NM $build_path/dmd > b - diff -u a b - exit 1 - fi - fi -} - -# test druntime, phobos, dmd -test() { - test_dub_package - make -j$N -C ../druntime -f posix.mak MODEL=$MODEL unittest - make -j$N -C ../phobos -f posix.mak MODEL=$MODEL unittest - test_dmd -} - -# test dmd -test_dmd() { - # test fewer compiler argument permutations for PRs to reduce CI load - if [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_OS_NAME" == "linux" ]; then - make -j$N -C test MODEL=$MODEL # all ARGS by default - else - make -j$N -C test MODEL=$MODEL ARGS="-O -inline -release" - fi -} - -# test dub package -test_dub_package() { - source ~/dlang/*/activate # activate host compiler - # GDC's standard library is too old for some example scripts - if [ "${DMD:-dmd}" == "gdmd" ] ; then - echo "Skipping DUB examples on GDC." - else - pushd test/dub_package - for file in *.d ; do - dub --single "$file" - done - popd - fi - deactivate -} - -for proj in druntime phobos; do - if [ $TRAVIS_BRANCH != master ] && [ $TRAVIS_BRANCH != stable ] && - ! git ls-remote --exit-code --heads https://github.com/dlang/$proj.git $TRAVIS_BRANCH > /dev/null; then - # use master as fallback for other repos to test feature branches - clone https://github.com/dlang/$proj.git ../$proj master - else - clone https://github.com/dlang/$proj.git ../$proj $TRAVIS_BRANCH - fi -done - -date -for step in build test rebuild "rebuild 1" test_dmd; do - $step - date -done +setup_repos +testsuite