diff options
author | Anthony Green <green@moxielogic.com> | 2021-07-16 08:29:08 -0400 |
---|---|---|
committer | Anthony Green <green@moxielogic.com> | 2021-07-16 08:29:08 -0400 |
commit | d1eef904766dbd647de6c240a57dbc98d46e33dd (patch) | |
tree | 3fcf7268fb4536fed516bc82d30730ef7ba41328 | |
parent | f9ea41683444ebe11cfa45b05223899764df28fb (diff) | |
download | libffi-d1eef904766dbd647de6c240a57dbc98d46e33dd.tar.gz |
Migrate from travis-ci to github actions.
-rwxr-xr-x | .ci/ar-lib (renamed from .travis/ar-lib) | 0 | ||||
-rw-r--r-- | .ci/bfin-sim.exp (renamed from .travis/bfin-sim.exp) | 0 | ||||
-rwxr-xr-x | .ci/build-cross-in-container.sh | 18 | ||||
-rwxr-xr-x | .ci/build-in-container.sh (renamed from .travis/build-in-container.sh) | 10 | ||||
-rwxr-xr-x | .ci/build.sh (renamed from .travis/build.sh) | 9 | ||||
-rwxr-xr-x | .ci/compile (renamed from .travis/compile) | 0 | ||||
-rwxr-xr-x | .ci/install.sh (renamed from .travis/install.sh) | 6 | ||||
-rw-r--r-- | .ci/m32r-sim.exp (renamed from .travis/m32r-sim.exp) | 0 | ||||
-rw-r--r-- | .ci/moxie-sim.exp (renamed from .travis/moxie-sim.exp) | 0 | ||||
-rwxr-xr-x | .ci/msvs-detect | 1103 | ||||
-rw-r--r-- | .ci/or1k-sim.exp (renamed from .travis/or1k-sim.exp) | 0 | ||||
-rw-r--r-- | .ci/powerpc-eabisim.exp (renamed from .travis/powerpc-eabisim.exp) | 0 | ||||
-rw-r--r-- | .ci/site.exp (renamed from .travis/site.exp) | 8 | ||||
-rw-r--r-- | .ci/wine-sim.exp (renamed from .travis/wine-sim.exp) | 0 | ||||
-rw-r--r-- | .github/workflows/build.yml | 154 | ||||
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | .travis.yml | 83 | ||||
-rwxr-xr-x | .travis/build-cross-in-container.sh | 14 |
18 files changed, 1293 insertions, 114 deletions
diff --git a/.travis/ar-lib b/.ci/ar-lib index 0baa4f6..0baa4f6 100755 --- a/.travis/ar-lib +++ b/.ci/ar-lib diff --git a/.travis/bfin-sim.exp b/.ci/bfin-sim.exp index b36d9f0..b36d9f0 100644 --- a/.travis/bfin-sim.exp +++ b/.ci/bfin-sim.exp diff --git a/.ci/build-cross-in-container.sh b/.ci/build-cross-in-container.sh new file mode 100755 index 0000000..d2143e3 --- /dev/null +++ b/.ci/build-cross-in-container.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -x + +cd /opt + +echo $PATH +export PATH=/usr/local/bin:$PATH +echo $PATH + +export DEJAGNU=$(pwd)/.ci/site.exp +echo $DEJAGNU +ls -l $DEJAGNU +pwd +find . +./configure --host=${HOST} || cat */config.log +make +make dist +BOARDSDIR=$(pwd)/.ci make check RUNTESTFLAGS="-a $RUNTESTFLAGS" || true diff --git a/.travis/build-in-container.sh b/.ci/build-in-container.sh index 1a7fa76..a4124b0 100755 --- a/.travis/build-in-container.sh +++ b/.ci/build-in-container.sh @@ -1,12 +1,10 @@ #!/bin/bash - -cd /opt +set -x export QEMU_LD_PREFIX=/usr/${HOST} - +export DEJAGNU=/opt/.ci/site.exp +cd /opt ./configure ${HOST+--host=$HOST --disable-shared} make make dist -make check RUNTESTFLAGS="-a $RUNTESTFLAGS" || true - - +BOARDSDIR=/opt/.ci make check RUNTESTFLAGS="-a $RUNTESTFLAGS" || true diff --git a/.travis/build.sh b/.ci/build.sh index ebd063d..a638977 100755 --- a/.travis/build.sh +++ b/.ci/build.sh @@ -35,7 +35,8 @@ function build_linux() ./configure ${HOST+--host=$HOST} ${CONFIGURE_OPTIONS} || cat */config.log make make dist - make check RUNTESTFLAGS="-a $RUNTESTFLAGS" + DEJAGNU=$(pwd)/.ci/site.exp BOARDSDIR=$(pwd)/.ci runtest --version + DEJAGNU=$(pwd)/.ci/site.exp BOARDSDIR=$(pwd)/.ci make check RUNTESTFLAGS="-a $RUNTESTFLAGS" ./rlgl l --key=${RLGL_KEY} https://rl.gl ID=$(./rlgl start) @@ -45,7 +46,7 @@ function build_linux() function build_foreign_linux() { - ${DOCKER} run --rm -t -i -v $(pwd):/opt ${SET_QEMU_CPU} -e LIBFFI_TEST_OPTIMIZATION="${LIBFFI_TEST_OPTIMIZATION}" $2 bash -c /opt/.travis/build-in-container.sh + ${DOCKER} run --rm -t -v $(pwd):/opt ${SET_QEMU_CPU} -e LIBFFI_TEST_OPTIMIZATION="${LIBFFI_TEST_OPTIMIZATION}" $2 bash -c /opt/.ci/build-in-container.sh ./rlgl l --key=${RLGL_KEY} https://rl.gl ID=$(./rlgl start) @@ -55,7 +56,7 @@ function build_foreign_linux() function build_cross_linux() { - ${DOCKER} run --rm -t -i -v $(pwd):/opt ${SET_QEMU_CPU} -e HOST="${HOST}" -e CC="${HOST}-gcc-8 ${GCC_OPTIONS}" -e CXX="${HOST}-g++-8 ${GCC_OPTIONS}" -e LIBFFI_TEST_OPTIMIZATION="${LIBFFI_TEST_OPTIMIZATION}" quay.io/moxielogic/cross-ci-build-container:latest bash -c /opt/.travis/build-in-container.sh + ${DOCKER} run --rm -t -v $(pwd):/opt ${SET_QEMU_CPU} -e HOST="${HOST}" -e CC="${HOST}-gcc-8 ${GCC_OPTIONS}" -e CXX="${HOST}-g++-8 ${GCC_OPTIONS}" -e LIBFFI_TEST_OPTIMIZATION="${LIBFFI_TEST_OPTIMIZATION}" quay.io/moxielogic/cross-ci-build-container:latest bash -c /opt/.ci/build-in-container.sh ./rlgl l --key=${RLGL_KEY} https://rl.gl ID=$(./rlgl start) @@ -66,7 +67,7 @@ function build_cross_linux() function build_cross() { ${DOCKER} pull quay.io/moxielogic/libffi-ci-${HOST} - ${DOCKER} run --rm -t -i -v $(pwd):/opt -e HOST="${HOST}" -e CC="${HOST}-gcc ${GCC_OPTIONS}" -e CXX="${HOST}-g++ ${GCC_OPTIONS}" -e TRAVIS_BUILD_DIR=/opt -e DEJAGNU="${DEJAGNU}" -e RUNTESTFLAGS="${RUNTESTFLAGS}" -e LIBFFI_TEST_OPTIMIZATION="${LIBFFI_TEST_OPTIMIZATION}" quay.io/moxielogic/libffi-ci-${HOST} bash -c /opt/.travis/build-cross-in-container.sh + ${DOCKER} run --rm -t -v $(pwd):/opt -e HOST="${HOST}" -e CC="${HOST}-gcc ${GCC_OPTIONS}" -e CXX="${HOST}-g++ ${GCC_OPTIONS}" -e RUNNER_WORKSPACE=/opt -e RUNTESTFLAGS="${RUNTESTFLAGS}" -e LIBFFI_TEST_OPTIMIZATION="${LIBFFI_TEST_OPTIMIZATION}" quay.io/moxielogic/libffi-ci-${HOST} bash -c /opt/.ci/build-cross-in-container.sh ./rlgl l --key=${RLGL_KEY} https://rl.gl ID=$(./rlgl start) diff --git a/.travis/compile b/.ci/compile index 655932a..655932a 100755 --- a/.travis/compile +++ b/.ci/compile diff --git a/.travis/install.sh b/.ci/install.sh index 7e87235..d3fa0e9 100755 --- a/.travis/install.sh +++ b/.ci/install.sh @@ -1,7 +1,7 @@ #!/bin/bash set -x -if [[ $TRAVIS_OS_NAME != 'linux' ]]; then +if [[ $RUNNER_OS != 'Linux' ]]; then brew update --verbose # brew update > brew-update.log 2>&1 # fix an issue with libtool on travis by reinstalling it @@ -48,11 +48,11 @@ else sudo apt-get install gcc-multilib g++-multilib; ;; moxie-elf) - echo 'deb https://repos.moxielogic.org:7114/MoxieLogic moxiedev main' | sudo tee -a /etc/apt/sources.list + echo 'deb [trusted=yes] https://repos.moxielogic.org:7114/MoxieLogic moxiedev main' | sudo tee -a /etc/apt/sources.list sudo apt-get clean # clear the cache sudo apt-get update ## -qq sudo apt-get update - sudo apt-get install -y --allow-unauthenticated moxielogic-moxie-elf-gcc moxielogic-moxie-elf-gcc-c++ moxielogic-moxie-elf-gcc-libstdc++ moxielogic-moxie-elf-gdb-sim + sudo apt-get install -y --allow-unauthenticated moxielogic-moxie-elf-gcc moxielogic-moxie-elf-gcc-c++ moxielogic-moxie-elf-gcc-libstdc++ moxielogic-moxie-elf-gdb-sim texinfo sharutils texlive dejagnu ;; x86_64-w64-mingw32) sudo apt-get install gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 wine; diff --git a/.travis/m32r-sim.exp b/.ci/m32r-sim.exp index c18123f..c18123f 100644 --- a/.travis/m32r-sim.exp +++ b/.ci/m32r-sim.exp diff --git a/.travis/moxie-sim.exp b/.ci/moxie-sim.exp index 32979ea..32979ea 100644 --- a/.travis/moxie-sim.exp +++ b/.ci/moxie-sim.exp diff --git a/.ci/msvs-detect b/.ci/msvs-detect new file mode 100755 index 0000000..601575c --- /dev/null +++ b/.ci/msvs-detect @@ -0,0 +1,1103 @@ +#!/usr/bin/env bash +# ################################################################################################ # +# MetaStack Solutions Ltd. # +# ################################################################################################ # +# Microsoft C Compiler Environment Detection Script # +# ################################################################################################ # +# Copyright (c) 2016, 2017, 2018, 2019, 2020 MetaStack Solutions Ltd. # +# ################################################################################################ # +# Author: David Allsopp # +# 16-Feb-2016 # +# ################################################################################################ # +# Redistribution and use in source and binary forms, with or without modification, are permitted # +# provided that the following two conditions are met: # +# 1. Redistributions of source code must retain the above copyright notice, this list of # +# conditions and the following disclaimer. # +# 2. Neither the name of MetaStack Solutions Ltd. nor the names of its contributors may be # +# used to endorse or promote products derived from this software without specific prior # +# written permission. # +# # +# This software is provided by the Copyright Holder 'as is' and any express or implied warranties # +# including, but not limited to, the implied warranties of merchantability and fitness for a # +# particular purpose are disclaimed. In no event shall the Copyright Holder be liable for any # +# direct, indirect, incidental, special, exemplary, or consequential damages (including, but not # +# limited to, procurement of substitute goods or services; loss of use, data, or profits; or # +# business interruption) however caused and on any theory of liability, whether in contract, # +# strict liability, or tort (including negligence or otherwise) arising in any way out of the use # +# of this software, even if advised of the possibility of such damage. # +# ################################################################################################ # + +VERSION=0.4.1 + +# debug [level=2] message +debug () +{ + if [[ -z ${2+x} ]] ; then + DEBUG_LEVEL=2 + else + DEBUG_LEVEL=$1 + shift + fi + + if [[ $DEBUG -ge $DEBUG_LEVEL ]] ; then + echo "$1">&2 + fi +} + +# warning message +warning () +{ + if [[ $DEBUG -gt 0 ]] ; then + echo "Warning: $1">&2 + fi +} + +# reg_string key value +# Retrieves a REG_SZ value from the registry (redirected on WOW64) +reg_string () +{ + reg query "$1" /v "$2" 2>/dev/null | tr -d '\r' | sed -ne "s/ *$2 *REG_SZ *//p" +} + +# reg64_string key value +# As reg_string, but without WOW64 redirection (i.e. guaranteed access to 64-bit registry) +reg64_string () +{ + $REG64 query "$1" /v "$2" 2>/dev/null | tr -d '\r' | sed -ne "s/ *$2 *REG_SZ *//p" +} + +# find_in list file +# Increments $RET if file does not exist in any of the directories in the *-separated list +find_in () +{ + debug 4 "Looking for $2 in $1" + if [[ -z $1 ]] ; then + STATUS=1 + else + IFS=* + STATUS=1 + for f in $1; do + if [[ -e "$f/$2" ]] ; then + STATUS=0 + break + fi + done + unset IFS + fi + if [[ $STATUS -eq 1 ]] ; then + debug 4 "$2 not found" + fi + ((RET+=STATUS)) +} + +# check_environment PATH INC LIB name arch +# By checking for the presence of various files, verifies that PATH, INC and LIB provide a complete +# compiler and indicates this in its return status. RET is assumed to be zero on entry. $ASSEMBLER +# will contain the name of assembler for this compiler series (ml.exe or ml64.exe). +# The following files are checked: +# cl.exe PATH Microsoft C compiler +# kernel32.lib LIB Implies Windows SDK present +# link.exe PATH Microsoft Linker +# ml[64].exe PATH Microsoft Assembler (ml.exe or ml64.exe) +# msvcrt.lib LIB Implies C Runtime Libraries present +# mt.exe PATH Microsoft Manifest Tool +# oldnames.lib LIB Implies C Runtime Libraries present +# rc.exe PATH Microsoft Resource Compiler (implies tools present) +# stdlib.h INC Implies Microsoft C Runtime Libraries present +# windows.h INC Implies Windows SDK present +# oldnames.lib is included, because certain SDKs and older versions don't correctly install the +# entire runtime if only some options (e.g. Dynamic Runtime and not Static) are selected. +check_environment () +{ + debug 4 "Checking $4 ($5)" + for tool in cl rc link ; do + find_in "$1" $tool.exe + done + + if [[ $RET -gt 0 ]] ; then + warning "Microsoft C Compiler tools not all found - $4 ($5) excluded" + return 1 + fi + + RET=0 + find_in "$2" windows.h + find_in "$3" kernel32.lib + if [[ $RET -gt 0 ]] ; then + warning "Windows SDK not all found - $4 ($5) excluded" + return 1 + fi + + RET=0 + find_in "$2" stdlib.h + find_in "$3" msvcrt.lib + find_in "$3" oldnames.lib + if [[ $RET -gt 0 ]] ; then + warning "Microsoft C runtime library not all found - $4 ($5) excluded" + return 1 + fi + + ASSEMBLER=ml${5#x} + ASSEMBLER=${ASSEMBLER%86}.exe + if [[ $ML_REQUIRED -eq 1 ]] ; then + RET=0 + find_in "$1" $ASSEMBLER + if [[ $RET -gt 0 ]] ; then + warning "Microsoft Assembler ($ASSEMBLER) not found - $4 ($5)" + return 1 + fi + fi + + if [[ $MT_REQUIRED -eq 1 ]] ; then + RET=0 + find_in "$1" mt.exe + if [[ $RET -gt 0 ]] ; then + warning "Microsoft Manifest Tool not found - $4 ($5)" + return 1 + fi + fi + + return 0 +} + +# output VAR value arch +# Outputs a command for setting VAR to value based on $OUTPUT. If $ENV_ARCH is arch, then an empty +# value (i.e. no change) is output. +output () +{ + if [[ $3 = $ENV_ARCH ]] ; then + VALUE= + else + VALUE=$2 + fi + case "$OUTPUT" in + 0) + echo "$1='${VALUE//\'/\'\"\'\"\'}'";; + 1) + VALUE=${VALUE//#/\\\#} + echo "$1=${VALUE//\$/\$\$}";; + esac +} + +# DEBUG Debugging level +# MODE Operation mode +# 0 - Normal +# 1 - --all +# 2 - --help +# 3 - --version +# OUTPUT --output option +# 0 - =shell +# 1 - =make +# MT_REQUIRED --with-mt +# ML_REQUIRED --with-assembler +# TARGET_ARCH Normalised --arch (x86, x64 or blank for both) +# LEFT_ARCH \ If $TARGET_ARCH is blank, these will be x86 and x64 respectively, otherwise they +# RIGHT_ARCH / equal $TARGET_ARCH +# SCAN_ENV Controls from parsing whether the environment should be queried for a compiler +DEBUG=0 +MODE=0 +OUTPUT=0 +MT_REQUIRED=0 +ML_REQUIRED=0 +TARGET_ARCH= +SCAN_ENV=0 + +# Various PATH messing around means it's sensible to know where tools are now +WHICH=$(which which) + +if [[ $(uname --operating-system 2>/dev/null) = "Msys" ]] ; then + # Prevent MSYS from translating command line switches to paths + SWITCH_PREFIX='//' +else + SWITCH_PREFIX='/' +fi + +# Parse command-line. At the moment, the short option which usefully combines with anything is -d, +# so for the time being, combining short options is not permitted, as the loop becomes even less +# clear with getopts. GNU getopt isn't installed by default on Cygwin... +if [[ $@ != "" ]] ; then + while true ; do + case "$1" in + # Mode settings ($MODE) + -a|--all) + MODE=1 + shift 1;; + -h|--help) + MODE=2 + shift;; + -v|--version) + MODE=3 + shift;; + + # Simple flags ($MT_REQUIRED and $ML_REQUIRED) + --with-mt) + MT_REQUIRED=1 + shift;; + --with-assembler) + ML_REQUIRED=1 + shift;; + + # -o, --output ($OUTPUT) + -o|--output) + case "$2" in + shell) + ;; + make) + OUTPUT=1;; + *) + echo "$0: unrecognised option for $1: '$2'">&2 + exit 2;; + esac + shift 2;; + -oshell|--output=shell) + shift;; + -omake|--output=make) + OUTPUT=1 + shift;; + -o*) + echo "$0: unrecognised option for -o: '${1#-o}'">&2 + exit 2;; + --output=*) + echo "$0: unrecognised option for --output: '${1#--output=}'">&2 + exit 2;; + + # -x, --arch ($TARGET_ARCH) + -x|--arch) + case "$2" in + 86|x86) + TARGET_ARCH=x86;; + 64|x64) + TARGET_ARCH=x64;; + *) + echo "$0: unrecognised option for $1: '$2'">&2 + exit 2 + esac + shift 2;; + -x86|-xx86|--arch=x86|--arch=86) + TARGET_ARCH=x86 + shift;; + -x64|-xx64|--arch=x64|--arch=64) + TARGET_ARCH=x64 + shift;; + -x*) + echo "$0: unrecognised option for -x: '${1#-x}'">&2 + exit 2;; + --arch=*) + echo "$0: unrecognised option for --arch: '${1#--arch}'">&2 + exit 2;; + + # -d, --debug ($DEBUG) + -d*) + DEBUG=${1#-d} + if [[ -z $DEBUG ]] ; then + DEBUG=1 + fi + shift;; + --debug=*) + DEBUG=${1#*=} + shift;; + --debug) + DEBUG=1 + shift;; + + # End of option marker + --) + shift + break;; + + # Invalid options + --*) + echo "$0: unrecognised option: '${1%%=*}'">&2 + exit 2;; + -*) + echo "$0: unrecognised option: '${1:1:1}'">&2 + exit 2;; + + # MSVS_PREFERENCE (without end-of-option marker) + *) + break;; + esac + done + + if [[ -n ${1+x} ]] ; then + if [[ $MODE -eq 1 ]] ; then + echo "$0: cannot specify MSVS_PREFERENCE and --all">&2 + exit 2 + else + MSVS_PREFERENCE="$@" + fi + fi +fi + +# Options sanitising +if [[ $MODE -eq 1 ]] ; then + if [[ -n $TARGET_ARCH ]] ; then + echo "$0: --all and --arch are mutually exclusive">&2 + exit 2 + fi + MSVS_PREFERENCE= + SCAN_ENV=1 +elif [[ -z ${MSVS_PREFERENCE+x} ]] ; then + MSVS_PREFERENCE='@;VS16.*;VS15.*;VS14.0;VS12.0;VS11.0;10.0;9.0;8.0;7.1;7.0' +fi + +MSVS_PREFERENCE=${MSVS_PREFERENCE//;/ } + +if [[ -z $TARGET_ARCH ]] ; then + LEFT_ARCH=x86 + RIGHT_ARCH=x64 +else + LEFT_ARCH=$TARGET_ARCH + RIGHT_ARCH=$TARGET_ARCH +fi + +# Command line parsing complete (MSVS_PREFERENCE pending) + +NAME="Microsoft C Compiler Environment Detection Script" +case $MODE in + 2) + echo "$NAME" + echo "Queries the environment and registry to locate Visual Studio / Windows SDK" + echo "installations and uses their initialisation scripts (SetEnv.cmd, vcvarsall.bat," + echo "etc.) to determine INCLUDE, LIB and PATH alterations." + echo + echo "Usage:" + echo " $0 [OPTIONS] [--] [MSVS_PREFERENCE]" + echo + echo "Options:" + echo " -a, --all Display all available compiler packages" + echo " -x, --arch=ARCH Only consider packages for ARCH (x86 or x64). Default is" + echo " to return packages containing both architectures" + echo " -d, --debug[=LEVEL] Set debug messages level" + echo " -h, --help Display this help screen" + echo " -o, --output=OUTPUT Set final output. Default is shell. Valid values:" + echo " shell - shell assignments, for use with eval" + echo " make - make assignments, for inclusion in a Makefile" + echo " -v, --version Display the version" + echo " --with-mt Only consider packages including the Manifest Tool" + echo " --with-assembler Only consider packages including an assembler" + echo + echo "If MSVS_PREFERENCE is not given, then the environment variable MSVS_PREFERENCE" + echo "is read. MSVS_PREFERENCE is a semicolon separated list of preferred versions." + echo "Three kinds of version notation are supported:" + echo " 1. @ - which refers to the C compiler found in PATH (if it can be identified)" + echo " (this allows the C compiler corresponding to the opposite architecture to" + echo " be selected, if possible)." + echo " 2. mm.n - which refers to a Visual Studio version (e.g. 14.0, 7.1) but which" + echo " also allows an SDK to provide the compiler (e.g. Windows SDK 7.1 provides" + echo " 10.0). Visual Studio packages are always preferred ahead of SDKs." + echo " 3. SPEC - an actual package specification. Visual Studio packages are VSmm.n" + echo " (e.g. VS14.0, VS7.1) and SDK packages are SDKm.n (e.g. SDK7.1)." + echo " Any Visual Studio 2017 update can be selected with VS15.*" + echo "The default behaviour is to match the environment compiler followed by the most" + echo "recent version of the compiler." + exit 0;; + 3) + echo "$NAME" + echo "Version $VERSION" + exit 0;; +esac + +# Known compiler packages. Visual Studio .NET 2002 onwards. Detection is in place for Visual Studio +# 2005 Express, but because it doesn't include a Windows SDK, it can only ever be detected if the +# script has been launched from within a Platform SDK command prompt (this provides the Windows +# Headers and Libraries which allows this script to detect the rest). +# Each element is either a Visual Studio or SDK package and the value is the syntax for a bash +# associative array to be eval'd. Each of these contains the following properties: +# NAME - the friendly name of the package +# ENV - (VS only) the version-specific portion of the VSCOMNTOOLS environment variable +# VERSION - (VS only) version number of the package +# ARCH - Lists the architectures available in this version +# ARCH_SWITCHES - The script is assumed to accept x86 and x64 to indicate architecture. This key +# contains another eval'd associative array allowing alternate values to be given +# SETENV_RELEASE - (SDK only) script switch necessary to select release than debugging versions +# EXPRESS - (VS only) the prefix to the registry key to detect the Express edition +# EXPRESS_ARCH - (VS only) overrides ARCH if Express edition is detected +# EXPRESS_ARCH_SWITCHES - (VS only) overrides ARCH_SWITCHES if Express edition is detected +# VC_VER - (SDK only) specifies the version of the C Compilers included in the SDK (SDK +# equivalent of the VERSION key) +# REG_KEY - (SDK only) registry key to open to identify this package installation +# REG_VALUE - (SDK only) registry value to query to identify this package installation +# VSWHERE - (VS 2017+) is 1 if the compiler can only be detected using vswhere +# For a while, Windows SDKs followed a standard pattern which is stored in the SDK element and +# copied to the appropriate version. SDKs after 7.1 do not include compilers, and so are not +# captured (as of Visual Studio 2015, the Windows SDK is official part of Visual Studio). +declare -A COMPILERS +SDK52_KEY='HKLM\SOFTWARE\Microsoft\MicrosoftSDK\InstalledSDKs\8F9E5EF3-A9A5-491B-A889-C58EFFECE8B3' +COMPILERS=( + ["VS7.0"]='( + ["NAME"]="Visual Studio .NET 2002" + ["ENV"]="" + ["VERSION"]="7.0" + ["ARCH"]="x86")' + ["VS7.1"]='( + ["NAME"]="Visual Studio .NET 2003" + ["ENV"]="71" + ["VERSION"]="7.1" + ["ARCH"]="x86")' + ["VS8.0"]='( + ["NAME"]="Visual Studio 2005" + ["ENV"]="80" + ["VERSION"]="8.0" + ["EXPRESS"]="VC" + ["ARCH"]="x86 x64" + ["EXPRESS_ARCH"]="x86")' + ["VS9.0"]='( + ["NAME"]="Visual Studio 2008" + ["ENV"]="90" + ["VERSION"]="9.0" + ["EXPRESS"]="VC" + ["ARCH"]="x86 x64" + ["EXPRESS_ARCH"]="x86")' + ["VS10.0"]='( + ["NAME"]="Visual Studio 2010" + ["ENV"]="100" + ["VERSION"]="10.0" + ["EXPRESS"]="VC" + ["ARCH"]="x86 x64" + ["EXPRESS_ARCH"]="x86")' + ["VS11.0"]='( + ["NAME"]="Visual Studio 2012" + ["ENV"]="110" + ["VERSION"]="11.0" + ["EXPRESS"]="WD" + ["ARCH"]="x86 x64" + ["EXPRESS_ARCH_SWITCHES"]="([\"x64\"]=\"x86_amd64\")")' + ["VS12.0"]='( + ["NAME"]="Visual Studio 2013" + ["ENV"]="120" + ["VERSION"]="12.0" + ["EXPRESS"]="WD" + ["ARCH"]="x86 x64" + ["EXPRESS_ARCH_SWITCHES"]="([\"x64\"]=\"x86_amd64\")")' + ["VS14.0"]='( + ["NAME"]="Visual Studio 2015" + ["ENV"]="140" + ["VERSION"]="14.0" + ["ARCH"]="x86 x64")' + ["VS15.*"]='( + ["NAME"]="Visual Studio 2017" + ["VSWHERE"]="1")' + ["VS16.*"]='( + ["NAME"]="Visual Studio 2019" + ["VSWHERE"]="1")' + ["SDK5.2"]='( + ["NAME"]="Windows Server 2003 SP1 SDK" + ["VC_VER"]="8.0" + ["REG_KEY"]="$SDK52_KEY" + ["REG_VALUE"]="Install Dir" + ["SETENV_RELEASE"]="/RETAIL" + ["ARCH"]="x64" + ["ARCH_SWITCHES"]="([\"x64\"]=\"/X64\")")' + ["SDK"]='( + ["NAME"]="Generalised Windows SDK" + ["SETENV_RELEASE"]="/Release" + ["ARCH"]="x86 x64" + ["ARCH_SWITCHES"]="([\"x86\"]=\"/x86\" [\"x64\"]=\"/x64\")")' + ["SDK6.1"]='( + ["NAME"]="Windows Server 2008 with .NET 3.5 SDK" + ["VC_VER"]="9.0")' + ["SDK7.0"]='( + ["NAME"]="Windows 7 with .NET 3.5 SP1 SDK" + ["VC_VER"]="9.0")' + ["SDK7.1"]='( + ["NAME"]="Windows 7 with .NET 4 SDK" + ["VC_VER"]="10.0")' +) + +# FOUND is ultimately an associative array containing installed compiler packages. It's +# hijacked here as part of MSVS_PREFERENCE validation. +# Ultimately, it contains a copy of the value from COMPILERS with the following extra keys: +# IS_EXPRESS - (VS only) indicates whether the Express edition was located +# SETENV - (SDK only) the full location of the SetEnv.cmd script +# ASSEMBLER - the name of the assembler (ml or ml64) +# MSVS_PATH \ +# MSVS_INC > prefix values for PATH, INCLUDE and LIB determined by running the scripts. +# MSVS_LIB / +declare -A FOUND + +# Check that MSVS_PREFERENCE is valid and contains no repetitions. +for v in $MSVS_PREFERENCE ; do + if [[ -n ${FOUND[$v]+x} ]] ; then + echo "$0: corrupt MSVS_PREFERENCE: repeated '$v'">&2 + exit 2 + fi + if [[ $v != "@" ]] ; then + if [[ -z ${COMPILERS[$v]+x} && -z ${COMPILERS["VS$v"]+x} && -z ${COMPILERS[${v%.*}.*]+x} ]] ; then + echo "$0: corrupt MSVS_PREFERENCE: unknown compiler '$v'">&2 + exit 2 + fi + else + SCAN_ENV=1 + fi + FOUND["$v"]="" +done + +# Reset FOUND for later use. +FOUND=() + +# Scan the environment for a C compiler, and check that it's valid. Throughout the rest of the +# script, it is assumed that if ENV_ARCH is set then there is a valid environment compiler. +if [[ $SCAN_ENV -eq 1 ]] ; then + if "$WHICH" cl >/dev/null 2>&1 ; then + # Determine its architecture from the Microsoft Logo line. + ENV_ARCH=$(cl 2>&1 | head -1 | tr -d '\r') + case "${ENV_ARCH#* for }" in + x64|AMD64) + ENV_ARCH=x64;; + 80x86|x86) + ENV_ARCH=x86;; + *) + echo "Unable to identify C compiler architecture from '${ENV_ARCH#* for }'">&2 + echo "Environment C compiler discarded">&2 + unset ENV_ARCH;; + esac + + # Environment variable names are a bit of a nightmare on Windows - they are actually case + # sensitive (at the kernel level) but not at the user level! To compound the misery is that SDKs + # use Include and Lib where vcvars32 tends to use INCLUDE and LIB. Windows versions also contain + # a mix of Path and PATH, but fortunately Cygwin normalises that to PATH for us! For this + # reason, use env to determine the actual case of the LIB and INCLUDE variables. + if [[ -n ${ENV_ARCH+x} ]] ; then + RET=0 + ENV_INC=$(env | sed -ne 's/^\(INCLUDE\)=.*/\1/pi') + ENV_LIB=$(env | sed -ne 's/^\(LIB\)=.*/\1/pi') + if [[ -z $ENV_INC || -z $ENV_LIB ]] ; then + warning "Microsoft C Compiler Include and/or Lib not set - Environment C compiler ($ENV_ARCH) excluded" + unset ENV_ARCH + else + if check_environment "${PATH//:/*}" \ + "${!ENV_INC//;/*}" \ + "${!ENV_LIB//;/*}" \ + "Environment C compiler" \ + "$ENV_ARCH" ; then + ENV_CL=$("$WHICH" cl) + ENV_cl=${ENV_CL,,} + ENV_cl=${ENV_cl/bin\/*_/bin\/} + debug "Environment appears to include a compiler at $ENV_CL" + if [[ -n $TARGET_ARCH && $TARGET_ARCH != $ENV_ARCH ]] ; then + debug "But architecture doesn't match required value" + unset ENV_ARCH + fi + else + unset ENV_ARCH + fi + fi + fi + fi +fi + +# Even if launched from a 64-bit Command Prompt, Cygwin is usually 32-bit and so the scripts +# executed will inherit that fact. This is a problem when querying the registry, but fortunately +# WOW64 provides a mechanism to break out of the 32-bit environment by mapping $WINDIR/sysnative to +# the real 64-bit programs. +# Thus: +# MS_ROOT is the 32-bit Microsoft Registry key (all Visual Studio keys are located there) +# REG64 is the processor native version of the reg utility (allowing 64-bit keys to be read for +# the SDKs) +if [[ -n ${PROCESSOR_ARCHITEW6432+x} ]] ; then + debug "WOW64 detected" + MS_ROOT='HKLM\SOFTWARE\Microsoft' + REG64=$WINDIR/sysnative/reg +else + MS_ROOT='HKLM\SOFTWARE\Wow6432Node\Microsoft' + REG64=reg +fi + +# COMPILER contains each eval'd element from COMPILERS +declare -A COMPILER + +# Scan the registry for compiler package (vswhere is later) +for i in "${!COMPILERS[@]}" ; do + eval COMPILER=${COMPILERS[$i]} + + if [[ -n ${COMPILER["ENV"]+x} ]] ; then + # Visual Studio package - test for its environment variable + ENV=VS${COMPILER["ENV"]}COMNTOOLS + if [[ -n ${!ENV+x} ]] ; then + debug "$ENV is a candidate" + TEST_PATH=${!ENV%\"} + TEST_PATH=$(cygpath -u -f - <<< ${TEST_PATH#\"}) + if [[ -e $TEST_PATH/vsvars32.bat ]] ; then + debug "Directory pointed to by $ENV contains vsvars32.bat" + EXPRESS=0 + # Check for the primary Visual Studio registry value indicating installation + INSTALL_DIR=$(reg_string "$MS_ROOT\\VisualStudio\\${COMPILER["VERSION"]}" InstallDir) + if [[ -z $INSTALL_DIR ]] ; then + if [[ -n ${COMPILER["EXPRESS"]+x} ]] ; then + TEST_KEY="$MS_ROOT\\${COMPILER["EXPRESS"]}Express\\${COMPILER["VERSION"]}" + INSTALL_DIR=$(reg_string "$TEST_KEY" InstallDir) + # Exception for Visual Studio 2005 Express, which doesn't set the registry correctly, so + # set INSTALL_DIR to a fake value to pass the next test. + if [[ ${COMPILER["VERSION"]} = "8.0" ]] ; then + INSTALL_DIR=$(cygpath -w "$TEST_PATH") + EXPRESS=1 + else + if [[ -z $INSTALL_DIR ]] ; then + warning "vsvars32.bat found, but registry value not located (Exp or Pro)" + else + EXPRESS=1 + fi + fi + else + warning "vsvars32.bat found, but registry value not located" + fi + fi + + if [[ -n $INSTALL_DIR ]] ; then + if [[ ${TEST_PATH%/} = $(cygpath -u "$INSTALL_DIR\\..\\Tools") ]] ; then + RESULT=${COMPILERS[$i]%)} + DISPLAY=${COMPILER["NAME"]} + if [[ $EXPRESS -eq 1 ]] ; then + DISPLAY="$DISPLAY Express" + fi + FOUND+=(["$i"]="$RESULT [\"DISPLAY\"]=\"$DISPLAY\" [\"IS_EXPRESS\"]=\"$EXPRESS\")") + debug "${COMPILER["NAME"]} accepted for further detection" + else + warning "$ENV doesn't agree with registry" + fi + else + warning "vsvars32.bat found, but registry settings not found" + fi + else + warning "$ENV set, but vsvars32.bat not found" + fi + fi + elif [[ -n ${COMPILER["REG_KEY"]+x} ]] ; then + # SDK with explicit registry detection value + INSTALL_DIR=$(reg64_string "${COMPILER["REG_KEY"]}" "${COMPILER["REG_VALUE"]}") + if [[ -n $INSTALL_DIR ]] ; then + TEST_PATH=$(cygpath -u "$INSTALL_DIR") + if [[ -e $TEST_PATH/SetEnv.cmd ]] ; then + RESULT=${COMPILERS[$i]%)} + FOUND+=(["$i"]="$RESULT [\"DISPLAY\"]=\"${COMPILER["NAME"]}\" [\"SETENV\"]=\"$INSTALL_DIR\\SetEnv.cmd\")") + debug "${COMPILER["NAME"]} accepted for further detection" + else + warning "Registry set for Windows Server 2003 SDK, but SetEnv.cmd not found" + fi + fi + fi +done + +# Now enumerate installed SDKs for v6.0+ +SDK_ROOT='HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows' +for i in $(reg query "$SDK_ROOT" 2>/dev/null | tr -d '\r' | sed -ne '/Windows\\v/s/.*\\//p') ; do + debug "Analysing SDK key $SDK_ROOT\\$i" + INSTALL_DIR=$(reg_string "$SDK_ROOT\\$i" InstallationFolder) + if [[ -n $INSTALL_DIR ]] ; then + TEST_PATH=$(cygpath -u "$INSTALL_DIR") + if [[ -e $TEST_PATH/Bin/SetEnv.cmd ]] ; then + if [[ -z ${COMPILERS["SDK${i#v}"]+x} ]] ; then + warning "SDK $i is not known to this script - assuming compatibility" + DISPLAY="Windows SDK $i" + else + eval COMPILER=${COMPILERS["SDK${i#v}"]} + DISPLAY=${COMPILER['NAME']} + fi + RESULT=${COMPILERS['SDK']%)} + FOUND+=(["SDK${i/v/}"]="$RESULT [\"DISPLAY\"]=\"$DISPLAY\" [\"SETENV\"]=\"$INSTALL_DIR\\Bin\\SetEnv.cmd\")") + else + if [[ -n ${COMPILERS["SDK${i#v}"]+x} ]] ; then + warning "Registry set for Windows SDK $i, but SetEnv.cmd not found" + fi + fi + else + warning "Registry key for Windows SDK $i doesn't contain expected InstallationFolder value" + fi +done + +# Now enumerate Visual Studio 2017+ instances +VSWHERE=$(dirname $(realpath $0))/vswhere.exe +if [[ ! -x $VSWHERE ]] ; then + VSWHERE="$(printenv 'ProgramFiles(x86)')\\Microsoft Visual Studio\\Installer\\vswhere.exe" + VSWHERE=$(echo $VSWHERE| cygpath -f -) +fi +if [[ -x $VSWHERE ]] ; then + debug "$VSWHERE found" + while IFS= read -r line; do + case ${line%: *} in + instanceId) + INSTANCE=${line#*: };; + installationPath) + INSTANCE_PATH=${line#*: };; + installationVersion) + INSTANCE_VER=${line#*: } + INSTANCE_VER=${INSTANCE_VER%.*} + INSTANCE_VER=${INSTANCE_VER%.*};; + displayName) + INSTANCE_NAME=${line#*: } + debug "Looking at $INSTANCE in $INSTANCE_PATH ($INSTANCE_VER $INSTANCE_NAME)" + if [[ -e "$(echo $INSTANCE_PATH| cygpath -f -)/VC/Auxiliary/Build/vcvarsall.bat" ]] ; then + debug "vcvarsall.bat found" + FOUND+=(["VS$INSTANCE_VER"]="([\"DISPLAY\"]=\"$INSTANCE_NAME\" [\"ARCH\"]=\"x86 x64\" [\"SETENV\"]=\"$INSTANCE_PATH\\VC\\Auxiliary\\Build\\vcvarsall.bat\" [\"SETENV_RELEASE\"]=\"\")") + else + warning "vcvarsall.bat not found for $INSTANCE" + fi;; + esac + done < <("$VSWHERE" -all -nologo | tr -d '\r') +fi + +if [[ $DEBUG -gt 1 ]] ; then + for i in "${!FOUND[@]}" ; do + echo "Inspect $i">&2 + done +fi + +# Basic scanning is complete, now interrogate the packages which seem to be installed and ensure +# that they pass the check_environment tests. + +# CANDIDATES is a hash table of the keys of FOUND. The result of the next piece of processing is to +# derive two arrays PREFERENCE and TEST. TEST will contain a list of the keys of FOUND in the order +# in which they should be evaluated. PREFERENCE contains a parsed version of MSVS_PREFERENCE but +# filtered on the basis of the compiler packages already identified. The current "hoped for" +# preference is stored in $pref (the index into PREFERENCE) and $PREF (which is +# ${PREFERENCE[$pref]}). These two arrays together allow testing to complete quickly if the desired +# version is found (note that often this won't be possible as the @ environment option requires all +# packages to be tested in order to be sure that the environment compiler is not ambiguous). +declare -A CANDIDATES +for i in "${!FOUND[@]}" ; do + CANDIDATES[$i]=""; +done + +# For --all, act as though MSVS_PREFERENCE were "@" because this causes all packages to be tested. +if [[ $MODE -eq 1 ]] ; then + PREFER_ENV=1 + PREFERENCE=("@") +else + PREFER_ENV=0 + PREFERENCE=() +fi + +TEST=() +for i in $MSVS_PREFERENCE ; do + if [[ $i = "@" ]] ; then + if [[ -n ${ENV_ARCH+x} ]] ; then + PREFERENCE+=("@") + PREFER_ENV=1 + else + debug "Preference @ ignored since no environment compiler selected" + fi + else + if [[ -n ${COMPILERS[$i]+x} || -n ${COMPILERS[${i%.*}.*]+x} ]] ; then + if [[ -n ${CANDIDATES[$i]+x} ]] ; then + unset CANDIDATES[$i] + TEST+=($i) + PREFERENCE+=($i) + elif [[ ${i#*.} = "*" ]] ; then + INSTANCES= + for j in "${!CANDIDATES[@]}" ; do + if [[ "${j%.*}.*" = $i ]] ; then + unset CANDIDATES[$j] + INSTANCES="$INSTANCES $j" + fi + done + INSTANCES="$(sort -r <<< "${INSTANCES// /$'\n'}")" + eval TEST+=($INSTANCES) + eval PREFERENCE+=($INSTANCES) + fi + else + if [[ -n ${CANDIDATES["VS$i"]+x} ]] ; then + unset CANDIDATES["VS$i"] + TEST+=("VS$i") + PREFERENCE+=("VS$i") + fi + SDKS= + for j in "${!COMPILERS[@]}" ; do + eval COMPILER=${COMPILERS[$j]} + if [[ -n ${COMPILER["VC_VER"]+x} ]] ; then + if [[ $i = ${COMPILER["VC_VER"]} && -n ${CANDIDATES[$j]+x} ]] ; then + unset CANDIDATES[$j] + SDKS="$j $SDKS" + fi + fi + done + SDKS=${SDKS% } + SDKS="$(sort -r <<< "${SDKS// /$'\n'}")" + SDKS=${SDKS//$'\n'/ } + eval TEST+=($SDKS) + eval PREFERENCE+=($SDKS) + fi + fi +done + +# If MSVS_PREFERENCE includes @, add any remaining items from CANDIDATES to TEST, otherwise remove +# them from FOUND so that they don't accidentally get reported on later. +for i in "${!CANDIDATES[@]}" ; do + if [[ $PREFER_ENV -eq 1 ]] ; then + TEST+=($i) + else + unset FOUND[$i] + fi +done + +# Initialise pref and PREF to ${PREFERENCE[0]} +pref=0 +PREF=${PREFERENCE[0]} + +if [[ $DEBUG -gt 1 ]] ; then + for i in "${!TEST[@]}" ; do + echo "Test ${TEST[$i]}">&2 + done +fi + + +# Now run each compiler's environment script and then test whether it is suitable. During this loop, +# attempt to identify the environment C compiler (if one was found). The environment C compiler is +# strongly identified if the full location of cl matches the one in PATH and both LIB and INCLUDE +# contain the strings returned by the script in an otherwise empty environment (if one or both of +# the LIB and INCLUDE variables do not contain the string returned, then the compiler is weakly +# identified). If the environment compiler is strongly identified by more than one package, then it +# is not identified at all; if it is strongly identified by no packages but weakly identified by +# exactly 1, then we grudgingly accept that that's probably the one. +ENV_COMPILER= +WEAK_ENV= + +# ARCHINFO contains the appropriate ARCH_SWITCHES associative array for each compiler. +declare -A ARCHINFO + +for i in "${TEST[@]}" ; do + CURRENT=${FOUND[$i]} + eval COMPILER=$CURRENT + # At the end of this process, the keys of FOUND will be augmented with the architecture found in + # each case (so if "VS14.0" was in FOUND from the scan and both the x86 and x64 compilers are + # valid, then at the end of this loop FOUND will contain "VS14.0-x86" and "VS14.0-x64"). + unset FOUND[$i] + + if [[ ${COMPILER["IS_EXPRESS"]}0 -gt 0 && -n ${COMPILER["EXPRESS_ARCH_SWITCHES"]+x} ]] ; then + eval ARCHINFO=${COMPILER["EXPRESS_ARCH_SWITCHES"]} + elif [[ -n ${COMPILER["ARCH_SWITCHES"]+x} ]] ; then + eval ARCHINFO=${COMPILER["ARCH_SWITCHES"]} + else + ARCHINFO=() + fi + + # Determine the script to be executed and any non-architecture specific switches needed. + # $ENV is will contain the value of the environment variable for the compiler (empty for an SDK) + # which is required for Visual Studio 7.x shim later. + if [[ -n ${COMPILER["ENV"]+x} ]] ; then + ENV=VS${COMPILER["ENV"]}COMNTOOLS + ENV=${!ENV%\"} + ENV=${ENV#\"} + if [[ ${COMPILER["ENV"]}0 -ge 800 ]] ; then + SCRIPT="$(cygpath -d -f - <<< $ENV)\\..\\..\\VC\\vcvarsall.bat" + SCRIPT_SWITCHES= + else + SCRIPT="$(cygpath -d -f - <<< $ENV)\\vsvars32.bat" + SCRIPT_SWITCHES= + fi + else + ENV= + SCRIPT=${COMPILER["SETENV"]} + SCRIPT_SWITCHES=${COMPILER["SETENV_RELEASE"]} + fi + # For reasons of escaping, the script is executed using its basename so the directory needs + # prepending to PATH. + DIR=$(dirname "$SCRIPT" | cygpath -u -f -) + + if [[ ${COMPILER["IS_EXPRESS"]} -gt 0 && -n ${COMPILER["EXPRESS_ARCH"]+x} ]] ; then + ARCHS=${COMPILER["EXPRESS_ARCH"]} + else + ARCHS=${COMPILER["ARCH"]} + fi + + for arch in $ARCHS ; do + # Determine the command line switch for this architecture + if [[ -n ${ARCHINFO[$arch]+x} ]] ; then + ARCH_SWITCHES=${ARCHINFO[$arch]} + else + ARCH_SWITCHES=$arch + fi + + # Run the script in order to determine changes made to PATH, INCLUDE and LIB. These scripts + # always prepend changes to the environment variables. + MSVS_PATH= + MSVS_LIB= + MSVS_INC= + + COMMAND='%EXEC_SCRIPT% && echo XMARKER && echo !PATH! && echo !LIB! && echo !INCLUDE!' + + # Note that EXEC_SCRIPT must have ARCH_SWITCHES first for older Platform SDKs (newer ones parse + # arguments properly) + if [[ $DEBUG -gt 3 ]] ; then + printf "Scanning %s... " "$(basename "$SCRIPT") $ARCH_SWITCHES $SCRIPT_SWITCHES">&2 + fi + num=0 + while IFS= read -r line; do + case $num in + 0) + MSVS_PATH=${line%% };; + 1) + MSVS_LIB=${line%% };; + 2) + MSVS_INC=${line%% };; + esac + ((num++)) + done < <(INCLUDE='' LIB='' PATH="?msvs-detect?:$DIR:$PATH" ORIGINALPATH='' \ + EXEC_SCRIPT="$(basename "$SCRIPT") $ARCH_SWITCHES $SCRIPT_SWITCHES" \ + $(cygpath "$COMSPEC") ${SWITCH_PREFIX}v:on ${SWITCH_PREFIX}c $COMMAND 2>/dev/null | grep -F XMARKER -A 3 | tr -d '\015' | tail -3) + if [[ $DEBUG -gt 3 ]] ; then + echo done>&2 + fi + + if [[ -n $MSVS_PATH ]] ; then + # Translate MSVS_PATH back to Cygwin notation (/cygdrive, etc. and colon-separated) + MSVS_PATH=$(cygpath "$MSVS_PATH" -p) + # Remove any trailing / from elements of MSVS_PATH + MSVS_PATH=$(echo "$MSVS_PATH" | sed -e 's|\([^:]\)/\+\(:\|$\)|\1\2|g;s/?msvs-detect?.*//') + # Guarantee that MSVS_PATH ends with a single : + MSVS_PATH="${MSVS_PATH%%:}:" + fi + # Ensure that both variables end with a semi-colon (it doesn't matter if for some erroneous + # reason they have come back blank, because check_environment will shortly fail) + MSVS_LIB="${MSVS_LIB%%;};" + MSVS_INC="${MSVS_INC%%;};" + + # Visual Studio .NET 2002 and 2003 do not include mt in PATH, for not entirely clear reasons. + # This shim detects that scenario and adds the winnt folder to MSVS_PATH. + RET=0 + if [[ ${i/.*/} = "VS7" ]] ; then + find_in "${MSVS_PATH//:/*}" mt.exe + if [[ $RET -eq 1 ]] ; then + MSVS_PATH="$MSVS_PATH$(cygpath -u -f - <<< $ENV\\Bin\\winnt):" + RET=0 + fi + fi + + # Ensure that these derived values give a valid compiler. + if check_environment "${MSVS_PATH//:/*}" "${MSVS_INC//;/*}" "${MSVS_LIB//;/*}" "$i" $arch ; then + # Put the package back into FOUND, but augmented with the architecture name and with the + # derived values. + FOUND["$i-$arch"]="${CURRENT%)} [\"MSVS_PATH\"]=\"$MSVS_PATH\" \ + [\"MSVS_INC\"]=\"$MSVS_INC\" \ + [\"MSVS_LIB\"]=\"$MSVS_LIB\" \ + [\"ASSEMBLER\"]=\"$ASSEMBLER\")" #"# fixes vim syn match error + + # Check to see if this is a match for the environment C compiler. + if [[ -n ${ENV_ARCH+x} ]] ; then + TEST_cl=$(PATH="$MSVS_PATH:$PATH" "$WHICH" cl) + TEST_cl=${TEST_cl,,} + TEST_cl=${TEST_cl/bin\/*_/bin\/} + if [[ $TEST_cl = $ENV_cl ]] ; then + if [[ ${!ENV_INC/"$MSVS_INC"/} != "${!ENV_INC}" && \ + ${!ENV_LIB/"$MSVS_LIB"/} != "${!ENV_LIB}" ]] ; then + debug "$i-$arch is a strong candidate for the Environment C compiler" + if [[ -n ${ENV_COMPILER+x} ]] ; then + if [[ -z ${ENV_COMPILER} ]] ; then + ENV_COMPILER=$i-$arch + unset WEAK_ENV + else + # More than one strong candidate - no fall back available + unset ENV_COMPILER + unset WEAK_ENV + fi + fi + else + debug "$i-$arch is a weak candidate for the Environment C compiler" + if [[ -n ${WEAK_ENV+x} ]] ; then + if [[ -z ${WEAK_ENV} ]] ; then + WEAK_ENV=$i-$arch + else + # More than one weak candidate - no fall back available + unset WEAK_ENV + fi + fi + fi + fi + fi + fi + done + + # Does this package match the current preference? Note that PREFERENCE and TEST are constructed in + # a cunning (and hopefully not too "You are not expected to understand this" way) such that $PREF + # will always equal $i, unless $PREF = "@". + if [[ $PREF = $i ]] ; then + # In which case, check that the architecture(s)s were found + if [[ -n ${FOUND["$i-$LEFT_ARCH"]+x} && -n ${FOUND["$i-$RIGHT_ARCH"]+x} ]] ; then + debug "Solved TARGET_ARCH=$TARGET_ARCH with $i" + SOLUTION=$i + break + fi + fi + + if [[ $PREF != "@" ]] ; then + ((pref++)) + PREF=${PREFERENCE[$pref]} + fi +done + +# If we got this far, then either we failed to find a compiler at all, or we were looking for the +# environment compiler (or --all was specified). + +# Adopt a weak match for the environment compiler, if that's the best we can do. +if [[ -n ${ENV_COMPILER+x} && -z ${ENV_COMPILER} && -n ${WEAK_ENV} ]] ; then + warning "Assuming Environment C compiler is $WEAK_ENV" + ENV_COMPILER=$WEAK_ENV +fi + +declare -A FLIP +FLIP=(["x86"]="x64" ["x64"]="x86") + +if [[ $MODE -eq 0 ]] ; then + if [[ $PREF = "@" && -n ${ENV_COMPILER} ]] ; then + SOLUTION=${ENV_COMPILER%-$ENV_ARCH} + # If --arch wasn't specified, then ensure that the other architecture was also found. If --arch + # was specified, then validate that the compiler was valid. This should always happen, unless + # something went wrong running the script to get MSVS_PATH, MSVS_LIB and MSVS_INC. + if [[ -n ${FOUND["$SOLUTION-${FLIP[$ENV_ARCH]}"]+x} || + -n ${FOUND["$SOLUTION-$TARGET_ARCH"]+x} ]] ; then + debug "Solved with $SOLUTION" + else + unset SOLUTION + unset ENV_ARCH + fi + fi + + if [[ -z ${SOLUTION+x} ]] ; then + ((pref++)) + debug "Search remaining: ${PREFERENCE[*]}" + TEST_ARCH=$TARGET_ARCH + for i in "${PREFERENCE[@]:$pref}" ; do + if [[ -n ${FOUND["$i-$LEFT_ARCH"]+x} && -n ${FOUND["$i-$RIGHT_ARCH"]+x} ]] ; then + debug "Solved TARGET_ARCH='$TARGET_ARCH' with $i" + SOLUTION=$i + break + fi + done + fi +fi + +debug "Solution: $SOLUTION" + +if [[ -n ${ENV_COMPILER} && $MODE -eq 1 ]] ; then + echo "Identified Environment C compiler as $ENV_COMPILER" +fi + +if [[ $MODE -eq 1 ]] ; then + echo "Installed and usable packages:" + for i in "${!FOUND[@]}" ; do + echo " $i" + done | sort + exit 0 +fi + +if [[ -n $SOLUTION ]] ; then + eval COMPILER=${FOUND[$SOLUTION-$LEFT_ARCH]} + output MSVS_NAME "${COMPILER["DISPLAY"]}" $LEFT_ARCH + output MSVS_PATH "${COMPILER["MSVS_PATH"]}" $LEFT_ARCH + output MSVS_INC "${COMPILER["MSVS_INC"]}" $LEFT_ARCH + output MSVS_LIB "${COMPILER["MSVS_LIB"]}" $LEFT_ARCH + if [[ $ML_REQUIRED -eq 1 ]] ; then + output MSVS_ML "${COMPILER["ASSEMBLER"]%.exe}" always + fi + if [[ -z $TARGET_ARCH ]] ; then + eval COMPILER=${FOUND[$SOLUTION-$RIGHT_ARCH]} + output MSVS64_PATH "${COMPILER["MSVS_PATH"]}" $RIGHT_ARCH + output MSVS64_INC "${COMPILER["MSVS_INC"]}" $RIGHT_ARCH + output MSVS64_LIB "${COMPILER["MSVS_LIB"]}" $RIGHT_ARCH + if [[ $ML_REQUIRED -eq 1 ]] ; then + output MSVS64_ML "${COMPILER["ASSEMBLER"]%.exe}" always + fi + fi + exit 0 +else + exit 1 +fi diff --git a/.travis/or1k-sim.exp b/.ci/or1k-sim.exp index 3920413..3920413 100644 --- a/.travis/or1k-sim.exp +++ b/.ci/or1k-sim.exp diff --git a/.travis/powerpc-eabisim.exp b/.ci/powerpc-eabisim.exp index 285fd4f..285fd4f 100644 --- a/.travis/powerpc-eabisim.exp +++ b/.ci/powerpc-eabisim.exp diff --git a/.travis/site.exp b/.ci/site.exp index 644ec63..96c013e 100644 --- a/.travis/site.exp +++ b/.ci/site.exp @@ -1,11 +1,11 @@ -# Copyright (C) 2008, 2010, 2018, 2019 Anthony Green +# Copyright (C) 2008, 2010, 2018, 2019, 2021 Anthony Green # Make sure we look in the right place for the board description files. if ![info exists boards_dir] { set boards_dir {} } -lappend boards_dir $::env(TRAVIS_BUILD_DIR)/.travis +lappend boards_dir $::env(BOARDSDIR) verbose "Global Config File: target_triplet is $target_triplet" 2 global target_list @@ -23,5 +23,7 @@ case "$target_triplet" in { { "or1k-elf" } { set target_list "or1k-sim" } + { "powerpc-eabisim" } { + set target_list "powerpc-eabisim" + } } - diff --git a/.travis/wine-sim.exp b/.ci/wine-sim.exp index 1ad6038..1ad6038 100644 --- a/.travis/wine-sim.exp +++ b/.ci/wine-sim.exp diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..ec19fe0 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,154 @@ +name: CI + +# Controls when the action will run. +on: + # Triggers the workflow on push or pull request events but only for the master branch + push: + branches: [ github-actions ] + pull_request: + branches: [ github-actions ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + + build-sim: + name: Build & test + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + include: + - MEVAL: "export CC=clang && CXX=clang" + - HOST: "i386-pc-linux-gnu" + MEVAL: 'export CC="gcc -m32" && CXX="g++ -m32"' + - CONFIGURE_OPTIONS: "--disable-shared" + - CONFIGURE_OPTIONS: "--enable-shared" + - HOST: "m68k-linux-gnu" + MEVAL: 'export CC="m68k-linux-gnu-gcc-8 -mcpu=547x" && CXX="m68k-linux-gnu-g++-8 -mcpu=547x"' + CONFIGURE_OPTIONS: '--disable-shared' + QEMU_LD_PREFIX: '/usr/m68k-linux-gnu' + QEMU_CPU: 'cfv4e' + - HOST: "sh4-linux-gnu" + CONFIGURE_OPTIONS: "--disable-shared" + QEMU_LD_PREFIX: "/usr/sh4-linux-gnu" + QEMU_CPU: 'sh7785' + - HOST: "alpha-linux-gnu" + CONFIGURE_OPTIONS: "--disable-shared" + QEMU_LD_PREFIX: "/usr/alpha-linux-gnu" + - HOST: "arm32v7-linux-gnu" + LIBFFI_TEST_OPTIMIZATION: "-O0" + - HOST: "arm32v7-linux-gnu" + LIBFFI_TEST_OPTIMIZATION: "-O2" + - HOST: "arm32v7-linux-gnu" + LIBFFI_TEST_OPTIMIZATION: "-O2 -fomit-frame-pointer" + - HOST: "powerpc-eabisim" + RUNTESTFLAGS: "--target_board powerpc-eabisim" + - HOST: "or1k-elf" + RUNTESTFLAGS: "--target_board or1k-sim" + - HOST: "m32r-elf" + RUNTESTFLAGS: "--target_board m32-sim" + - HOST: "bfin-elf" + RUNTESTFLAGS: "--target_board bfin-sim" + - MEVAL: "export PATH=/opt/moxielogic/bin:$PATH && CC=moxie-elf-gcc && CXX=moxie-elf-g++" + HOST: "moxie-elf" + LDFLAGS: "-Tsim.ld" + RUNTESTFLAGS: "--target_board moxie-sim" + + steps: + - uses: actions/checkout@v2 + + - env: + MEVAL: ${{ matrix.MEVAL }} + HOST: ${{ matrix.HOST }} + LDFLAGS: ${{ matrix.LDFLAGS }} + RUNTESTFLAGS: ${{ matrix.RUNTESTFLAGS }} + CONFIGURE_OPTIONS: ${{ matrix.CONFIGURE_OPTIONS }} + QEMU_LD_PREFIX: ${{ matrix.QEMU_LD_PREFIX }} + QEMU_CPU: ${{ matrix.QEMU_CPU }} + run: | + if test x"$MEVAL" != x; then eval ${MEVAL}; fi + ./.ci/install.sh + ./.ci/build.sh + + build: + name: Build & test with Cygwin + runs-on: windows-latest + + strategy: + fail-fast: false + matrix: + platform: [windows-latest] + + steps: + - uses: actions/checkout@v2 + + - name: Set up Cygwin + uses: egor-tensin/setup-cygwin@v3 + with: + platform: x64 + packages: wget gcc-core make dejagnu automake autoconf libtool texinfo dos2unix unzip + + - run: | + cd $(cygpath $RUNNER_WORKSPACE)/libffi + wget https://rl.gl/cli/rlgl-windows-amd64.zip + unzip rlgl-windows-amd64.zip + find . -name \*.m4|xargs dos2unix + find . -name \*.ac|xargs dos2unix + find . -name \*.am|xargs dos2unix + find . -name \*.host|xargs dos2unix + autoreconf -f -v -i + ./configure + find . -name libtool\*|xargs dos2unix + make -j 4 + TERM=none export DEJAGNU=$(pwd)/.ci/site.exp BOARDSDIR=$(pwd)/.ci make check || true + ./rlgl/rlgl.exe l --key=0LIBFFI-0LIBFFI-0LIBFFI-0LIBFFI https://rl.gl + ID=$(./rlgl/rlgl.exe start) + ./rlgl/rlgl.exe e --id=$ID --policy=https://github.com/libffi/rlgl-policy.git $(find . -name libffi.log) + shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' + + build-msvc: + name: Build & test with Visual C++ + runs-on: windows-latest + + strategy: + fail-fast: false + matrix: + platform: [windows-latest] + + steps: + - uses: actions/checkout@v2 + - uses: egor-tensin/setup-cygwin@v3 + with: + platform: x64 + packages: wget make dejagnu automake autoconf libtool texinfo unzip dos2unix + - uses: ilammy/msvc-dev-cmd@v1.8.1 + - uses: microsoft/setup-msbuild@v1.0.2 + + - name: Build and test + run: | + dos2unix $(cygpath $RUNNER_WORKSPACE)/libffi/.ci/msvs-detect + # $(cygpath $RUNNER_WORKSPACE)/libffi/.ci/msvs-detect --arch=x64 --with-assembler + export PATH=$PATH:"/cygdrive/c/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.16.27023/bin/HostX64/x64" + cd $(cygpath $RUNNER_WORKSPACE)/libffi + wget https://rl.gl/cli/rlgl-windows-amd64.zip + unzip rlgl-windows-amd64.zip + find . -name \*.sh|xargs dos2unix + find . -name \*.m4|xargs dos2unix + find . -name \*.ac|xargs dos2unix + find . -name \*.am|xargs dos2unix + find . -name \*.host|xargs dos2unix + dos2unix .ci/ar-lib + autoreconf -f -v -i + ./configure CC="$(pwd)/msvcc.sh -m64" CXX="$(pwd)/msvcc.sh -m64" LD='link' CPP='cl -nologo -EP' CXXCPP='cl -nologo -EP' CPPFLAGS='-DFFI_BUILDING_DLL' AR='$(pwd)/.ci/ar-lib lib' NM='dumpbin -symbols' STRIP=':' --build=$BUILD --host=$HOST $DEBUG_ARG $SHARED_ARG || cat */config.log + find . -name libtool\*|xargs dos2unix + make + cp $(find . -name 'libffi-?.dll') x86_64-pc-cygwin/testsuite/ + TERM=none DEJAGNU=$(pwd)/.ci/site.exp BOARDSDIR=$(pwd)/.ci make check || true + ./rlgl/rlgl.exe l --key=0LIBFFI-0LIBFFI-0LIBFFI-0LIBFFI https://rl.gl + ID=$(./rlgl/rlgl.exe start) + ./rlgl/rlgl.exe e --id=$ID --policy=https://github.com/libffi/rlgl-policy.git $(find . -name libffi.log) + shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' @@ -9,7 +9,7 @@ Makefile Makefile.in aclocal.m4 compile -!.travis/compile +!.ci/compile configure depcomp doc/libffi.info diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a18919c..0000000 --- a/.travis.yml +++ /dev/null @@ -1,83 +0,0 @@ ---- -sudo: required - -language: cpp - -# For qemu-powered targets, get the list of supported processors from -# travis by setting QEMU_CPU=help, then set -mcpu= for the compilers -# accordingly. - -matrix: - include: - - os: linux - env: HOST=powerpc-eabisim RUNTESTFLAGS="--target_board powerpc-eabisim" DEJAGNU="/opt/.travis/site.exp" - - os: linux - env: HOST=or1k-elf RUNTESTFLAGS="--target_board or1k-sim" DEJAGNU="/opt/.travis/site.exp" - - os: linux - env: HOST=m32r-elf RUNTESTFLAGS="--target_board m32r-sim" DEJAGNU="/opt/.travis/site.exp" - - os: linux - env: HOST=bfin-elf RUNTESTFLAGS="--target_board bfin-sim" DEJAGNU="/opt/.travis/site.exp" -# This configuration is still using the native x86 toolchain? -# - os: osx -# env: HOST=aarch64-apple-darwin13 - - os: osx - env: HOST=x86_64-apple-darwin10 - - os: linux - env: HOST=x86_64-w64-mingw32 MEVAL='export CC="x86_64-w64-mingw32-gcc" && CXX="x86_64-w64-mingw32-g++" RUNTESTFLAGS="--target_board wine-sim" DEJAGNU="$TRAVIS_BUILD_DIR/.travis/site.exp" CONFIGURE_OPTIONS=--disable-shared LIBFFI_TEST_OPTIMIZATION="-O2" - - os: linux - env: HOST=sh4-linux-gnu CONFIGURE_OPTIONS=--disable-shared QEMU_LD_PREFIX=/usr/sh4-linux-gnu - - os: linux - env: HOST=alpha-linux-gnu CONFIGURE_OPTIONS=--disable-shared QEMU_LD_PREFIX=/usr/alpha-linux-gnu - - os: linux - env: HOST=m68k-linux-gnu MEVAL='export CC="m68k-linux-gnu-gcc-8 -mcpu=547x" && CXX="m68k-linux-gnu-g++-8 -mcpu=547x"' CONFIGURE_OPTIONS=--disable-shared QEMU_LD_PREFIX=/usr/m68k-linux-gnu QEMU_CPU=cfv4e - - os: linux - arch: s390x - env: HOST=s390x-linux-gnu - - os: linux - arch: ppc64le - env: HOST=ppc64le-linux-gnu - - os: linux - arch: arm64 - env: HOST=aarch64-linux-gnu - - os: linux - arch: arm64 - env: HOST=aarch64-linux-gnu - compiler: clang - - os: linux - env: HOST=arm32v7-linux-gnu LIBFFI_TEST_OPTIMIZATION="-O0" - - os: linux - env: HOST=arm32v7-linux-gnu LIBFFI_TEST_OPTIMIZATION="-O2" - - os: linux - env: HOST=arm32v7-linux-gnu LIBFFI_TEST_OPTIMIZATION="-O2 -fomit-frame-pointer" -# The sparc64 linux system in the GCC compile farm is non-responsive. -# - os: linux -# env: HOST=sparc64-linux-gnu -# The mips64 linux system in the GCC compile farm is not allowing logins -# - os: linux -# env: HOST=mips64el-linux-gnu - - os: linux - compiler: gcc - env: HOST=i386-pc-linux-gnu MEVAL='export CC="$CC -m32" && CXX="$CXX -m32"' - - os: linux - compiler: gcc - - os: linux - compiler: gcc - env: CONFIGURE_OPTIONS=--disable-shared - - os: linux - compiler: clang - - os: linux - compiler: clang - env: CONFIGURE_OPTIONS=--disable-shared - - os: linux - env: HOST=moxie-elf MEVAL='export PATH=/opt/moxielogic/bin:$PATH && CC=moxie-elf-gcc && CXX=moxie-elf-g++' LDFLAGS=-Tsim.ld RUNTESTFLAGS="--target_board moxie-sim" DEJAGNU="$TRAVIS_BUILD_DIR/.travis/site.exp" - -before_install: - - if test x"$MEVAL" != x; then eval ${MEVAL}; fi - -install: - - travis_wait 60 ./.travis/install.sh - -script: - - if ! test x"$MEVAL" = x; then eval ${MEVAL}; fi - - travis_wait 115 sleep infinity & - - ./.travis/build.sh diff --git a/.travis/build-cross-in-container.sh b/.travis/build-cross-in-container.sh deleted file mode 100755 index 7e2252c..0000000 --- a/.travis/build-cross-in-container.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -cd /opt - -echo $PATH -export PATH=/usr/local/bin:$PATH -echo $PATH - -./configure --host=${HOST} || cat */config.log -make -make dist -make check RUNTESTFLAGS="-a $RUNTESTFLAGS" || true - - |