Skip to content

Linux GCC

Linux GCC #193

#
# File: %linux-gcc-build.yml
#
#=============================================================================#
#
# This does Linux builds on GitHub's Ubuntu container, using gcc.
#
#====# PLEASE READ THE README #===============================================#
#
# Whenever this file says "See README", that is referring to the notes in the
# %.github/workflows/README.md file. If something appears in multiple GitHub
# Workflow files, it's best to document it there instead of repeating it:
#
# https://github.com/metaeducation/ren-c/blob/master/.github/workflows/README.md
#
name: Linux GCC
# See README: When To Trigger Builds
#
on:
push:
branches: [
# master,
linux # pushing to linux won't build other workflows, use to debug
]
pull_request:
branches: [
master
]
workflow_dispatch: # Allows running this workflow manually from Actions tab
# Standardize to use bash on all platforms.
#
# See README: Using The Strict Erroring Bash Shell
#
defaults:
run:
shell: bash
# Each "Job" runs in its own VM, and a workflow run is made up of one or more
# jobs that can run sequentially or in parallel.
#
# See README: Jobs
#
jobs:
linux-gcc-build: # Name of this workflow's only job
# https://github.com/actions/virtual-environments#available-environments
#
# We want to build on the oldest available ubuntu, because GLIBC from
# newer Ubuntus won't work on older ones.
#
# !!! Consider usage of BUILD-ANYWHERE toolchain for better compatibility:
#
# https://github.com/theopolis/build-anywhere
#
runs-on: ubuntu-20.04
# See README: Build Matrix
#
strategy:
matrix:
include:
- os-id: 0.4.40 # 64-bit Target (built on this 64-bit platform)
config-file: generic.r
standard: gnu99 # used for sigjmp_buf (signal safety)
debug: none
extensions: ""
variation: ""
- os-id: 0.4.40 # 64-bit Target (built on this 64-bit platform)
config-file: generic.r
standard: gnu99 # used for sigjmp_buf (signal safety)
debug: normal
extensions: "ODBC +"
variation: "-debug" # !!! Maybe -debug-odbc ?
- os-id: 0.4.4 # 32-bit Target (built on this 64-bit platform)
config-file: generic-c++.r
standard: c++17 # c++11 is "default", no option for it
debug: normal
extensions: "" # TBD: ODBC for 32-bit?
variation: ""
# See README: Environment Variables
#
env:
AWS_S3_BUCKET_NAME: metaeducation
# See README: Minimize GitHub-Specific Syntax
#
OS_ID: ${{ matrix.os-id }}
CONFIG_FILE: ${{ matrix.config-file }}
STANDARD: ${{ matrix.standard }}
DEBUG: ${{ matrix.debug }}
EXTENSIONS: ${{ matrix.extensions }}
VARIATION: ${{ matrix.variation }}
# Steps are a sequence of tasks that will be executed within a single VM
# as part of the job.
#
# See README: Steps
#
steps: # (no indentatation needed below; so indent the minimum!)
#====# CHECKOUT STEPS #=====================================================#
# https://github.com/actions/checkout
#
# See README: Checkout Action
#
- uses: actions/checkout@v3 # See README: Trusted Actions
# The full commit is passed to make to build into the binary, and the
# abbreviated commit is used to name the executable.
#
# See README: Portably Capturing Git Hashes
#
- name: Grab Git Hash and Short Hash Into Environment Variables
run: |
git_commit="$(git show --format="%H" --no-patch)"
git_commit_short="$(git show --format="%h" --no-patch)"
echo "GIT_COMMIT=$git_commit" >> $GITHUB_ENV
echo "GIT_COMMIT_SHORT=$git_commit_short" >> $GITHUB_ENV
#====# TOOLCHAIN INSTALLATION STEPS #=======================================#
# !!! Ideally this would use the same step that clients can use to build
# the system with `make.sh`. Unfortunately, something about the GitHub
# Ubuntus do not like the old bootstrap executable. Make sure the
# ordinary path works, but for the moment patch over it just to get
# to a point where the action works.
#
- name: Fetch R3 To Use For "Prep" Build Steps as $R3MAKE
run: |
repo_dir=$(pwd)/
source tools/bash/fetch-prebuilt.sh
r3make=$(fetch_prebuilt)
echo "R3MAKE is set to $r3make"
echo "But that executable won't run on GitHub for some reason"
# "$r3make" --do "print {TESTING 1 2 3}" # NOT WORKING, dunno why
cd prebuilt
wget http://hostilefork.com/media/shared/github/r3-linux-8994d23-patched
chmod +x r3-linux-8994d23-patched
r3make=$(pwd)/r3-linux-8994d23-patched
echo "So now R3MAKE is $r3make"
echo "R3MAKE=$r3make" >> $GITHUB_ENV # pass to next step
- name: Stop the build early if the R3MAKE is no good
run: |
"$R3MAKE" --do "print {R3MAKE is Working} quit"
# GCC can build 32-bit targets on a 64-bit host, but it needs multilib
# (otherwise fatal error: bits/c++config.h: No such file or directory)
#
- name: Get Multilib If Cross-Compiling
if: env.OS_ID == '0.4.4'
run: |
sudo apt install gcc-multilib
sudo apt install g++-multilib
# The ODBC executable is built with debug included, to make the workflow
# that uses it for testing ODBC more rigorous.
#
- name: Get ODBC if Needed
if: (env.OS_ID == '0.4.40') && (env.DEBUG == 'normal')
run: |
sudo apt install unixodbc-dev
# Show a little bit of sanity check information.
#
- name: Output System Information
run: |
echo "GCC version check:"
gcc -v
#====# BUILD STEPS #========================================================#
# See README: {Braces} For %make.r String Parameters
#
- name: Use Rebmake to Generate a makefile
run: |
mkdir build
cd build
"$R3MAKE" ../make.r \
config="../configs/$CONFIG_FILE" \
target=makefile \
standard=$STANDARD \
os_id=$OS_ID \
debug=$DEBUG \
git_commit="{$GIT_COMMIT}" \
rigorous=no \
static=no \
extensions="$EXTENSIONS"
- name: Create Folders For Build Products (Compiler Won't Create Them)
run: |
cd build
make folders
- name: Prep the Build By Making Various Auto-Generated .h and .c Files
run: |
cd build
make prep
# https://github.com/actions/upload-artifact
#
- name: Optional Download of Prep Files Before They Can Cause Build Failure
if: false # Change this to true to download a file
uses: actions/upload-artifact@v2 # See README: Trusted Actions
with:
name: tmp-internals.h
path: build/prep/include/tmp-internals.h
- name: Compile and Link the C Files to into R3BUILT
run: |
cd build
make -j 2 # Linux GitHub Runners have 2 cores, use 2 jobs
echo "R3BUILT=$(pwd)/r3" >> $GITHUB_ENV
# See README: Ren-C Code As Step
#
- name: Copy Built R3 To Where It Can Be Used As A Shell
run: |
sudo cp build/r3 /usr/bin/r3built
#====# TESTING STEPS #======================================================#
- name: Basic Smoke Test (Print A Message And Quit)
run: |
"$R3BUILT" --do "print {hi}"
# Besides just testing success cases, it's important to make sure failures
# actually report bad exit codes, or a lot of the GitHub Actions intended
# for testing will be useless.
#
# Since GitHub Actions spawns the shell as `bash -e` this means any errors
# will terminate the step. Use `set +e` to disable this mode...as trying
# to capture the exit code without raising an error is a nuisance.
- name: FAIL Test (from code on command line)
run: |
set +e # so nonzero exit codes won't immediately terminate step
"$R3BUILT" --do "fail {Error Message}"
if [ $? -eq 1 ]; then
echo "FAIL Properly Gave Exit Status 1"
else
echo "Expected Exit Status 1, But Got $?"
exit 1
fi
- name: FAIL Test (from running a script)
run: |
set +e # so nonzero exit codes won't immediately terminate step
"$R3BUILT" tests/misc/fail-script.r
if [ $? -eq 1 ]; then
echo "FAIL Properly Gave Exit Status 1"
else
echo "Expected Exit Status 1, But Got $?"
exit 1
fi
- name: QUIT Test (from code on command line)
run: |
set +e # so nonzero exit codes won't immediately terminate step
"$R3BUILT" --do "quit/with 3"
if [ $? -eq 3 ]; then
echo "QUIT Properly Gave Exit Status 3"
else
echo "Expected Exit Status 3, But Got $?"
exit 1
fi
- name: QUIT Test (from running a script)
run: |
set +e # so nonzero exit codes won't immediately terminate step
"$R3BUILT" tests/misc/quit-script.r
if [ $? -eq 3 ]; then
echo "QUIT Properly Gave Exit Status 3"
else
echo "Expected Exit Status 3, But Got $?"
exit 1
fi
- name: Check Time Matches
shell: r3built --fragment {0} # See README: Ren-C Code As Step
run: |
; Because the two times are (by necessity) captured at different
; moments, we don't bother checking that the seconds line up (this is
; more about making sure the coarse time and time zones are consistent
; with the system). But still, freak cases can happen where you catch
; it on something like a minute turnover. Address this just by doing
; the process twice, and assume it's diminishingly rare to fail twice.
;
repeat 2 [
r3time: now
print ["R3 Time reported as:" r3time]
call/shell/output {date --iso-8601=seconds} unixtime: copy {}
print ["UNIX Time (date --iso-8601) reported as:" unixtime]
parse unixtime [
year: between <here> "-" (year: to integer! year)
month: between <here> "-" (month: to integer! month)
day: between <here> "T" (day: to integer! day)
time: across to ["-" | "+"] (time: to time! time)
zone: between <here> newline (zone: to time! zone)
]
all [
year = r3time.year
month = r3time.month
day = r3time.day
time.hour = r3time.hour
time.minute = r3time.minute
; Don't check seconds, likely different moments of capture
zone = r3time.zone
]
then [
print "Times matched!"
quit/with 0
]
]
fail "Times Did Not Match"
- name: HTTPS Read Test (If This Works, A Lot Of Things Are Working)
shell: r3built --fragment {0} # See README: Ren-C Code As Step
run: |
print {== Hello From R3 HTTPS Read Test! ==}
header: parse as text! read https://example.com [
thru '<h1> accept across to '</h1>
]
assert [header = "Example Domain"]
print ["Succeeded:" header]
#====# DEPLOY STEPS #=======================================================#
# This action configures the AWS keys stored in GitHub's "Secrets" for
# the repository so that `aws s3` allows us to do uploads, without needing
# to publish any passwords publicly:
#
# https://github.com/aws-actions/configure-aws-credentials
#
# See README: Trusted Actions
#
- name: Configure AWS Credentials
if: github.ref == 'refs/heads/master' # see notes on DEPLOY STEPS
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.METAEDUCATION_AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.METAEDUCATION_AWS_SECRET_KEY }}
aws-region: us-east-1
# Name the executable based on the abbreviated commit, whether it is a
# debug or release build, and if it was built using C++ or not. Note that
# the C++ debug builds have additional runtime checks in the debug
# build...though there should not be any impact on the release build.
# (Though there may be additional DLL dependencies regardless.)
#
# !!! All Ren-C stakeholders should be using debug builds at this time.
#
- name: Deploy Executable
if: github.ref == 'refs/heads/master' # see notes on DEPLOY STEPS
run: |
cd build
NEW_NAME="r3-${GIT_COMMIT_SHORT}${VARIATION}"
MIME_TYPE="" # e.g. "--content-type application/wasm"
local=r3
lastpart=travis-builds/${OS_ID}/${NEW_NAME}
remote=s3://${AWS_S3_BUCKET_NAME}/$lastpart
aws s3 cp $local $remote $MIME_TYPE
echo "R3_URL_LASTPART=$lastpart" >> $GITHUB_ENV
- name: Greenlight Build
if: github.ref == 'refs/heads/master' # see notes on DEPLOY STEPS
run: |
cd build
local=last-deploy.short-hash
# -n option to echo means "no newline at end" (it's not a "text file"
# so there is no standard enforcing that it have one...and it's
# easier in the client to not have it)
#
echo -n "${GIT_COMMIT_SHORT}" > $local
remote=s3://${AWS_S3_BUCKET_NAME}/travis-builds/${OS_ID}/$local
aws s3 cp $local $remote # upload
- name: Test That LATEST-OF Script Gives Back The Just-Greenlit Build
if: github.ref == 'refs/heads/master'
shell: r3built --fragment {0} # See README: Ren-C Code As Step
run: |
latest-of: do %scripts/latest-of.reb
os-id: to tuple! get-env 'OS_ID
variation: if "-debug" = get-env 'VARIATION ['debug] else ['release]
r3-url-lastpart: get-env 'R3_URL_LASTPART
url: latest-of/variant os-id variation
parse (as text! url) [thru r3-url-lastpart] except [
fail ["!!! LATEST-OF Gave Mismatched URL:" url]
]
print ["LATEST-OF Matched:" url]
#====# BOOTSTRAP STEP #=====================================================#
# We should check for bootstrap capability