1
0
Fork 0

Expand CI coverage and move actions into scripts

This change makes a couple changes to the CI workflow:
 - Adds more compiler coverage:
     - gcc to MacOS (see note below)
     - 32 and 64bit gcc and clang to Windows

 - With more builds, this separates them into per-OS workflow YAMLs
   (laying the foundation for more build environments: BSD? DOS? ... )

 - Moves all functional commands from GitHub-syntax-YAML into scripts,
   which (besides eliminating repeated code), now serve a dual-purpose
   of being runnable outside of GitHub.
     - One script takes care of listing dependent packages for the given
       runtime environment
     - Another script takes care of configuring and building

These scripts can be leveraged by a nightly build & asset generator in
the future.

Note: adding GCC to MacOS is now "correct" from a build perspective,
however to keep this PR focussed on the CI workflow I have not included
the coreMIDI / AppleBlocks code-fixes here (so for now, the gcc macOS
builds will fail; we will merge the coreMIDI / AppleBlocks later
depending on how upstream wants to handle it).
This commit is contained in:
krcroft 2019-10-26 11:41:33 -07:00
parent b87966cd11
commit 86aabad5da
No known key found for this signature in database
GPG key ID: 94D8F8D0D171A64B
9 changed files with 1176 additions and 144 deletions

View file

@ -1,142 +0,0 @@
name: "Build"
on: [push]
jobs:
build_gcc9:
name: "GCC 9 (ubuntu-18.04)"
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- name: "Log environment"
run: ./scripts/log-env.sh
- run: sudo apt update
- name: "Install packages"
run: sudo apt-get install g++-9 libsdl1.2-dev libsdl-net1.2-dev libsdl-sound1.2-dev
- name: "Build"
env:
CC: gcc-9
CXX: g++-9
run: |
# build steps
set -x
$CXX --version
./autogen.sh
./configure CXXFLAGS="-Wall -fdiagnostics-color=always"
make -j "$(nproc)" |& tee build.log
- name: "Summarize warnings"
run: python3 ./scripts/count-warnings.py build.log
build_gcc_ubuntu:
name: "GCC"
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-18.04, ubuntu-16.04]
steps:
- uses: actions/checkout@v1
- name: "Log environment"
run: ./scripts/log-env.sh
- run: sudo apt update
- name: "Install packages"
run: sudo apt-get install libsdl1.2-dev libsdl-net1.2-dev libsdl-sound1.2-dev
- name: "Build"
run: |
# build steps
set -x
g++ --version
./autogen.sh
./configure CXXFLAGS="-Wall -fdiagnostics-color=always"
make -j "$(nproc)" |& tee build.log
- name: "Summarize warnings"
run: python3 ./scripts/count-warnings.py build.log
build_clang:
name: "Clang (ubuntu-18.04)"
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- name: "Log environment"
run: ./scripts/log-env.sh
- run: sudo apt update
- name: "Install packages"
run: sudo apt-get install libsdl1.2-dev libsdl-net1.2-dev libsdl-sound1.2-dev
- name: "Build"
env:
CC: clang
CXX: clang++
run: |
# build steps
set -x
$CXX --version
./autogen.sh
./configure CXXFLAGS="-Wall"
make -j "$(nproc)" |& tee build.log
- name: "Summarize warnings"
run: python3 ./scripts/count-warnings.py build.log
build_macos:
name: "Clang (macOS-10.14)"
runs-on: macOS-10.14
steps:
- uses: actions/checkout@v1
- name: "Log environment"
run: ./scripts/log-env.sh
- run: brew update
- name: "Install packages"
run: brew install automake libpng sdl sdl_net sdl_sound
- name: "Build"
run: |
# build steps
set -x
clang++ --version
./autogen.sh
./configure CXXFLAGS="-Wall"
make -j "$(sysctl -n hw.physicalcpu)" 2>&1 | tee build.log
- name: "Summarize warnings"
run: python3 ./scripts/count-warnings.py build.log
build_msvc_debug:
name: "MSVC 14 Debug (win-2019)"
runs-on: windows-2019
steps:
- uses: actions/checkout@v1
- name: "Log environment"
shell: pwsh
run: .\scripts\log-env.ps1
- name: "Install packages"
shell: pwsh
run: |
vcpkg install libpng sdl1 sdl1-net
vcpkg integrate install
- name: "Build"
shell: pwsh
env:
PATH: '${env:PATH};C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64'
run: |
# build steps
cd visualc_net
MSBuild -m dosbox.sln -p:Configuration=Debug
build_msvc_release:
name: "MSVC 14 Release (win-2019)"
runs-on: windows-2019
steps:
- uses: actions/checkout@v1
- name: "Log environment"
shell: pwsh
run: .\scripts\log-env.ps1
- name: "Install packages"
shell: pwsh
run: |
vcpkg install libpng sdl1 sdl1-net
vcpkg integrate install
- name: "Build"
shell: pwsh
env:
PATH: '${env:PATH};C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64'
run: |
# build steps
cd visualc_net
MSBuild -m dosbox.sln -p:Configuration=Release

48
.github/workflows/linux.yml vendored Normal file
View file

@ -0,0 +1,48 @@
name: "Linux builds"
on: push
jobs:
build_ubuntu_gcc9:
name: "GCC 9 (ubuntu-18.04)"
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- name: "Log environment"
run: ./scripts/log-env.sh
- name: Install dependencies
run: sudo apt-get update && sudo apt install -y $(./scripts/list-build-dependencies.sh --compiler-version 9)
- name: Build
run: ./scripts/build.sh --compiler-version 9 --lto
- name: "Summarize warnings"
run: ./scripts/count-warnings.py build.log
build_ubuntu_gcc_defaults:
name: "GCC"
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-18.04, ubuntu-16.04]
steps:
- uses: actions/checkout@v1
- name: "Log environment"
run: ./scripts/log-env.sh
- name: Install dependencies
run: sudo apt-get update && sudo apt install -y $(./scripts/list-build-dependencies.sh)
- name: Build
run: ./scripts/build.sh
- name: "Summarize warnings"
run: ./scripts/count-warnings.py build.log
build_ubuntu_clang_8:
name: "Clang 8 (ubuntu-18.04)"
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- name: "Log environment"
run: ./scripts/log-env.sh
- name: Install dependencies
run: sudo apt-get update && sudo apt install -y $(./scripts/list-build-dependencies.sh --compiler clang --compiler-version 8)
- name: Build
run: ./scripts/build.sh --compiler clang --compiler-version 8 --lto
- name: "Summarize warnings"
run: ./scripts/count-warnings.py build.log

16
.github/workflows/macos.yml vendored Normal file
View file

@ -0,0 +1,16 @@
name: "macOS builds"
on: push
jobs:
build_macos_clang:
name: "Clang (macOS-10.14)"
runs-on: macOS-10.14
steps:
- uses: actions/checkout@v1
- name: "Log environment"
run: ./scripts/log-env.sh
- name: Install dependencies
run: brew install $(./scripts/list-build-dependencies.sh --compiler clang)
- name: Build
run: ./scripts/build.sh --compiler clang --lto
- name: "Summarize warnings"
run: python3 ./scripts/count-warnings.py build.log

142
.github/workflows/windows.yml vendored Normal file
View file

@ -0,0 +1,142 @@
# SPDX-License-Identifier: GPL-2.0-or-later
name: "Windows builds"
on: push
jobs:
build_msvc_debug:
name: "MSVC 14 Debug (win-2019)"
runs-on: windows-2019
steps:
- uses: actions/checkout@v1
- name: "Log environment"
shell: pwsh
run: .\scripts\log-env.ps1
- name: "Install packages"
shell: pwsh
run: |
vcpkg install libpng sdl1 sdl1-net
vcpkg integrate install
- name: "Build"
shell: pwsh
env:
PATH: '${env:PATH};C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64'
run: |
# build steps
cd visualc_net
MSBuild -m dosbox.sln -p:Configuration=Debug
build_msvc_release:
name: "MSVC 14 Release (win-2019)"
runs-on: windows-2019
steps:
- uses: actions/checkout@v1
- name: "Log environment"
shell: pwsh
run: .\scripts\log-env.ps1
- name: "Install packages"
shell: pwsh
run: |
vcpkg install libpng sdl1 sdl1-net
vcpkg integrate install
- name: "Build"
shell: pwsh
env:
PATH: '${env:PATH};C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64'
run: |
# build steps
cd visualc_net
MSBuild -m dosbox.sln -p:Configuration=Release
build_msys2_gcc_64:
name: MSYS2 GCC-9 x86_64
runs-on: windows-2019
env:
CHERE_INVOKING: yes
steps:
- uses: actions/checkout@v1
- name: Install msys2 environment
run: choco install msys2 --no-progress
- name: "Log environment"
run: C:\tools\msys64\usr\bin\bash -lc "./scripts/log-env.sh"
- name: Install dependencies
run: C:\tools\msys64\usr\bin\bash -lc "./scripts/list-build-dependencies.sh | xargs pacman -S --noconfirm"
- name: Build
run: C:\tools\msys64\usr\bin\bash -lc "./scripts/build.sh --bin-path /mingw64/bin"
- name: Summarize warnings
run: .\scripts\count-warnings.py build.log
build_msys2_gcc_32:
name: MSYS2 GCC-9 i686
runs-on: windows-2019
env:
CHERE_INVOKING: yes
steps:
- uses: actions/checkout@v1
- name: Install msys2 environment
run: choco install msys2 --no-progress
- name: "Log environment"
run: C:\tools\msys64\usr\bin\bash -lc "./scripts/log-env.sh"
- name: Install dependencies
run: C:\tools\msys64\usr\bin\bash -lc "./scripts/list-build-dependencies.sh --bit-depth 32 | xargs pacman -S --noconfirm"
- name: Build
run: C:\tools\msys64\usr\bin\bash -lc "./scripts/build.sh --bit-depth 32 --bin-path /mingw32/bin"
- name: Summarize warnings
run: .\scripts\count-warnings.py build.log
build_msys2_clang_64:
name: MSYS2 Clang-8 x86_64
runs-on: windows-2019
env:
CHERE_INVOKING: yes
steps:
- uses: actions/checkout@v1
- name: Install msys2 environment
run: choco install msys2 --no-progress
- name: "Log environment"
run: C:\tools\msys64\usr\bin\bash -lc "./scripts/log-env.sh"
- name: Install dependencies
run: C:\tools\msys64\usr\bin\bash -lc "./scripts/list-build-dependencies.sh --compiler clang | xargs pacman -S --noconfirm"
- name: Build
run: C:\tools\msys64\usr\bin\bash -lc "./scripts/build.sh --compiler clang --bin-path /mingw64/bin"
- name: Summarize warnings
run: .\scripts\count-warnings.py build.log
build_msys2_clang_32:
name: MSYS2 Clang-8 i686
runs-on: windows-2019
env:
CHERE_INVOKING: yes
steps:
- uses: actions/checkout@v1
- name: Install msys2 environment
run: choco install msys2 --no-progress
- name: "Log environment"
run: C:\tools\msys64\usr\bin\bash -lc "./scripts/log-env.sh"
- name: Install dependencies
run: C:\tools\msys64\usr\bin\bash -lc "./scripts/list-build-dependencies.sh --compiler clang --bit-depth 32 | xargs pacman -S --noconfirm"
- name: Build
run: C:\tools\msys64\usr\bin\bash -lc "./scripts/build.sh --compiler clang --bit-depth 32 --bin-path /mingw32/bin"
- name: Summarize warnings
run: .\scripts\count-warnings.py build.log

110
scripts/build.md Normal file
View file

@ -0,0 +1,110 @@
# DOSBox build script
A helper-script that builds DOSBox with varying compilers, release types, and versions
on MacOS, Linux, and Windows.
A second script, **list-build-dependencies.sh** prints a list of package and library
dependencies used to build and link DOSBox, customized for your hardware, operating system,
and selected compiler and its version. You can use this script's output to install
those necessary packages.
## Requirements
- **Windows newer than XP**
- **NTFS-based C:**, because msys2 doesn't work on FAT filesystems
- **Chocolately**, to install msys2
- **MacOS** 10.x
- **brew**, as the package manager
- **Ubuntu** 16.04 or newer
- **apt**, as the package manager
- **sudo**, to permit installation of depedencies (optional)
- **Build dependencies (all operating systems)**
- Per those listed by the accompanying list-build-dependencies.sh script
## Windows Installation and Usage
1. Download and install Chocolatey: https://chocolatey.org/install
1. Open a console and run Cholocatey's command line interface (CLI) to install msys2:
`choco install msys2 git --no-progress`
```
Chocolatey v0.10.15
Installing the following packages:
msys2 git
By installing you accept licenses for the packages.
msys2 v20180531.0.0 [Approved]
msys2 package files install completed. Performing other installation steps.
Installing to: C:\tools\msys64
Extracting 64-bit C:\ProgramData\chocolatey\lib\msys2\tools\msys2-base-x86_64-20180531.tar.xz to C:\tools\msys64...
C:\tools\msys64
Extracting C:\tools\msys64\msys2-base-x86_64-20180531.tar to C:\tools\msys64...
C:\tools\msys64
Starting initialization via msys2_shell.cmd
PATH environment variable does not have C:\tools\msys64 in it. Adding...
```
1. Open a new console and clone the DOSBox staging repository:
`git clone https://github.com/dreamer/dosbox-staging.git`
1. [optional] Install the build tools and package dependencies, if not yet done so:
``` shell
cd dosbox-staging
SET CWD=%cd%
bash -lc "pacman -S --noconfirm $($CWD/scripts/list-build-dependencies.sh)"
```
1. Launch the build script with default settings:
``` shell
cd dosbox-staging
SET CWD=%cd%
bash -lc "$CWD/scripts/build.sh --bin-path /mingw64/bin --src-path $CWD"
```
## MacOS Installation and Usage
1. Download and install brew: https://brew.sh
1. Install git: `brew install git`
1. Clone the repository: `git clone https://github.com/dreamer/dosbox-staging.git`
1. Change directories into the repo: `cd dosbox-staging`
1. [optional] Install the build tools and package dependencies, if not yet done so:
``` shell
brew update
brew install $(./scripts/list-build-dependencies.sh)
```
1. Build DOSBox: `./scripts/build.sh`
## Linux (Ubuntu/Debian-based) Installation and Usage
1. Install git: `sudo apt install -y git`
1. Clone the repository: `git clone https://github.com/dreamer/dosbox-staging.git`
1. Change directories into the repo: `cd dosbox-staging`
1. [optional] Install the build tools and package dependencies, if not yet done so:
``` shell
sudo apt update -y
sudo apt install -y $(./scripts/list-build-dependencies.sh)
```
1. Build DOSBox: `./scripts/build.sh`
## Additional Tips
The compiler, version, and bit-depth can be selected by passing the following common
options to the **list-build-dependencies.sh** and **build.sh** scripts:
* `--compiler clang`, to use CLang instead of GCC
* `--compiler-version 8`, to use a specific version of compiler (if available in your package manager)
* `--bit-depth 32`, to build a 32-bit binary instead of 64-bit
After building, your binary will reside inside the src/ directory.
Build flags you might be interested in:
* `--release debug`, to build a binary containing debug symbols (instead of **fast** or **small**)
* `--lto`, perform optimizations across the entire object space instead of per-file (Only available on Mac and Linux)
The above flags are othogonal and thus can be mixed-and-matched as desired.
If you want to run multiple back-to-back builds from the same directory with different settings then
add the `--clean` flag to ensure previous objects and binaries are removed.

561
scripts/build.sh Executable file
View file

@ -0,0 +1,561 @@
#!/bin/bash
##
#
# Copyright (c) 2019 Kevin R. Croft
# SPDX-License-Identifier: GPL-2.0-or-later
#
# This script builds DOSBox within supported environments including
# MacOS, Ubuntu Linux, and MSYS2 using specified compilers and release types.
#
# For automation without prompts, Windows should have User Account Control (UAC)
# disabled, which matches the configuration of GitHub'Windows VMs, described here:
# https://help.github.com/en/articles/virtual-environments-for-github-actions
#
# See the usage block below for details or run it with the -h or --help arguments.
#
# In general, this script adheres to Google's shell scripting style guide
# (https://google.github.io/styleguide/shell.xml), however some deviations (such as
# tab indents instead of two-spaces) are used to fit with DOSBox's in-practice"
# coding style.
#
set -euo pipefail
IFS=$'\n\t'
function usage() {
if [ -n "${1}" ]; then
errcho "${1}"
fi
local script
script=$(basename "${0}")
echo "Usage: ${script} [-b 32|64] [-c gcc|clang] [-f linux|macos|msys2] [-d] [-l] \\"
echo " [-p /custom/bin] [-u #] [-r fast|small|debug] [-s /your/src] [-t #]"
echo ""
echo " FLAG Description Default"
echo " ----------------------- ----------------------------------------------------- -------"
echo " -b, --bit-depth Build a 64 or 32 bit binary [$(print_var "${BITS}")]"
echo " -c, --compiler Choose either gcc or clang [$(print_var "${COMPILER}")]"
echo " -f, --force-system Force the system to be linux, macos, or msys2 [$(print_var "${SYSTEM}")]"
echo " -d, --fdo Used feedback-Directed Optimization data [$(print_var "${FDO}")]"
echo " -l, --lto Perform link-time-optimization [$(print_var "${LTO}")]"
echo " -p, --bin-path Prepend PATH with the one provided to find executables [$(print_var "${BIN_PATH}")]"
echo " -u, --compiler-version # Use a specific compiler version (ie: 9 -> gcc-9) [$(print_var "${COMPILER_VERSION}")]"
echo " -r, --release Build a fast, small, or debug release [$(print_var "${RELEASE}")]"
echo " -s, --src-path Use a different source directory to build [$(print_var "${SRC_PATH}")]"
echo " -t, --threads # Override auto-detection of number of logical CPUs [$(print_var "${THREADS}")]"
echo " -v, --version Print the version of this script [$(print_var "${SCRIPT_VERSION}")]"
echo " -x, --clean Clean old object and build file before making [$(print_var "${CLEAN}")]"
echo " -h, --help Print this usage text"
echo ""
echo "Example: ${script} -b 32 --compiler clang -u 8 --bin-path /mingw64/bin -r small --lto"
echo ""
echo "Note: the last value will take precendent if duplicate flags are provided."
exit 1
}
# parse params
function parse_args() {
defaults
while [[ "${#}" -gt 0 ]]; do case ${1} in
-b|--bit-depth) BITS="${2}"; shift;shift;;
-c|--compiler) COMPILER="${2}"; shift;shift;;
-d|--fdo) FDO="true"; shift;;
-f|--force-system) SYSTEM="${2}"; shift;shift;;
-l|--lto) LTO="true"; shift;;
-p|--bin-path) BIN_PATH="${2}"; shift;shift;;
-u|--compiler-version) COMPILER_VERSION="${2}";shift;shift;;
-r|--release) RELEASE="${2}"; shift;shift;;
-s|--src-path) SRC_PATH="${2}"; shift;shift;;
-t|--threads) THREADS="${2}"; shift;shift;;
-v|--version) print_version; shift;;
-x|--clean) CLEAN="true"; shift;;
-h|--help) usage "Show usage"; shift;;
*) usage "Unknown parameter: ${1}"; shift;shift;;
esac; done
}
function defaults() {
# variables that are directly set via user arguments
BITS="64"
CLEAN="false"
COMPILER="gcc"
COMPILER_VERSION="unset"
FDO="false"
LTO="false"
BIN_PATH="unset"
RELEASE="fast"
SRC_PATH="$(dirname "$(dirname "$(realpath -s "$0")")")"
SYSTEM="auto"
THREADS="auto"
# derived variables with initial values
EXECUTABLE="unset"
VERSION_POSTFIX=""
MACHINE="unset"
CONFIGURE_OPTIONS=("--enable-core-inline")
CFLAGS_ARRAY=("-Wall" "-pipe")
LDFLAGS_ARRAY=("")
LIBS_ARRAY=("")
CALL_CACHE=("")
# read-only strings
readonly SCRIPT_VERSION="0.9"
readonly REPO_URL="https://github.com/dreamer/dosbox-staging"
# environment variables passed onto the build
export CC="CC_is_not_set"
export CXX="CXX_is_not_set"
export LD="LD_is_not_set"
export AR="AR_is_not_set"
export RANLIB="RANLIB_is_not_set"
export CFLAGS=""
export CXXFLAGS=""
export LDFLAGS=""
export LIBS=""
export GCC_COLORS="error=01;31:warning=01;35:note=01;36:range1=32:range2=34:locus=01:\
quote=01:fixit-insert=32:fixit-delete=31:diff-filename=01:\
diff-hunk=32:diff-delete=31:diff-insert=32:type-diff=01;32"
}
function errcho() {
local CLEAR='\033[0m'
local RED='\033[0;91m'
>&2 echo ""
>&2 echo -e " ${RED}👉 ${*}${CLEAR}" "\\n"
}
function bug() {
local CLEAR='\033[0m'
local YELLOW='\033[0;33m'
>&2 echo -e " ${YELLOW}Please report the following at ${REPO_URL}${CLEAR}"
errcho "${@}"
exit 1
}
function error() {
errcho "${@}"
exit 1
}
function exists() {
command -v "${1}" &> /dev/null
}
function print_var() {
if [[ -z "${1}" ]]; then
echo "unset"
else
echo "${1}"
fi
}
function uses() {
# assert
if [[ "${#}" != 1 ]]; then
bug "The 'uses' function was called without an argument"
fi
# only handles function calls, so filter everything else
func="${1}"
if [[ "$(type -t "${func}")" != "function" ]]; then
bug "The 'uses' function was passed ${func}, which isn't a function"
fi
local found_in_previous="false"
# has our function already been called?
for previous_func in "${CALL_CACHE[@]}"; do
if [[ "${previous_func}" == "${func}" ]]; then
found_in_previous="true"
break
fi
done
# if it hasn't, record it and run it
if [[ "${found_in_previous}" == "false" ]]; then
CALL_CACHE+=("${func}")
"${func}"
fi
}
function print_version() {
echo "${SCRIPT_VERSION}"
exit 0
}
function system() {
if [[ "${MACHINE}" == "unset" ]]; then
MACHINE="$(uname -m)"
fi
if [[ "${SYSTEM}" == "auto" ]]; then
SYSTEM="$(uname -s)"
fi
if [[ "${SYSTEM}" == "Darwin" \
|| "${SYSTEM}" == "macos" ]]; then
SYSTEM="macos"
elif [[ "${SYSTEM}" == "MSYS"* \
|| "${SYSTEM}" == "msys2" ]]; then
SYSTEM="msys2"
elif [[ "${SYSTEM}" == "Linux" \
|| "${SYSTEM}" == "linux" ]]; then
SYSTEM="linux"
else
error "Your system, ${SYSTEM}, is not currently supported"
fi
}
function bits() {
if [[ "${BITS}" != 64 && "${BITS}" != 32 ]]; then
usage "A bit-depth of ${BITS} is not allowed; choose 64 or 32"
fi
}
function compiler_type() {
if [[ "${COMPILER}" != "gcc" && "${COMPILER}" != "clang" ]]; then
usage "The choice of compiler (${COMPILER}) is not valid; choose gcc or clang"
fi
}
function tools_and_flags() {
uses compiler_type
uses compiler_version
uses system
# GCC universal
if [[ "${COMPILER}" == "gcc" ]]; then
CC="gcc${VERSION_POSTFIX}"
LD="gcc${VERSION_POSTFIX}"
CXX="g++${VERSION_POSTFIX}"
CFLAGS_ARRAY+=("-fstack-protector" "-fdiagnostics-color=always")
# Prioritize versioned lib-tools over generics
AR="gcc-ar${VERSION_POSTFIX}"
if ! exists "${AR}"; then
AR="ar"
fi
RANLIB="gcc-ranlib${VERSION_POSTFIX}"
if ! exists "${RANLIB}"; then
RANLIB="ranlib"
fi
# CLANG universal
elif [[ "${COMPILER}" == "clang" ]]; then
CC="clang${VERSION_POSTFIX}"
CXX="clang++${VERSION_POSTFIX}"
CFLAGS_ARRAY+=("-fcolor-diagnostics")
# CLANG on Linux and MSYS2
if [[ "${SYSTEM}" == "linux" || "${SYSTEM}" == "msys2" ]]; then
LD="llvm-link${VERSION_POSTFIX}"
AR="llvm-ar${VERSION_POSTFIX}"
RANLIB="llvm-ranlib${VERSION_POSTFIX}"
# CLANG on MacOS
elif [[ "${SYSTEM}" == "macos" ]]; then
LD="ld"
fi
# CLANG and MSYS2
if [[ "${SYSTEM}" == "msys2" ]]; then
CFLAGS_ARRAY+=("-DWIN32")
fi
fi
# macOS universal
if [[ "${SYSTEM}" == "macos" ]]; then
AR="ar"
RANLIB="ranlib"
# MSYS universal
elif [[ "${SYSTEM}" == "msys2" ]]; then
LIBS_ARRAY+=("-lwinmm" "-lws2_32")
fi
}
function src_path() {
if [[ ! -d "${SRC_PATH}" ]]; then
usage "The requested source directory (${SRC_PATH}) does not exist, is not a directory, or is not accessible"
fi
cd "${SRC_PATH}"
}
function bin_path() {
uses system
uses compiler_type
# By default, if we're on macOS and using GCC then always include /usr/local/bin, because
# that's where brew installs all the binaries. If the user adds their own --bin-path,
# that will be prefixed ahead of /usr/local/bin and take precedent.
if [[ "${SYSTEM}" == "macos" && "${COMPILER}" == "gcc" ]]; then
PATH="/usr/local/bin:${PATH}"
fi
if [[ "${BIN_PATH}" != "unset" ]]; then
if [[ ! -d "${BIN_PATH}" ]]; then
usage "The requested PATH (${BIN_PATH}) does not exist, is not a directory, or is not accessible"
else
PATH="${BIN_PATH}:${PATH}"
fi
fi
}
function check_build_tools() {
for tool in "${CC}" "${CXX}" "${LD}" "${AR}" "${RANLIB}"; do
if ! exists "${tool}"; then
error "${tool} was not found in your PATH or is not executable. If it's in a custom path, use --bin-path"
fi
done
}
function compiler_version() {
if [[ "${COMPILER_VERSION}" != "unset" ]]; then
VERSION_POSTFIX="-${COMPILER_VERSION}"
fi
}
function release_flags() {
uses compiler_type
if [[ "${RELEASE}" == "fast" ]]; then
CFLAGS_ARRAY+=("-Ofast")
elif [[ "${RELEASE}" == "small" ]]; then
CFLAGS_ARRAY+=("-Os")
if [[ "${COMPILER}" == "gcc" ]]; then
CFLAGS_ARRAY+=("-ffunction-sections" "-fdata-sections")
# ld on MacOS doesn't understand --as-needed, so exclude it
uses system
if [[ "${SYSTEM}" != "macos" ]]; then
LDFLAGS_ARRAY+=("-Wl,--as-needed")
fi
fi
elif [[ "${RELEASE}" == "debug" ]]; then
CFLAGS_ARRAY+=("-g" "-O1")
else
usage "The release type of ${RELEASE} is not allowed. Choose fast, small, or debug"
fi
}
function threads() {
uses system
if [[ "${THREADS}" != "auto" ]]; then
if [[ "${THREADS}" -lt 1 || "${THREADS}" -gt 256 ]]; then
usage "The number of threads, ${THREADS}, needs to be between 1 and 256, or don't set it at all"
fi
else
if [[ -n "${NUMBER_OF_PROCESSORS:-}" && "${NUMBER_OF_PROCESSORS}" -gt 0 ]]; then
THREADS="${NUMBER_OF_PROCESSORS}"
elif [[ "${SYSTEM}" == "macos" ]]; then
THREADS="$(sysctl -n hw.physicalcpu || echo 4)"
elif exists nproc; then
THREADS="$(nproc)"
else
THREADS=4 # if auto-detection fails fallback to a reasonable
# number of logical CPUs for 2019
fi
fi
}
function fdo_flags() {
if [[ "${FDO}" != "true" ]]; then
return
fi
uses compiler_type
local fdo_file="${SRC_PATH}/scripts/profile-data/${COMPILER}.profile"
if [[ ! -f "${fdo_file}" ]]; then
error "The Feedback-Directed Optimization file provided (${fdo_file}) does not exist or could not be accessed"
fi
if [[ "${COMPILER}" == "gcc" ]]; then
# Don't let GCC 6.x and under use both FDO and LTO
uses compiler_version
if [[ ( "${COMPILER_VERSION}" == "unset"
&& "$(2>&1 gcc -v | grep -Po '(?<=version )[^.]+')" -lt "7"
|| "${COMPILER_VERSION}" -lt "7" )
&& "${LTO}" == "true" ]]; then
error "GCC versions 6 and under cannot handle FDO and LTO simultaneously; please change one or more these."
fi
CFLAGS_ARRAY+=("-fauto-profile=${fdo_file}")
elif [[ "${COMPILER}" == "clang" ]]; then
CFLAGS_ARRAY+=("-fprofile-sample-use=${fdo_file}")
fi
}
function lto_flags() {
if [[ "${LTO}" != "true" ]]; then
return
fi
uses system
# Only allow LTO on Linux and MacOS; it currently fails under Windows
if [[ "${SYSTEM}" == "msys2" ]]; then
usage "LTO currently does not link or build on Windows with GCC or Clang"
fi
uses compiler_type
if [[ "${COMPILER}" == "gcc" ]]; then
CFLAGS_ARRAY+=("-flto")
# The linker performs the code optimizations across all objects, and therefore
# needs the same flags as the compiler would normally get
LDFLAGS_ARRAY+=("${CFLAGS_ARRAY[@]}")
# GCC on MacOS fails to parse the thread flag, so we only provide it under Linux
# (error: unsupported argument 4 to option flto=)
if [[ "${SYSTEM}" == "linux" ]]; then
uses threads
LDFLAGS_ARRAY+=("-flto=$THREADS")
fi
elif [[ "${COMPILER}" == "clang" ]]; then
CFLAGS_ARRAY+=("-flto=thin")
# Clang LTO on Linux is incompatible with -Os so replace them with -O2
# (ld: error: Optimization level must be between 0 and 3)
if [[ "${SYSTEM}" == "linux" ]]; then
CFLAGS_ARRAY=("${CFLAGS_ARRAY[@]/-Os/-O2}")
fi # clang-linux-lto-small exclusion
fi # gcc & clang
}
function configure_options() {
uses system
if [[ "${MACHINE}" != *"86"* ]]; then
CONFIGURE_OPTIONS+=("--disable-dynamic-x86" "--disable-fpu-x86" "--disable-fpu-x64")
fi
}
function do_autogen() {
uses src_path
if [[ ! -f autogen.sh ]]; then
error "autogen.sh doesn't exist in our current directory $PWD. If your DOSBox source is somewhere else set it with --src-path"
fi
# Only autogen if needed ..
if [[ ! -f configure ]]; then
uses bin_path
./autogen.sh
fi
}
function do_configure() {
uses bin_path
uses src_path
uses tools_and_flags
uses release_flags
uses fdo_flags
uses lto_flags
uses check_build_tools
uses configure_options
# Convert our arrays into space-delimited strings
LIBS=$( printf "%s " "${LIBS_ARRAY[@]}")
CFLAGS=$( printf "%s " "${CFLAGS_ARRAY[@]}")
CXXFLAGS=$(printf "%s " "${CFLAGS_ARRAY[@]}")
LDFLAGS=$( printf "%s " "${LDFLAGS_ARRAY[@]}")
local lto_string=""
if [[ "${LTO}" == "true" ]]; then
lto_string="-LTO"
fi
local fdo_string=""
if [[ "${FDO}" == "true" ]]; then
fdo_string="-FDO"
fi
echo ""
echo "Launching with:"
echo ""
echo " CC = ${CC}"
echo " CXX = ${CXX}"
echo " LD = ${LD}"
echo " AR = ${AR}"
echo " RANLIB = ${RANLIB}"
echo " CFLAGS = ${CFLAGS}"
echo " CXXFLAGS = ${CXXFLAGS}"
echo " LIBS = ${LIBS}"
echo " LDFLAGS = ${LDFLAGS}"
echo " THREADS = ${THREADS}"
echo ""
echo "Build type: ${SYSTEM}-${MACHINE}-${BITS}bit-${COMPILER}-${RELEASE}${lto_string}${fdo_string}"
echo ""
"${CC}" --version
sleep 5
if [[ ! -f configure ]]; then
error "configure script doesn't exist in $PWD. If the source is somewhere else, set it with --src-path"
elif ! ./configure "${CONFIGURE_OPTIONS[@]}"; then
>&2 cat "config.log"
error "configure failed, see config.log output above"
fi
}
function executable() {
uses src_path
EXECUTABLE="src/"
if [[ "${SYSTEM}" == "msys2" ]]; then
EXECUTABLE+="dosbox.exe"
else
EXECUTABLE+="dosbox"
fi
if [[ ! -f "${EXECUTABLE}" ]]; then
error "${EXECUTABLE} does not exist or hasn't been created yet"
fi
}
function build() {
uses src_path
uses bin_path
uses threads
if [[ "${CLEAN}" == "true" && -f "Makefile" ]]; then
make clean 2>&1 | tee -a build.log
fi
do_autogen
do_configure
make -j "${THREADS}" 2>&1 | tee -a build.log
}
function strip_binary() {
if [[ "${RELEASE}" == "debug" ]]; then
echo "[skipping strip] Debug symbols will be left in the binary because it's a debug release"
else
uses bin_path
uses executable
strip "${EXECUTABLE}"
fi
}
function show_binary() {
uses bin_path
uses system
uses executable
if [[ "$SYSTEM" == "macos" ]]; then
otool -L "${EXECUTABLE}"
else
ldd "${EXECUTABLE}"
fi
ls -1lh "${EXECUTABLE}"
}
function main() {
parse_args "$@"
build
strip_binary
show_binary
}
main "$@"

View file

@ -25,7 +25,6 @@ from bs4 import BeautifulSoup
#
MAX_ISSUES = 99
def summary_values(summary_table):
if not summary_table:
return

View file

@ -23,7 +23,7 @@ import sys
# then script will return with status 1. Simply change this line if you
# want to set a different limit.
#
MAX_ISSUES = 375
MAX_ISSUES = 420
# For recognizing warnings in GCC format in stderr:
#

View file

@ -0,0 +1,298 @@
#!/bin/bash
##
# Copyright (c) 2019 Kevin R. Croft
# SPDX-License-Identifier: GPL-2.0-or-later
#
# This script lists DOSBox package dependencies as determined by the runtime
# architecture, operating system, and selected compiler type and and its version.
#
# See the usage block below for details or run it with the -h or --help arguments.
#
# In general, this script adheres to Google's shell scripting style guide
# (https://google.github.io/styleguide/shell.xml), however some deviations (such as
# tab indents instead of two-spaces) are used to fit with DOSBox's in-practice"
# coding style.
#
set -euo pipefail
IFS=$'\n\t'
function usage() {
if [ -n "${1}" ]; then
errcho "${1}"
fi
local script
script=$(basename "${0}")
echo "Usage: ${script} [-b 32|64] [-c gcc|clang] [-f linux|macos|msys2] [-o FILE] [-u #]"
echo ""
echo " FLAG Description Default"
echo " ----------------------- ----------------------------------------------------- -------"
echo " -b, --bit-depth Build a 64 or 32 bit binary [$(print_var "${BITS}")]"
echo " -c, --compiler Choose either gcc or clang [$(print_var "${COMPILER}")]"
echo " -f, --force-system Force the system to be linux, macos, or msys2 [$(print_var "${SYSTEM}")]"
echo " -o, --output-file <file> Write the packages to a text file instead of stdout [$(print_var "${OUTPUT_FILE}")]"
echo " -u, --compiler-version # Use a specific compiler version (ie: 9 -> gcc-9) [$(print_var "${COMPILER_VERSION}")]"
echo " -v, --version Print the version of this script [$(print_var "${SCRIPT_VERSION}")]"
echo " -h, --help Print this usage text"
echo ""
echo "Example: ${script} --bit-depth 32 --compiler clang --compiler-version 8"
echo ""
echo "Note: the last value will take precendent if duplicate flags are provided."
exit 1
}
# parse params
function parse_args() {
defaults
while [[ "${#}" -gt 0 ]]; do case ${1} in
-b|--bit-depth) BITS="${2}"; shift;shift;;
-c|--compiler) COMPILER="${2}"; shift;shift;;
-f|--force-system) SYSTEM="${2}"; shift;shift;;
-o|--output-file) OUTPUT_FILE="${2}"; shift;shift;;
-u|--compiler-version) COMPILER_VERSION="${2}";shift;shift;;
-v|--version) print_version; shift;;
-h|--help) usage "Show usage"; shift;;
*) usage "Unknown parameter: ${1}"; shift;shift;;
esac; done
}
function defaults() {
# variables that are directly set via user arguments
BITS="64"
COMPILER="gcc"
COMPILER_VERSION="unset"
OUTPUT_FILE="unset"
SYSTEM="auto"
# derived variables with initial values
VERSION_POSTFIX=""
MACHINE="unset"
CALL_CACHE=("")
# read-only strings
readonly SCRIPT_VERSION="0.1"
readonly REPO_URL="https://github.com/dreamer/dosbox-staging"
}
function errcho() {
local CLEAR='\033[0m'
local RED='\033[0;91m'
>&2 echo ""
>&2 echo -e " ${RED}👉 ${*}${CLEAR}" "\\n"
}
function bug() {
local CLEAR='\033[0m'
local YELLOW='\033[0;33m'
>&2 echo -e " ${YELLOW}Please report the following at ${REPO_URL}${CLEAR}"
errcho "${@}"
exit 1
}
function error() {
errcho "${@}"
exit 1
}
function print_var() {
if [[ -z "${1}" ]]; then
echo "unset"
else
echo "${1}"
fi
}
function uses() {
# assert
if [[ "${#}" != 1 ]]; then
bug "The 'uses' function was called without an argument"
fi
# only handles function calls, so filter everything else
func="${1}"
if [[ "$(type -t "${func}")" != "function" ]]; then
bug "The 'uses' function was passed ${func}, which isn't a function"
fi
local found_in_previous="false"
# has our function already been called?
for previous_func in "${CALL_CACHE[@]}"; do
if [[ "${previous_func}" == "${func}" ]]; then
found_in_previous="true"
break
fi
done
# if it hasn't, record it and run it
if [[ "${found_in_previous}" == "false" ]]; then
CALL_CACHE+=("${func}")
"${func}"
fi
}
function print_version() {
echo "${SCRIPT_VERSION}"
exit 0
}
function packages() {
# only proceed if the user wants to install packages
uses system
if [[ "${OUTPUT_FILE}" != "unset" ]]; then
"packages_for_${SYSTEM}" > "${OUTPUT_FILE}"
else
"packages_for_${SYSTEM}"
fi
}
function packages_for_macos() {
uses compiler_type
uses compiler_version
local compiler_package="" # for brew, the clang package doesn't exist, so stay empty in this case (?)
if [[ "${COMPILER}" == "gcc" ]]; then
compiler_package="gcc"
if [[ "${COMPILER_VERSION}" != "unset" ]]; then
compiler_package+="@${COMPILER_VERSION}"
fi
fi
# Typical installation:
# - brew update
# - brew install <list of packages>
local packages=(
"${compiler_package}"
coreutils
autogen
autoconf
automake
pkg-config
libpng
sdl
sdl_net
opusfile
speexdsp )
echo "${packages[@]}"
}
function packages_for_msys2() {
uses bits
local pkg_type=""
if [[ "${BITS}" == 64 ]]; then
pkg_type="x86_64"
else
pkg_type="i686"
fi
uses compiler_type
uses compiler_version
local compiler_package="${COMPILER}"
compiler_package+="${VERSION_POSTFIX}"
# Typical installation step:
# pacman -S --noconfirm <list of packages>
local packages=(
autogen
autoconf
base-devel
automake-wrapper
"mingw-w64-${pkg_type}-pkg-config"
"mingw-w64-${pkg_type}-${compiler_package}"
"mingw-w64-${pkg_type}-libtool"
"mingw-w64-${pkg_type}-libpng"
"mingw-w64-${pkg_type}-zlib"
"mingw-w64-${pkg_type}-SDL"
"mingw-w64-${pkg_type}-SDL_net"
"mingw-w64-${pkg_type}-opusfile"
"mingw-w64-${pkg_type}-speexdsp" )
echo "${packages[@]}"
}
function packages_for_linux() {
# TODO:
# Convert this into an associative map between package
# managers and the list of respective package names. We
# should have coverage for the major distribution types,
# such as:
# - RPM-based (RHEL/CentOS, Fedora, and openSUSE)
# - Debian-based (Debian, Ubuntu, and Raspbian)
# - pacman-based (Arch and Manjero)
#
uses compiler_type
local compiler_package=""
if [[ "${COMPILER}" == "gcc" ]]; then
compiler_package="g++"
else
compiler_package="clang"
fi
uses compiler_version
compiler_package+="${VERSION_POSTFIX}"
# Typically install step
# sudo apt update -y
# sudo apt install -y <list of packages>
local packages=(
"${compiler_package}"
libtool
build-essential
libsdl1.2-dev
libsdl-net1.2-dev
libopusfile-dev
libspeexdsp-dev )
echo "${packages[@]}"
}
function system() {
if [[ "${MACHINE}" == "unset" ]]; then
MACHINE="$(uname -m)"
fi
if [[ "${SYSTEM}" == "auto" ]]; then
SYSTEM="$(uname -s)"
fi
if [[ "${SYSTEM}" == "Darwin" \
|| "${SYSTEM}" == "macos" ]]; then
SYSTEM="macos"
elif [[ "${SYSTEM}" == "MSYS"* \
|| "${SYSTEM}" == "msys2" \
|| "${SYSTEM}" == "MINGW"* ]]; then
SYSTEM="msys2"
elif [[ "${SYSTEM}" == "Linux" \
|| "${SYSTEM}" == "linux" ]]; then
SYSTEM="linux"
else
error "Your system, ${SYSTEM}, is not currently supported"
fi
}
function bits() {
if [[ "${BITS}" != 64 && "${BITS}" != 32 ]]; then
usage "A bit-depth of ${BITS} is not allowed; choose 64 or 32"
fi
}
function compiler_type() {
if [[ "${COMPILER}" != "gcc" && "${COMPILER}" != "clang" ]]; then
usage "The choice of compiler (${COMPILER}) is not valid; choose gcc or clang"
fi
}
function compiler_version() {
if [[ "${COMPILER_VERSION}" != "unset" ]]; then
VERSION_POSTFIX="-${COMPILER_VERSION}"
fi
}
function main() {
parse_args "$@"
packages
}
main "$@"