mirror of
https://github.com/boostorg/url.git
synced 2025-05-09 01:13:53 +00:00
ci: set up cpp-actions matrix
This commit is contained in:
parent
fd72f3fce1
commit
381033202c
137
.github/actions/b2_workflow/action.yml
vendored
137
.github/actions/b2_workflow/action.yml
vendored
@ -1,137 +0,0 @@
|
||||
name: 'B2 Workflow'
|
||||
description: 'This action runs a complete B2 workflow from source files'
|
||||
inputs:
|
||||
source-dir:
|
||||
description: 'The boost source directory.'
|
||||
required: false
|
||||
default: '.'
|
||||
build-variant:
|
||||
description: 'Custom build variants.'
|
||||
required: false
|
||||
default: ''
|
||||
modules:
|
||||
description: 'The list of modules we should test.'
|
||||
required: true
|
||||
default: ''
|
||||
gcc_toolchain:
|
||||
description: 'Create a special GCC toolchain for this version of GCC and update user-config.jam'
|
||||
required: false
|
||||
default: ''
|
||||
toolset:
|
||||
description: 'Toolset name.'
|
||||
required: false
|
||||
default: ''
|
||||
address-model:
|
||||
description: 'Valid b2 list of address models.'
|
||||
required: false
|
||||
default: ''
|
||||
cxx:
|
||||
description: 'Path to C++ compiler.'
|
||||
required: false
|
||||
default: ''
|
||||
cxxflags:
|
||||
description: 'Extra compiler flags.'
|
||||
required: false
|
||||
default: ''
|
||||
linkflags:
|
||||
description: 'Extra linker flags.'
|
||||
required: false
|
||||
default: ''
|
||||
cxxstd:
|
||||
description: 'List of standards with which cmake will build and test the program.'
|
||||
required: false
|
||||
default: ''
|
||||
ubsan:
|
||||
description: 'List of standards with which cmake will build and test the program.'
|
||||
required: false
|
||||
default: 'false'
|
||||
threading:
|
||||
description: 'b2 threading option.'
|
||||
required: false
|
||||
default: ''
|
||||
trace-commands:
|
||||
description: 'Trace commands executed by the workflow.'
|
||||
required: false
|
||||
default: 'false'
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Get CPU cores
|
||||
uses: SimenB/github-actions-cpu-cores@v1
|
||||
id: cpu-cores
|
||||
|
||||
- name: Bootstrap
|
||||
working-directory: ${{ inputs.source-dir }}
|
||||
shell: bash
|
||||
run: |
|
||||
${{ (inputs.trace-commands == 'true' && 'set -xe') || '' }}
|
||||
./bootstrap.sh
|
||||
./b2 headers
|
||||
|
||||
- name: Setup GCC Toolchain
|
||||
if: ${{ inputs.gcc_toolchain }}
|
||||
shell: bash
|
||||
run: |
|
||||
${{ (inputs.trace-commands == 'true' && 'set -xe') || '' }}
|
||||
# Create dir for toolchain
|
||||
GCC_TOOLCHAIN_ROOT="$HOME/gcc-toolchain"
|
||||
mkdir -p "$GCC_TOOLCHAIN_ROOT"
|
||||
echo "GCC_TOOLCHAIN_ROOT=\"$GCC_TOOLCHAIN_ROOT\"" >> $GITHUB_ENV
|
||||
|
||||
# Create symlinks for compiler into the toolchain dir
|
||||
MULTIARCH_TRIPLET="$(dpkg-architecture -qDEB_HOST_MULTIARCH)"
|
||||
ln -s /usr/include "$GCC_TOOLCHAIN_ROOT/include"
|
||||
ln -s /usr/bin "$GCC_TOOLCHAIN_ROOT/bin"
|
||||
mkdir -p "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET"
|
||||
ln -s "/usr/lib/gcc/$MULTIARCH_TRIPLET/${{inputs.gcc_toolchain}}" "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET/${{inputs.gcc_toolchain}}"
|
||||
|
||||
# Write toolchain data to ~/user-config.jam
|
||||
if [ -n "${{ inputs.cxx }}" -o -n "$GCC_TOOLCHAIN_ROOT" ]; then
|
||||
echo -n "using ${{inputs.toolset}} : : ${{inputs.cxx}}" > ~/user-config.jam
|
||||
if [ -n "$GCC_TOOLCHAIN_ROOT" ]; then
|
||||
echo -n " : <compileflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\" <linkflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\"" >> ~/user-config.jam
|
||||
fi
|
||||
echo " ;" >> ~/user-config.jam
|
||||
fi
|
||||
|
||||
- name: Setup user-config.jam
|
||||
if: ${{ !inputs.gcc_toolchain }}
|
||||
shell: bash
|
||||
run: |
|
||||
${{ (inputs.trace-commands == 'true' && 'set -xe') || '' }}
|
||||
if [ -n "${{ inputs.cxx }}" -o -n "$GCC_TOOLCHAIN_ROOT" ]; then
|
||||
echo -n "using ${{ inputs.toolset }} : : ${{ inputs.cxx }}" > ~/user-config.jam
|
||||
if [ -n "$GCC_TOOLCHAIN_ROOT" ]
|
||||
then
|
||||
echo -n " : <compileflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\" <linkflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\"" >> ~/user-config.jam
|
||||
fi
|
||||
echo " ;" >> ~/user-config.jam
|
||||
fi
|
||||
|
||||
- name: B2 Workflow
|
||||
working-directory: ${{ inputs.source-dir }}
|
||||
shell: bash
|
||||
run: |
|
||||
${{ (inputs.trace-commands == 'true' && 'set -xe') || '' }}
|
||||
|
||||
B2_ARGS+=(${{ (steps.cpu-cores.outputs.count != '1' && format('"-j" "{0}"', steps.cpu-cores.outputs.count)) || '' }})
|
||||
B2_ARGS+=(${{ (inputs.toolset && format('"toolset={0}"', inputs.toolset)) || '' }})
|
||||
B2_ARGS+=(${{ (inputs.address-model && format('"address-model={0}"', inputs.address-model)) || '' }})
|
||||
B2_ARGS+=(${{ (inputs.cxxstd && format('"cxxstd={0}"', inputs.cxxstd)) || '' }})
|
||||
B2_ARGS+=(${{ (inputs.build-variant && format('"variant={0}"', inputs.build-variant)) || '' }})
|
||||
B2_ARGS+=(${{ (inputs.threading && format('"threading={0}"', inputs.threading)) || '' }})
|
||||
${{ (inputs.ubsan == 'true' && 'export UBSAN_OPTIONS="print_stacktrace=1"') || '' }}
|
||||
B2_ARGS+=(${{ (inputs.ubsan == 'true' && '"cxxflags=-fsanitize=undefined -fno-sanitize-recover=undefined" "linkflags=-fsanitize=undefined -fuse-ld=gold" "define=UBSAN=1" "debug-symbols=on" "visibility=global"') || '' }})
|
||||
B2_ARGS+=(${{ (inputs.cxxflags && format('"cxxflags={0}"', inputs.cxxflags)) || '' }})
|
||||
B2_ARGS+=(${{ (inputs.linkflags && format('"linkflags={0}"', inputs.linkflags)) || '' }})
|
||||
|
||||
modules="${{ inputs.modules }}"
|
||||
for module in ${modules//,/ }
|
||||
do
|
||||
B2_ARGS+=("libs/$module/test")
|
||||
done
|
||||
|
||||
set -x
|
||||
./b2 "${B2_ARGS[@]}"
|
||||
set +x
|
314
.github/actions/boost_clone/action.yml
vendored
314
.github/actions/boost_clone/action.yml
vendored
@ -1,314 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com)
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# Official repository: https://github.com/CPPAlliance/url
|
||||
#
|
||||
|
||||
name: 'Boost Clone'
|
||||
description: 'This workflow clones the boost source directory, attempting to get it from the cache first'
|
||||
inputs:
|
||||
boost_dir:
|
||||
description: 'The boost directory. The default value assumes boost is in-source.'
|
||||
required: false
|
||||
default: 'boost'
|
||||
branch:
|
||||
description: 'Branch of the super-project'
|
||||
required: false
|
||||
default: 'master'
|
||||
patches:
|
||||
description: 'Libraries used to patch the boost installation'
|
||||
required: true
|
||||
default: ''
|
||||
modules:
|
||||
description: 'The boost submodules we need to clone'
|
||||
required: false
|
||||
default: ''
|
||||
scan-modules-dir:
|
||||
description: 'An independent directory we should scan for boost dependencies to clone'
|
||||
required: false
|
||||
default: ''
|
||||
scan-modules-ignore:
|
||||
description: 'List of modules that should be ignored in scan-modules'
|
||||
required: false
|
||||
default: ''
|
||||
trace-commands:
|
||||
description: 'Trace commands executed by the workflow.'
|
||||
required: false
|
||||
default: 'false'
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Find python
|
||||
shell: bash
|
||||
id: find-python
|
||||
if: inputs.scan-modules-dir != ''
|
||||
run: |
|
||||
# Looking for python
|
||||
${{ (inputs.trace-commands == 'true' && 'set -xe') || '' }}
|
||||
if command -v python3 &> /dev/null; then
|
||||
python_path="$(which python3)"
|
||||
elif command -v python &> /dev/null; then
|
||||
python_version_output=$(python --version)
|
||||
regex='[0-9]+\.[0-9]+\.[0-9]+'
|
||||
[[ $python_version_output =~ $regex ]]
|
||||
python_version=${BASH_REMATCH[0]}
|
||||
IFS='.' read -r -a version_components <<< "$python_version"
|
||||
major_version=${version_components[0]}
|
||||
if [ "$major_version" -lt 3 ]; then
|
||||
echo "Python $python_version found." >&2
|
||||
echo "Please install Python 3!" >&2
|
||||
else
|
||||
python_path="$(which python)"
|
||||
fi
|
||||
else
|
||||
echo "Cannot Python 3!" >&2
|
||||
fi
|
||||
if [ "$python_path" != "" ]; then
|
||||
$python_path --version
|
||||
echo "python_path=$python_path" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- uses: actions/setup-python@v4
|
||||
if: inputs.scan-modules-dir != '' && !steps.find-python.outputs.python_path
|
||||
id: setup-python
|
||||
with:
|
||||
python-version: '3.10'
|
||||
|
||||
- name: Scan Required Boost Modules
|
||||
if: inputs.scan-modules-dir != ''
|
||||
id: scan-modules
|
||||
shell: bash
|
||||
run: |
|
||||
# Scan ${{ inputs.scan-modules-dir }}
|
||||
${{ (inputs.trace-commands == 'true' && 'set -xe') || '' }}
|
||||
source_dir="${{ inputs.scan-modules-dir }}"
|
||||
if [[ $source_dir != /* ]]; then
|
||||
source_dir="$(readlink -f "$source_dir" 2>/dev/null || realpath -e "$source_dir" 2>/dev/null || echo "$(pwd)/$source_dir")"
|
||||
fi
|
||||
|
||||
python_path="${{ steps.find-python.outputs.python_path || steps.setup-python.outputs.python-path }}"
|
||||
|
||||
# Go to action path to find the script and aux files
|
||||
# https://github.com/actions/runner/issues/716
|
||||
cd "$GITHUB_ACTION_PATH"
|
||||
|
||||
# Pre-cache the files scan_deps needs for scanning
|
||||
if command -v curl &> /dev/null; then
|
||||
curl -o "${{ inputs.branch }}.gitmodules" "https://raw.githubusercontent.com/boostorg/boost/${{ inputs.branch }}/.gitmodules"
|
||||
curl -o "${{ inputs.branch }}.exceptions.txt" "https://raw.githubusercontent.com/boostorg/boostdep/${{ inputs.branch }}/depinst/exceptions.txt"
|
||||
elif command -v wget &> /dev/null; then
|
||||
wget -O "${{ inputs.branch }}.gitmodules" "https://raw.githubusercontent.com/boostorg/boost/${{ inputs.branch }}/.gitmodules"
|
||||
wget -O "${{ inputs.branch }}.exceptions.txt" "https://raw.githubusercontent.com/boostorg/boostdep/${{ inputs.branch }}/depinst/exceptions.txt"
|
||||
else
|
||||
# Let scan_deps download the files
|
||||
$python_path -m pip install requests
|
||||
fi
|
||||
ls
|
||||
|
||||
# Run scan_deps on the reference directory
|
||||
set -e
|
||||
modules=$($python_path scan_deps.py --dir "$source_dir" --branch ${{ inputs.branch }} ${{ inputs.scan-modules-ignore && format('--ignore {0}', inputs.scan-modules-ignore) }})
|
||||
python_exit_code=$?
|
||||
set -e
|
||||
if [ $python_exit_code -ne 0 ]; then
|
||||
echo "Error: Scan deps failed with exit code $python_exit_code"
|
||||
modules=""
|
||||
fi
|
||||
echo "modules=$modules" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Environment
|
||||
id: ctx
|
||||
shell: bash
|
||||
run: |
|
||||
# Determine cache key for boost
|
||||
${{ (inputs.trace-commands == 'true' && 'set -xe') || '' }}
|
||||
boost_hash=$(git ls-remote https://github.com/boostorg/boost.git ${{ inputs.branch }} | awk '{ print $1 }')
|
||||
echo "boost_hash=$boost_hash" >> $GITHUB_OUTPUT
|
||||
|
||||
# Merge input modules and scanned modules
|
||||
all_modules=""
|
||||
input_modules="${{ inputs.modules }}"
|
||||
scanned_modules="${{ steps.scan-modules.outputs.modules }}"
|
||||
for module in ${input_modules//,/ }
|
||||
do
|
||||
module_basename=${module##*/}
|
||||
all_modules="$all_modules $module_basename"
|
||||
done
|
||||
for module in ${scanned_modules// / }
|
||||
do
|
||||
module_basename=${module##*/}
|
||||
all_modules="$all_modules $module_basename"
|
||||
done
|
||||
echo "all_modules=$all_modules" >> $GITHUB_OUTPUT
|
||||
|
||||
# Find wget or curl
|
||||
if command -v curl &> /dev/null; then
|
||||
curl_executable="curl"
|
||||
fi
|
||||
if command -v wget &> /dev/null; then
|
||||
wget_executable="wget"
|
||||
fi
|
||||
|
||||
# Add modules hashes to boost cache key
|
||||
cache_hash=""
|
||||
if command -v sha1sum >/dev/null 2>&1; then
|
||||
has_sha1sum=true
|
||||
else
|
||||
has_sha1sum=false
|
||||
fi
|
||||
for module in ${all_modules// / }
|
||||
do
|
||||
module_basename=${module##*/}
|
||||
|
||||
# Ensure the module repo exists so git doesn't fail later on
|
||||
module_repo_exists=false
|
||||
if [ -n "$curl_executable" ]; then
|
||||
module_repo_exists=$(curl --silent --fail --head https://github.com/boostorg/$module_basename >/dev/null && echo "true" || echo "false")
|
||||
elif [ -n "$wget_executable" ]; then
|
||||
module_repo_exists=$(wget --quiet --spider https://github.com/boostorg/$module_basename && echo "true" || echo "false")
|
||||
fi
|
||||
|
||||
# Get a hash for the module
|
||||
if [ "$module_repo_exists" == "true" ]; then
|
||||
module_hash=$(git ls-remote https://github.com/boostorg/$module_basename.git ${{ inputs.branch }} | awk '{ print $1 }')
|
||||
else
|
||||
module_hash=$boost_hash
|
||||
fi
|
||||
|
||||
# Update the cache key with a hash for the module only
|
||||
# We only invalidate the cache if one of the modules has changed.
|
||||
# Changing only the boost super-project won't invalidate the cache
|
||||
if [ "$cache_hash" == "" ]; then
|
||||
cache_hash=$module_hash
|
||||
else
|
||||
concatenated_string="${cache_hash}${module_hash}"
|
||||
if [ "$has_sha1sum" == "true" ]; then
|
||||
cache_hash=$(echo -n "${concatenated_string}" | sha1sum | awk '{print $1}')
|
||||
else
|
||||
cache_hash=$(echo -n "${concatenated_string}" | shasum -a 1 | awk '{print $1}')
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Add patch names and hashes to hash
|
||||
patches=${{ inputs.patches }}
|
||||
for patch in ${patches//,/ }
|
||||
do
|
||||
patch_hash=$(git ls-remote $patch ${{ inputs.branch }} | awk '{ print $1 }')
|
||||
if [ "cache_hash" == "" ]; then
|
||||
cache_hash=$patch_hash
|
||||
else
|
||||
concatenated_string="${cache_hash}${patch_hash}"
|
||||
if [ "$has_sha1sum" == "true" ]; then
|
||||
cache_hash=$(echo -n "${concatenated_string}" | sha1sum | awk '{print $1}')
|
||||
else
|
||||
cache_hash=$(echo -n "${concatenated_string}" | shasum -a 1 | awk '{print $1}')
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# If there are no modules, then we update the cache key with the boost-hash
|
||||
# as we are about to clone all modules
|
||||
# cache_os=${{ runner.os }}
|
||||
# cache_os="$(echo "$cache_os" | tr '[:upper:]' '[:lower:]')"
|
||||
if [ "cache_hash" == "" ]; then
|
||||
# cache_hash=$cache_os-boost-all-$boost_hash
|
||||
cache_hash=boost-source-all-$boost_hash
|
||||
else
|
||||
# cache_hash=$cache_os-boost-$cache_hash
|
||||
cache_hash=boost-source-$cache_hash
|
||||
fi
|
||||
echo "cache_hash=$cache_hash" >> $GITHUB_OUTPUT
|
||||
|
||||
# absolute cache directory
|
||||
working_dir="$(pwd)"
|
||||
boost_dir="${{ inputs.boost_dir }}"
|
||||
if [[ $boost_dir != /* ]]; then
|
||||
boost_dir="$(readlink -f "$boost_dir" 2>/dev/null || realpath -e "$boost_dir" 2>/dev/null || echo "$working_dir/$boost_dir")"
|
||||
fi
|
||||
echo "boost_dir=$boost_dir" >> $GITHUB_OUTPUT
|
||||
|
||||
# Attempt to get boost with the specified modules from the cache before cloning it
|
||||
- name: boost cache
|
||||
id: cache-boost
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.ctx.outputs.boost_dir }}
|
||||
key: ${{ steps.ctx.outputs.cache_hash }}
|
||||
|
||||
# Clone boost if not found in cache
|
||||
- name: boost clone
|
||||
if: steps.cache-boost.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
git clone https://github.com/boostorg/boost.git -b ${{ inputs.branch }} "${{ inputs.boost_dir }}"
|
||||
|
||||
# Apply patches if boost not found in cache
|
||||
- name: boost patches
|
||||
if: steps.cache-boost.outputs.cache-hit != 'true' && inputs.patches != ''
|
||||
shell: bash
|
||||
working-directory: ${{ inputs.boost_dir }}/libs
|
||||
run: |
|
||||
# Apply boost patches ${{ inputs.patches }}
|
||||
patches=${{ inputs.patches }}
|
||||
for patch in ${patches//,/ }
|
||||
do
|
||||
git clone $patch -b ${{ inputs.branch }}
|
||||
done
|
||||
|
||||
- name: Get CPU cores
|
||||
uses: SimenB/github-actions-cpu-cores@v1
|
||||
id: cpu-cores
|
||||
|
||||
# Initialize all submodules if boost not found in cache and no specific modules were specified
|
||||
- name: Initialize all submodules
|
||||
if: (steps.cache-boost.outputs.cache-hit != 'true' && steps.ctx.outputs.all_modules == '')
|
||||
working-directory: ${{ inputs.boost_dir }}
|
||||
shell: bash
|
||||
run: |
|
||||
# Update all boost submodules
|
||||
git submodule update --depth 1 --jobs ${{ steps.cpu-cores.outputs.count }}--init --recursive
|
||||
|
||||
# Initialize specified submodules if boost not found in cache and submodules were specified
|
||||
- name: Initialize specified submodules
|
||||
if: (steps.cache-boost.outputs.cache-hit != 'true' && steps.ctx.outputs.all_modules != '')
|
||||
working-directory: ${{ inputs.boost_dir }}
|
||||
shell: bash
|
||||
run: |
|
||||
# Scan transitive dependencies and update submodules
|
||||
${{ (inputs.trace-commands == 'true' && 'set -xe') || '' }}
|
||||
git submodule update --depth 1 -q --init tools/boostdep
|
||||
# Run boostdep for required modules: ${{ steps.ctx.outputs.all_modules }}
|
||||
|
||||
# Initialize each explicitly specified module
|
||||
modules="${{ steps.ctx.outputs.all_modules }}"
|
||||
for module in ${modules// / }
|
||||
do
|
||||
echo "Initialize submodule $module"
|
||||
git submodule update --depth 1 --jobs ${{ steps.cpu-cores.outputs.count }} -q --init libs/$module || true
|
||||
done
|
||||
|
||||
# Initialize dependencies of each explicitly specified module
|
||||
python_path="${{ steps.find-python.outputs.python_path || steps.setup-python.outputs.python-path }}"
|
||||
python_exit_code=0
|
||||
for module in ${modules// / }
|
||||
do
|
||||
echo "Run boostdep for required module $module"
|
||||
set +e
|
||||
$python_path tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools --include source --git_args "--jobs ${{ steps.cpu-cores.outputs.count }} --depth 1" $module
|
||||
python_exit_code=$?
|
||||
set -e
|
||||
if [ $python_exit_code -ne 0 ]; then
|
||||
echo "Error: Boostdep failed with exit code $python_exit_code"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $python_exit_code -ne 0 ]; then
|
||||
echo "Boostdep failed. Initializing all modules..."
|
||||
git submodule update --depth 1 --jobs ${{ steps.cpu-cores.outputs.count }}--init --recursive
|
||||
fi
|
220
.github/actions/boost_clone/scan_deps.py
vendored
220
.github/actions/boost_clone/scan_deps.py
vendored
@ -1,220 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#
|
||||
# Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com)
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# Official repository: https://github.com/CPPAlliance/url
|
||||
#
|
||||
|
||||
# Adapted from boostorg/boostdep/blob/develop/depinst/depinst.py
|
||||
|
||||
# depinst.py - installs the dependencies needed to test
|
||||
# a Boost library
|
||||
#
|
||||
# Copyright 2016-2020 Peter Dimov
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
# The difference between this script and depinst.py is that depinst.py
|
||||
# is intended to clone the dependencies of other boost modules, while
|
||||
# this script is only intended to find what modules should be cloned
|
||||
# for a library that depends on boost needs to work.
|
||||
|
||||
# The intention of the script is to determine what modules should be
|
||||
# cloned *before* boost is cloned, thus allowing us to determine if
|
||||
# we can use cached results.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import re
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
|
||||
verbose = 0
|
||||
|
||||
|
||||
def vprint(level, *args):
|
||||
if verbose >= level:
|
||||
print(*args)
|
||||
|
||||
|
||||
def is_module(m, gm):
|
||||
return ('libs/' + m) in gm
|
||||
|
||||
|
||||
def module_for_header(h, x, gm):
|
||||
if h in x:
|
||||
return x[h]
|
||||
else:
|
||||
# boost/function.hpp
|
||||
m = re.match('boost/([^\\./]*)\\.h[a-z]*$', h)
|
||||
|
||||
if m and is_module(m.group(1), gm):
|
||||
return m.group(1)
|
||||
|
||||
# boost/numeric/conversion.hpp
|
||||
m = re.match('boost/([^/]*/[^\\./]*)\\.h[a-z]*$', h)
|
||||
|
||||
if m and is_module(m.group(1), gm):
|
||||
return m.group(1)
|
||||
|
||||
# boost/numeric/conversion/header.hpp
|
||||
m = re.match('boost/([^/]*/[^/]*)/', h)
|
||||
|
||||
if m and is_module(m.group(1), gm):
|
||||
return m.group(1)
|
||||
|
||||
# boost/function/header.hpp
|
||||
m = re.match('boost/([^/]*)/', h)
|
||||
|
||||
if m and is_module(m.group(1), gm):
|
||||
return m.group(1)
|
||||
|
||||
vprint(0, 'Cannot determine module for header', h)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def scan_header_dependencies(f, exceptions, submodule_paths):
|
||||
deps = set()
|
||||
for line in f:
|
||||
m = re.match('[ \t]*#[ \t]*include[ \t]*["<](boost/[^">]*)[">]', line)
|
||||
if m:
|
||||
h = m.group(1)
|
||||
mod = module_for_header(h, exceptions, submodule_paths)
|
||||
deps.add(mod)
|
||||
return deps
|
||||
|
||||
|
||||
def scan_directory(d, exceptions, submodule_paths):
|
||||
vprint(1, 'Scanning directory', d)
|
||||
|
||||
if os.name == 'nt' and sys.version_info[0] < 3:
|
||||
d = unicode(d)
|
||||
|
||||
deps = set()
|
||||
for root, dirs, files in os.walk(d):
|
||||
for file in files:
|
||||
fn = os.path.join(root, file)
|
||||
vprint(2, 'Scanning file', fn)
|
||||
if sys.version_info[0] < 3:
|
||||
with open(fn, 'r') as f:
|
||||
deps.update(scan_header_dependencies(f, exceptions, submodule_paths))
|
||||
else:
|
||||
with open(fn, 'r', encoding='latin-1') as f:
|
||||
deps.update(scan_header_dependencies(f, exceptions, submodule_paths))
|
||||
return deps
|
||||
|
||||
|
||||
def list_boost_dependencies(dir, subdirs, exceptions, submodule_paths):
|
||||
vprint(1, 'Scanning dir', dir)
|
||||
deps = set()
|
||||
for subdir in subdirs:
|
||||
deps.update(scan_directory(os.path.join(dir, subdir), exceptions, submodule_paths))
|
||||
return deps
|
||||
|
||||
|
||||
def read_exceptions(branch):
|
||||
# exceptions.txt is the output of "boostdep --list-exceptions"
|
||||
vprint(1, 'Reading exceptions.txt')
|
||||
x = {}
|
||||
module = None
|
||||
|
||||
exceptions_path = os.path.join(os.path.dirname(sys.argv[0]), branch + '.exceptions.txt')
|
||||
if not os.path.exists(exceptions_path):
|
||||
import requests
|
||||
url = "https://raw.githubusercontent.com/boostorg/boostdep/" + branch + "/depinst/exceptions.txt"
|
||||
response = requests.get(url)
|
||||
if response.status_code == 200:
|
||||
content = response.text
|
||||
with open(exceptions_path, "w") as f:
|
||||
f.write(content)
|
||||
|
||||
with open(exceptions_path, 'r') as f:
|
||||
for line in f:
|
||||
line = line.rstrip()
|
||||
m = re.match('(.*):$', line)
|
||||
if m:
|
||||
module = m.group(1).replace('~', '/')
|
||||
else:
|
||||
header = line.lstrip()
|
||||
x[header] = module
|
||||
return x
|
||||
|
||||
|
||||
def read_gitmodules(branch):
|
||||
vprint(1, 'Reading .gitmodules')
|
||||
gm = []
|
||||
|
||||
gitmodules_path = os.path.join(os.path.dirname(sys.argv[0]), branch + '.gitmodules')
|
||||
if not os.path.exists(gitmodules_path):
|
||||
import requests
|
||||
url = "https://raw.githubusercontent.com/boostorg/boost/" + branch + "/.gitmodules"
|
||||
response = requests.get(url)
|
||||
if response.status_code == 200:
|
||||
content = response.text
|
||||
with open(gitmodules_path, "w") as f:
|
||||
f.write(content)
|
||||
|
||||
with open(gitmodules_path, 'r') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
m = re.match('path[ \t]*=[ \t]*(.*)$', line)
|
||||
if m:
|
||||
gm.append(m.group(1))
|
||||
|
||||
return gm
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description='Installs the dependencies needed to test a Boost library.')
|
||||
|
||||
parser.add_argument('--dir', help="directory to scan")
|
||||
parser.add_argument('--branch', help="boost branch", default='master')
|
||||
|
||||
parser.add_argument('-I', '--include', help="additional subdirectory to scan; can be repeated", metavar='DIR',
|
||||
action='append', default=[])
|
||||
parser.add_argument('-X', '--exclude',
|
||||
help="exclude a default subdirectory ('include', 'src', or 'test') from scan; can be repeated",
|
||||
metavar='DIR', action='append', default=[])
|
||||
parser.add_argument('-N', '--ignore', help="exclude top-level dependency even when found in scan; can be repeated",
|
||||
metavar='LIB', action='append', default=[])
|
||||
parser.add_argument('-v', '--verbose', help='enable verbose output', action='count', default=0)
|
||||
parser.add_argument('-q', '--quiet', help='quiet output (opposite of -v)', action='count', default=0)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
verbose = args.verbose - args.quiet
|
||||
|
||||
vprint(2, '-X:', args.exclude)
|
||||
vprint(2, '-I:', args.include)
|
||||
vprint(2, '-N:', args.ignore)
|
||||
|
||||
exceptions = read_exceptions(args.branch)
|
||||
vprint(2, 'Exceptions:', exceptions)
|
||||
|
||||
submodule_paths = read_gitmodules(args.branch)
|
||||
vprint(2, '.gitmodules:', submodule_paths)
|
||||
|
||||
subdirs = ['include', 'src', 'source', 'test', 'tests', 'example', 'examples']
|
||||
for subdir in args.exclude:
|
||||
if subdir in subdirs:
|
||||
subdirs.remove(subdir)
|
||||
for subdir in args.include:
|
||||
if subdir not in subdirs:
|
||||
subdirs.append(subdir)
|
||||
vprint(1, 'Directories to scan:', *subdirs)
|
||||
|
||||
modules = list_boost_dependencies(args.dir, subdirs, exceptions, submodule_paths)
|
||||
for ignored in args.ignore:
|
||||
if ignored in modules:
|
||||
modules.remove(ignored)
|
||||
|
||||
sorted_modules = sorted(modules)
|
||||
print(' '.join(sorted_modules))
|
534
.github/actions/cmake_workflow/action.yml
vendored
534
.github/actions/cmake_workflow/action.yml
vendored
@ -1,534 +0,0 @@
|
||||
name: 'CMake Workflow'
|
||||
description: 'This action runs a complete CMake workflow from source files'
|
||||
inputs:
|
||||
source-dir:
|
||||
description: 'Directory for the source files.'
|
||||
required: false
|
||||
default: '.'
|
||||
build-dir:
|
||||
description: 'Directory for the binaries relative to the source directory.'
|
||||
required: false
|
||||
default: 'build'
|
||||
cmake-min-version:
|
||||
description: 'The minimum cmake version for this workflow. If the existing version is below that, the action attempts to update CMake.'
|
||||
required: false
|
||||
default: '3.5'
|
||||
cmake_exec:
|
||||
description: 'The cmake executable'
|
||||
required: false
|
||||
default: 'cmake'
|
||||
cc:
|
||||
description: 'Path to C compiler.'
|
||||
required: false
|
||||
default: ''
|
||||
cxx:
|
||||
description: 'Path to C++ compiler.'
|
||||
required: false
|
||||
default: ''
|
||||
cxxstd:
|
||||
description: 'List of standards with which cmake will build and test the program.'
|
||||
required: false
|
||||
default: ''
|
||||
toolchain:
|
||||
description: 'Path to toolchain.'
|
||||
required: false
|
||||
default: ''
|
||||
generator:
|
||||
description: 'Generator name.'
|
||||
required: false
|
||||
default: ''
|
||||
build-type:
|
||||
description: 'Build type.'
|
||||
required: false
|
||||
default: 'Release'
|
||||
build-target:
|
||||
description: 'Targets to build instead of the default target'
|
||||
required: false
|
||||
default: ''
|
||||
install-prefix:
|
||||
description: 'Path where the library should be installed.'
|
||||
required: false
|
||||
default: '.local/usr'
|
||||
run-tests:
|
||||
description: 'Whether we should run tests.'
|
||||
required: false
|
||||
default: 'true'
|
||||
install:
|
||||
description: 'Whether we should install the library.'
|
||||
required: false
|
||||
default: 'true'
|
||||
extra-args:
|
||||
description: 'Extra arguments to cmake configure command.'
|
||||
required: false
|
||||
default: ''
|
||||
create-annotations:
|
||||
description: 'Create github annotations on errors.'
|
||||
required: false
|
||||
default: 'true'
|
||||
ref-source-dir:
|
||||
description: 'A reference source directory for annotations.'
|
||||
required: false
|
||||
default: ''
|
||||
trace-commands:
|
||||
description: 'Trace commands executed by the workflow.'
|
||||
required: false
|
||||
default: 'false'
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Get CPU cores
|
||||
uses: SimenB/github-actions-cpu-cores@v1
|
||||
id: cpu-cores
|
||||
|
||||
- name: Setup msvc dev-cmd
|
||||
if: runner.os == 'Windows'
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
|
||||
- name: CMake Features
|
||||
shell: bash
|
||||
id: version
|
||||
working-directory: ${{ inputs.source_dir }}
|
||||
run: |
|
||||
${{ (inputs.trace-commands == 'true' && 'set -xe') || '' }}
|
||||
|
||||
# Extract cmake min version
|
||||
cmake_min_version=${{ inputs.cmake-min-version }}
|
||||
IFS='.' read -r -a version_components <<< "$cmake_min_version"
|
||||
major_min_version=${version_components[0]}
|
||||
minor_min_version=${version_components[1]:-0}
|
||||
patch_min_version=${version_components[2]:-0}
|
||||
cmake_min_version="$major_min_version.$minor_min_version.$patch_min_version"
|
||||
|
||||
# Extract cmake current version
|
||||
cmake_version_output=$(cmake --version)
|
||||
# extract the version number using a regular expression
|
||||
regex='[0-9]+\.[0-9]+\.[0-9]+'
|
||||
[[ $cmake_version_output =~ $regex ]]
|
||||
cmake_version=${BASH_REMATCH[0]}
|
||||
IFS='.' read -r -a version_components <<< "$cmake_version"
|
||||
major_version=${version_components[0]}
|
||||
minor_version=${version_components[1]}
|
||||
patch_version=${version_components[2]}
|
||||
|
||||
# Check version requirements
|
||||
version_is_ge=false
|
||||
if [ "$major_version" -gt "$major_min_version" ]; then
|
||||
version_is_ge=true
|
||||
elif [ "$major_version" -lt "$major_min_version" ]; then
|
||||
version_is_ge=false
|
||||
else
|
||||
# major versions are equal, check minor versions
|
||||
if [ "$minor_version" -gt "$minor_min_version" ]; then
|
||||
version_is_ge=true
|
||||
elif [ "$minor_version" -lt "$minor_min_version" ]; then
|
||||
version_is_ge=false
|
||||
else
|
||||
# major and minor versions are equal, check patch versions
|
||||
if [ "$patch_version" -ge "$patch_min_version" ]; then
|
||||
version_is_ge=true
|
||||
else
|
||||
version_is_ge=false
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Update cmake if needed
|
||||
if [ "$version_is_ge" == "false" ]; then
|
||||
url_os=${{ runner.os }}
|
||||
url_os="$(echo "$url_os" | tr '[:upper:]' '[:lower:]')"
|
||||
if [ "$minor_min_version" -le "19" ]; then
|
||||
if [ "$url_os" == "windows" ]; then
|
||||
url_os="win${{ (runner.arch == 'X86' && '32') || '64' }}"
|
||||
elif [ "$url_os" == "linux" ]; then
|
||||
url_os="Linux"
|
||||
elif [ "$url_os" == "macos" ]; then
|
||||
if [ "$minor_min_version" -le "18" ]; then
|
||||
url_os="Darwin"
|
||||
elif [ "$patch_min_version" -le "2" ]; then
|
||||
url_os="Darwin"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
url_arch=${{ runner.arch }}
|
||||
url_arch="$(echo "$url_arch" | tr '[:upper:]' '[:lower:]')"
|
||||
if [ "$url_os" == "windows" ]; then
|
||||
url_arch="${{ (startswith(runner.arch, 'ARM') && 'arm64') || 'x86_64' }}"
|
||||
elif [ "$url_os" == "win32" ]; then
|
||||
url_arch="x86"
|
||||
elif [ "$url_os" == "win64" ]; then
|
||||
url_arch="x64"
|
||||
elif [ "$url_os" == "linux" ]; then
|
||||
url_arch="${{ (startswith(runner.arch, 'ARM') && 'aarch64') || 'x86_64' }}"
|
||||
elif [ "$url_os" == "Linux" ]; then
|
||||
url_arch="${{ (startswith(runner.arch, 'ARM') && 'aarch64') || 'x86_64' }}"
|
||||
elif [ "$url_os" == "macos" ]; then
|
||||
url_arch="universal"
|
||||
fi
|
||||
|
||||
url_extension="${{ (runner.os == 'Windows' && 'zip') || 'tar.gz' }}"
|
||||
|
||||
cmake_basename="cmake-$cmake_min_version-$url_os-$url_arch"
|
||||
cmake_filename="$cmake_basename.$url_extension"
|
||||
cmake_url="https://cmake.org/files/v$major_min_version.$minor_min_version/$cmake_filename"
|
||||
if command -v curl &> /dev/null; then
|
||||
curl -o "$cmake_filename" "$cmake_url"
|
||||
elif command -v wget &> /dev/null; then
|
||||
wget -O "$cmake_filename" "$cmake_url"
|
||||
fi
|
||||
|
||||
${{ (runner.os == 'Windows' && 'unzip $cmake_filename') || (inputs.trace-commands == 'true' && 'tar -xvf $cmake_filename') || 'tar -xf $cmake_filename' }}
|
||||
cmake_bin_path="$(pwd)/$cmake_basename/bin"
|
||||
echo "$cmake_bin_path" >> $GITHUB_PATH
|
||||
export PATH=$PATH:"$cmake_bin_path"
|
||||
$cmake_bin_path/cmake --version
|
||||
|
||||
cmake_version="$cmake_min_version"
|
||||
major_version="$major_min_version"
|
||||
minor_version="$minor_min_version"
|
||||
patch_version="$patch_min_version"
|
||||
fi
|
||||
|
||||
# Identify features
|
||||
if [ "$minor_version" -ge 13 ]; then
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "CMake version is greater than or equal to 3.13"') || '' }}
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "-B <path-to-build> syntax is supported"') || '' }}
|
||||
path_to_build=true
|
||||
else
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "CMake version is NOT greater than or equal to 3.13"') || '' }}
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "-B <path-to-build> syntax is NOT supported"') || '' }}
|
||||
path_to_build=false
|
||||
fi
|
||||
|
||||
if [ "$minor_version" -ge 12 ]; then
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "CMake version is greater than or equal to 3.12"') || '' }}
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "-j <threads> syntax is supported"') || '' }}
|
||||
parallel_build=true
|
||||
else
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "CMake version is NOT greater than or equal to 3.12"') || '' }}
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "-j <threads> syntax is NOT supported"') || '' }}
|
||||
parallel_build=false
|
||||
fi
|
||||
|
||||
if [ "$minor_version" -ge 15 ]; then
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "CMake version is greater than or equal to 3.15"') || '' }}
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "--target with multiple targets is supported"') || '' }}
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "cmake --install is supported"') || '' }}
|
||||
build_multiple_targets=true
|
||||
cmake_install=true
|
||||
else
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "CMake version is NOT greater than or equal to 3.15"') || '' }}
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "--target with multiple targets is NOT supported"') || '' }}
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "cmake --install is NOT supported"') || '' }}
|
||||
build_multiple_targets=false
|
||||
cmake_install=false
|
||||
fi
|
||||
|
||||
generator="${{ inputs.generator }}"
|
||||
if [ "$generator" == "" ]; then
|
||||
generator=$(cmake --system-information | sed -n 's/^CMAKE_GENERATOR [[:space:]]*"\([^"]*\)".*/\1/p')
|
||||
fi
|
||||
if [ "$generator" == "" ]; then
|
||||
generator=${{ ((runner.os == 'macOS') && '"XCode"') || ((runner.os == 'Windows') && '"Visual Studio"') || '"Unix Makefiles"' }}
|
||||
fi
|
||||
|
||||
if [[ $generator == "Visual Studio"* ]]; then
|
||||
generator_is_multi_config=true
|
||||
elif [ "$generator" == "Xcode" ]; then
|
||||
generator_is_multi_config=true
|
||||
elif [ "$generator" == "Ninja Multi-Config" ]; then
|
||||
generator_is_multi_config=true
|
||||
else
|
||||
generator_is_multi_config=false
|
||||
fi
|
||||
${{ (inputs.trace-commands == 'true' && 'if [ "$generator_is_multi_config" == "true" ]; then echo "Generator is multi-config"; fi') || '' }}
|
||||
|
||||
echo "cmake_version=$cmake_version" >> $GITHUB_OUTPUT
|
||||
echo "major_version=$major_version" >> $GITHUB_OUTPUT
|
||||
echo "minor_version=$minor_version" >> $GITHUB_OUTPUT
|
||||
echo "patch_version=$patch_version" >> $GITHUB_OUTPUT
|
||||
echo "cmake_min_version=$cmake_min_version" >> $GITHUB_OUTPUT
|
||||
echo "major_min_version=$major_min_version" >> $GITHUB_OUTPUT
|
||||
echo "minor_min_version=$minor_min_version" >> $GITHUB_OUTPUT
|
||||
echo "patch_min_version=$patch_min_version" >> $GITHUB_OUTPUT
|
||||
echo "path_to_build=$path_to_build" >> $GITHUB_OUTPUT
|
||||
echo "parallel_build=$parallel_build" >> $GITHUB_OUTPUT
|
||||
echo "build_multiple_targets=$build_multiple_targets" >> $GITHUB_OUTPUT
|
||||
echo "cmake_install=$cmake_install" >> $GITHUB_OUTPUT
|
||||
echo "generator_is_multi_config=$generator_is_multi_config" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: CMake Workflow
|
||||
shell: bash
|
||||
working-directory: ${{ inputs.source_dir }}
|
||||
run: |
|
||||
${{ (inputs.trace-commands == 'true' && 'set -xe') || '' }}
|
||||
|
||||
# compiler executables
|
||||
cc=${{ inputs.cc }}
|
||||
if [ "$cc" != "" ]; then
|
||||
if command -v $cc &> /dev/null; then
|
||||
cc="$(which $cc)"
|
||||
elif command -v /usr/bin/$cc &> /dev/null; then
|
||||
cc="/usr/bin/$cc"
|
||||
fi
|
||||
fi
|
||||
cxx=${{ inputs.cxx }}
|
||||
if [ "$cxx" != "" ]; then
|
||||
if command -v $cxx &> /dev/null; then
|
||||
cxx="$(which $cxx)"
|
||||
elif command -v /usr/bin/$cxx &> /dev/null; then
|
||||
cxx="/usr/bin/$cxx"
|
||||
fi
|
||||
fi
|
||||
|
||||
# std versions
|
||||
cxxstds=${{ inputs.cxxstd }}
|
||||
if [ "$cxxstds" == "" ]; then
|
||||
cxxstds="defaultcxx"
|
||||
fi
|
||||
main_cxxstd=${cxxstds##*,}
|
||||
|
||||
run_tests="${{ inputs.run-tests }}"
|
||||
if [ "$run_tests" == "true" ]; then
|
||||
cmake_enable_test_args="-D BUILD_TESTING=ON"
|
||||
fi
|
||||
|
||||
# absolute directories
|
||||
working_dir="$(pwd)"
|
||||
source_dir="${{ inputs.source-dir }}"
|
||||
if [[ $source_dir != /* ]]; then
|
||||
source_dir="$(readlink -f "$source_dir" 2>/dev/null || realpath -e "$source_dir" 2>/dev/null || echo "$working_dir/$source_dir")"
|
||||
fi
|
||||
|
||||
ref_source_dir="${{ inputs.ref-source-dir || inputs.source-dir }}"
|
||||
if [[ $ref_source_dir != /* ]]; then
|
||||
ref_source_dir="$(readlink -f "$ref_source_dir" 2>/dev/null || realpath -e "$ref_source_dir" 2>/dev/null || echo "$working_dir/$ref_source_dir")"
|
||||
fi
|
||||
|
||||
build_dir="${{ inputs.build-dir }}"
|
||||
if [[ $build_dir != /* ]]; then
|
||||
build_dir="$(readlink -f "$source_dir/$build_dir" 2>/dev/null || realpath -e "$source_dir/$build_dir" 2>/dev/null || echo "$source_dir/$build_dir")"
|
||||
fi
|
||||
|
||||
# iterate stds
|
||||
for cxxstd in ${cxxstds//,/ }
|
||||
do
|
||||
if [ "$cxxstd" != "defaultcxx" ]; then
|
||||
echo "==================================> C++$cxxstd"
|
||||
fi
|
||||
std_build_dir="$build_dir$( [ "$cxxstd" == "$main_cxxstd" ] && echo "" || echo "-$cxxstd" )"
|
||||
|
||||
# Configure step
|
||||
CONFIGURE_ARGS=(${{ (steps.version.outputs.path_to_build == 'true' && '"-S" "$source_dir" "-B" "$std_build_dir"') || '' }})
|
||||
CONFIGURE_ARGS+=(${{ (inputs.generator && format('"-G" "{0}"', inputs.generator)) || '' }})
|
||||
CONFIGURE_ARGS+=(${{ ((steps.version.outputs.generator_is_multi_config == 'false' && inputs.build-type) && format('"-D" "CMAKE_BUILD_TYPE={0}"', inputs.build-type)) || '' }})
|
||||
CONFIGURE_ARGS+=(${{ ((steps.version.outputs.generator_is_multi_config == 'true' && inputs.build-type) && format('"-D" "CMAKE_CONFIGURATION_TYPES={0}"', inputs.build-type)) || '' }})
|
||||
CONFIGURE_ARGS+=(${{ (inputs.toolchain && format('"-D" "CMAKE_TOOLCHAIN_FILE={0}"', inputs.toolchain)) || '' }})
|
||||
CONFIGURE_ARGS+=(${{ (inputs.toolchain && format('"-D" "CMAKE_TOOLCHAIN_FILE={0}"', inputs.toolchain)) || '' }})
|
||||
CONFIGURE_ARGS+=(${{ (inputs.install-prefix && format('"-D" "CMAKE_INSTALL_PREFIX={0}"', inputs.install-prefix)) || '' }})
|
||||
CONFIGURE_ARGS+=(${{ (inputs.run-tests && '"-D" "BUILD_TESTING=ON"') || '' }})
|
||||
CONFIGURE_ARGS+=(${{ (inputs.cc && '"-D" "CMAKE_C_COMPILER=$cc"') || '' }})
|
||||
CONFIGURE_ARGS+=(${{ (inputs.cxx && '"-D" "CMAKE_CXX_COMPILER=$cxx"') || '' }})
|
||||
CONFIGURE_ARGS+=($( [ "$cxxstd" == "defaultcxx" ] && echo "" || echo "-D CMAKE_CXX_STANDARD=$cxxstd" ))
|
||||
CONFIGURE_ARGS+=(${{ inputs.extra-args }})
|
||||
SOURCE_DIR_ARG=${{ (steps.version.outputs.path_to_build == 'false' && '"$source_dir"') || '' }}
|
||||
|
||||
mkdir "$std_build_dir" || true
|
||||
cd "$std_build_dir"
|
||||
set +e
|
||||
set -x
|
||||
cmake "${CONFIGURE_ARGS[@]}" $SOURCE_DIR_ARG 2>&1 | tee -a "$std_build_dir/cmake-configure-output.txt"
|
||||
${{ (inputs.trace-commands != 'true' && 'set +x') || '' }}
|
||||
cmake_exit_code=$?
|
||||
set -e
|
||||
cd "$working_dir"
|
||||
|
||||
# Configure step annotations
|
||||
if [[ ${{ inputs.create-annotations }} == "true" ]]; then
|
||||
cmake_regex="^CMake (Warning|Error)( at ([^:]+):([[:digit:]]+) \\(([^:]+)\\))?:(.*)"
|
||||
message_type=""
|
||||
lines=""
|
||||
while read line; do
|
||||
if [[ "$message_type" != "" ]]; then
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "$line"') || '' }}
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "$lines"') || '' }}
|
||||
lines="$lines\n$line"
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "$lines"') || '' }}
|
||||
if [[ "${lines: -4}" != "\n\n" ]]; then
|
||||
continue
|
||||
fi
|
||||
else
|
||||
if [[ $line == "CMake Error"* ]]; then
|
||||
message_type="error"
|
||||
lines="$line"
|
||||
continue
|
||||
elif [[ $line == "CMake Warning"* ]]; then
|
||||
message_type="warning"
|
||||
lines="$line"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "$lines"') || '' }}
|
||||
if [[ $lines =~ $cmake_regex ]]; then
|
||||
filename=${BASH_REMATCH[3]}
|
||||
if [ "$filename" != "" ]; then
|
||||
${{ runner.os != 'macOS' && 'filename="$(realpath -m --relative-to="$ref_source_dir" "$source_dir/$filename")"' }}
|
||||
fi
|
||||
line_number=${BASH_REMATCH[4]}
|
||||
error_type=${BASH_REMATCH[1]}
|
||||
error_code=${BASH_REMATCH[5]}
|
||||
error_message=${BASH_REMATCH[6]}
|
||||
error_message="${error_message:2}"
|
||||
error_message=$(echo $error_message | sed 's/....$//')
|
||||
error_message=$(echo "$error_message" | sed 's/:\\n\\n/: /g')
|
||||
error_message=$(echo "$error_message" | sed 's/.\\n/. /g')
|
||||
error_message=$(echo "$error_message" | sed 's/\\n/. /g')
|
||||
error_message=$(echo "$error_message" | sed 's/\n/. /g')
|
||||
if [ "$filename" == "" ]; then
|
||||
echo "::$message_type title:CMake-$error_type::CMake: $error_message"
|
||||
else
|
||||
echo "::$message_type file=$filename,line=$line_number,title:CMake-$error_type::CMake: $error_message"
|
||||
fi
|
||||
fi
|
||||
message_type=""
|
||||
lines=""
|
||||
done < "$std_build_dir/cmake-configure-output.txt"
|
||||
fi
|
||||
|
||||
if [[ $cmake_exit_code -ne 0 ]]; then
|
||||
echo "CMake configuration step failed with exit code $cmake_exit_code"
|
||||
false
|
||||
fi
|
||||
|
||||
# Build step
|
||||
set +e
|
||||
jobs_args="${{ (steps.version.outputs.parallel_build == 'false' && '') || format('-j {0}', steps.cpu-cores.outputs.count) }}"
|
||||
if [[ "${{ steps.version.outputs.build_multiple_targets }}" == "true" || "${{ inputs.build-target }}" != *" "* ]]; then
|
||||
set -x
|
||||
cmake --build "$std_build_dir" --config ${{ inputs.build-type }} $jobs_args ${{ (inputs.build-target != '' && format('--target {0}', inputs.build-target)) || '' }} 2>&1 | tee -a "$std_build_dir/cmake-build-output.txt"
|
||||
${{ (inputs.trace-commands != 'true' && 'set +x') || '' }}
|
||||
else
|
||||
build_targets="${{ inputs.build-target }}"
|
||||
for build_target in ${build_targets// / }; do
|
||||
set -x
|
||||
cmake --build "$std_build_dir" --config ${{ inputs.build-type }} $jobs_args --target $build_target 2>&1 | tee -a "$std_build_dir/cmake-build-output.txt"
|
||||
${{ (inputs.trace-commands != 'true' && 'set +x') || '' }}
|
||||
done
|
||||
fi
|
||||
cmake_exit_code=$?
|
||||
set -e
|
||||
|
||||
# Build step annotations
|
||||
if [[ ${{ inputs.create-annotations }} == "true" ]]; then
|
||||
msvc_regex="^([^\\(\\)]+)\\(([[:digit:]]+)\\): (warning|error) ([^:]+): (.*)$"
|
||||
gcc_clang_regex="^([^:]+):([[:digit:]]+):([[:digit:]]+)?: (warning|error):([^\\[]*)(\\[-W[A-Za-z0-9-]*\\])?$"
|
||||
while read line; do
|
||||
${{ (inputs.trace-commands == 'true' && 'echo "$line"') || '' }}
|
||||
if [[ "$line" =~ $gcc_clang_regex ]]; then
|
||||
filename=${BASH_REMATCH[1]}
|
||||
${{ runner.os != 'macOS' && 'filename="$(realpath -m --relative-to="$ref_source_dir" "$filename")"' }}
|
||||
if [[ $filename == ../* ]]; then
|
||||
continue
|
||||
fi
|
||||
error_type=${BASH_REMATCH[4]}
|
||||
line_number=${BASH_REMATCH[2]}
|
||||
column=${BASH_REMATCH[3]}
|
||||
title="Build Error"
|
||||
msg=""
|
||||
compiler="${{ inputs.cxx }}"
|
||||
if [ "$compiler" != "" ]; then
|
||||
compiler=$(basename $compiler)
|
||||
title="$title - $compiler"
|
||||
msg="$compiler"
|
||||
fi
|
||||
error_message=${BASH_REMATCH[5]}
|
||||
if [ "$msg" != "" ]; then
|
||||
msg="$msg: $error_message"
|
||||
else
|
||||
msg="$error_message"
|
||||
fi
|
||||
error_code=${BASH_REMATCH[6]}
|
||||
if [ "$error_code" != "" ]; then
|
||||
title="$title - $error_code"
|
||||
msg="$msg ($error_code)"
|
||||
fi
|
||||
echo "::$error_type file=$filename,line=$line_number,col:$column,title:$title::$msg"
|
||||
elif [[ "$line" =~ $msvc_regex ]]; then
|
||||
filename=${BASH_REMATCH[1]}
|
||||
${{ runner.os != 'macOS' && 'filename="$(realpath -m --relative-to="$ref_source_dir" "$filename")"' }}
|
||||
if [[ $filename == ../* ]]; then
|
||||
continue
|
||||
fi
|
||||
line_number=${BASH_REMATCH[2]}
|
||||
error_type=${BASH_REMATCH[3]}
|
||||
error_code=${BASH_REMATCH[4]}
|
||||
error_message=${BASH_REMATCH[5]}
|
||||
compiler="${{ inputs.cxx }}"
|
||||
if [ "$compiler" != ""]; then
|
||||
compiler=$(basename $compiler)
|
||||
fi
|
||||
echo "::$error_type file=$filename,line=$line_number,title:$compiler: $error_type $error_code::$compiler: $error_message ($error_type - $error_code)"
|
||||
fi
|
||||
done < "$std_build_dir/cmake-build-output.txt"
|
||||
fi
|
||||
|
||||
if [[ $cmake_exit_code -ne 0 ]]; then
|
||||
echo "CMake build step failed with exit code $cmake_exit_code"
|
||||
false
|
||||
fi
|
||||
|
||||
# Install step
|
||||
mkdir "${{ inputs.install-prefix }}" || true
|
||||
if [[ "${{ inputs.install }}" == true && "$cxxstd" == "$main_cxxstd" ]]; then
|
||||
if [[ ${{ steps.version.outputs.cmake_install }} == "true" ]]; then
|
||||
set -x
|
||||
cmake --install "$std_build_dir" --config ${{ inputs.build-type }} --prefix "${{ inputs.install-prefix }}" 2>&1 | tee -a "$std_build_dir/cmake-install-output.txt"
|
||||
${{ (inputs.trace-commands != 'true' && 'set +x') || '' }}
|
||||
else
|
||||
set -x
|
||||
cmake --build "$std_build_dir" --config ${{ inputs.build-type }} --target install || true 2>&1 | tee -a "$std_build_dir/cmake-install-output.txt"
|
||||
${{ (inputs.trace-commands != 'true' && 'set +x') || '' }}
|
||||
fi
|
||||
fi
|
||||
|
||||
# Test step
|
||||
if [[ "$run_tests" == true && "$cxxstd" == "$main_cxxstd" ]]; then
|
||||
set +e
|
||||
ctest --test-dir "$std_build_dir" $jobs_args -C ${{ inputs.build-type }} --no-tests=error --progress --output-on-failure 2>&1 | tee -a "$std_build_dir/cmake-test-output.txt"
|
||||
cmake_exit_code=$?
|
||||
set -e
|
||||
|
||||
# Test step annotations
|
||||
if [[ "${{ inputs.create-annotations }}" == true ]]; then
|
||||
boost_test_regex="^#[[:digit:]]+ ([^\\(\\)]+)\\(([[:digit:]]+)\\) failed: (.*)"
|
||||
while read line; do
|
||||
if [[ "$line" =~ $boost_test_regex ]]; then
|
||||
filename=${BASH_REMATCH[1]}
|
||||
if [ -e "$ref_source_dir/$filename" ]; then
|
||||
${{ runner.os != 'macOS' && 'filename="$(realpath -m --relative-to="$ref_source_dir" "$ref_source_dir/$filename")"' }}
|
||||
else
|
||||
test_filename=$(find "$ref_source_dir/test" -name "$filename" | head -n 1 | xargs)
|
||||
if [ "$test_filename" != "" ]; then
|
||||
${{ runner.os != 'macOS' && 'filename="$(realpath -m --relative-to="$ref_source_dir" "$test_filename")"' }}
|
||||
else
|
||||
ref_filename=$(find "$ref_source_dir" -name "$filename" | head -n 1 | xargs)
|
||||
if [ "$ref_filename" == "" ]; then
|
||||
${{ runner.os != 'macOS' && 'filename="$(realpath -m --relative-to="$ref_source_dir" "$ref_filename")"' }}
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
line_number=${BASH_REMATCH[2]}
|
||||
error_message=${BASH_REMATCH[3]}
|
||||
echo "::error file=$filename,line=$line_number,title:Boost.Test::Boost.Test: $error_message"
|
||||
fi
|
||||
done < "$std_build_dir/cmake-test-output.txt"
|
||||
fi
|
||||
|
||||
if [[ $cmake_exit_code -ne 0 ]]; then
|
||||
echo "CMake test step failed with exit code $cmake_exit_code"
|
||||
false
|
||||
fi
|
||||
fi
|
||||
done
|
206
.github/actions/package_install/action.yml
vendored
206
.github/actions/package_install/action.yml
vendored
@ -1,206 +0,0 @@
|
||||
name: 'Install dependencies'
|
||||
description: 'This actions installs dependencies from multiple package managers for a workflow'
|
||||
inputs:
|
||||
vcpkg:
|
||||
description: 'List of packages we should install with vcpkg. (Whitespace-separated)'
|
||||
required: false
|
||||
default: ''
|
||||
apt-get:
|
||||
description: 'List of packages we should install with apt-get. (Whitespace-separated)'
|
||||
required: false
|
||||
default: ''
|
||||
|
||||
vcpkg_triplet:
|
||||
description: 'The triplet used by vcpkg to install packages.'
|
||||
required: false
|
||||
default: ''
|
||||
vcpkg_dir:
|
||||
description: 'The directory where vcpkg should be cloned and installed.'
|
||||
required: false
|
||||
default: 'vcpkg'
|
||||
vcpkg_branch:
|
||||
description: 'vcpkg branch we should use'
|
||||
required: false
|
||||
default: 'master'
|
||||
|
||||
apt-get-retries:
|
||||
description: 'Number of time we should retry when apt-get fails.'
|
||||
required: false
|
||||
default: '1'
|
||||
apt-get-sources:
|
||||
description: 'List of sources for apt-get.'
|
||||
required: false
|
||||
default: ''
|
||||
apt-get-source-keys:
|
||||
description: 'List of source keys for apt-get.'
|
||||
required: false
|
||||
default: ''
|
||||
apt-get-ignore-missing:
|
||||
description: 'Whether apt-get should ignore missing packages.'
|
||||
required: false
|
||||
default: 'false'
|
||||
|
||||
|
||||
outputs:
|
||||
vcpkg_toolchain:
|
||||
description: "vcpkg toolchain file"
|
||||
value: ${{ steps.ctx.outputs.vcpkg_toolchain }}
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
# Install packages on ubuntu
|
||||
# https://docs.github.com/en/actions/learn-github-actions/contexts#runner-context
|
||||
- name: apt-get packages
|
||||
shell: bash
|
||||
if: ${{ runner.os == 'Linux' && inputs.apt-get }}
|
||||
run: |
|
||||
set -xe
|
||||
|
||||
# Determine if apt-get should be called with `sudo`, which is often not the case with containers
|
||||
if which sudo >/dev/null 2>&1; then
|
||||
sudo -n apt-get -o Acquire::Retries=${{ inputs.apt-get-retries }} update > /dev/null 2>&1
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
sudo_prefix="sudo "
|
||||
else
|
||||
sudo_prefix=""
|
||||
fi
|
||||
else
|
||||
sudo_prefix=""
|
||||
fi
|
||||
|
||||
# Install sources
|
||||
SOURCE_KEYS=(${{ inputs.apt-get-source-keys }})
|
||||
for key in "${SOURCE_KEYS[@]}"
|
||||
do
|
||||
for i in {1..$NET_RETRY_COUNT}
|
||||
do
|
||||
wget -O - "$key" | sudo apt-key add - && break || sleep 2
|
||||
done
|
||||
done
|
||||
|
||||
SOURCES=(${{ inputs.apt-get-sources }})
|
||||
if [ ${#SOURCES[@]} -gt 0 ]
|
||||
then
|
||||
APT_ADD_REPO_COMMON_ARGS=("-y")
|
||||
APT_ADD_REPO_HAS_SOURCE_ARGS=0
|
||||
SOFTWARE_PROPERTIES_VERSION="$(dpkg-query --showformat='${Version}' --show software-properties-common)"
|
||||
if dpkg --compare-versions "$SOFTWARE_PROPERTIES_VERSION" ge "0.96.24.20"
|
||||
then
|
||||
APT_ADD_REPO_COMMON_ARGS+=("-n")
|
||||
fi
|
||||
if dpkg --compare-versions "$SOFTWARE_PROPERTIES_VERSION" ge "0.98.10"
|
||||
then
|
||||
APT_ADD_REPO_HAS_SOURCE_ARGS=1
|
||||
fi
|
||||
for source in "${SOURCES[@]}"
|
||||
do
|
||||
for i in {1..$NET_RETRY_COUNT}
|
||||
do
|
||||
APT_ADD_REPO_ARGS=("${APT_ADD_REPO_COMMON_ARGS[@]}")
|
||||
if [ $APT_ADD_REPO_HAS_SOURCE_ARGS -ne 0 ]
|
||||
then
|
||||
case "$source" in
|
||||
"ppa:"*)
|
||||
APT_ADD_REPO_ARGS+=("-P")
|
||||
;;
|
||||
"deb "*)
|
||||
APT_ADD_REPO_ARGS+=("-S")
|
||||
;;
|
||||
*)
|
||||
APT_ADD_REPO_ARGS+=("-U")
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
APT_ADD_REPO_ARGS+=("$source")
|
||||
$sudo_prefix -E apt-add-repository "${APT_ADD_REPO_ARGS[@]}" && break || sleep 2
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
# Update and install
|
||||
$sudo_prefix apt-get -o Acquire::Retries=${{ inputs.apt-get-retries }} update
|
||||
if [ "${{ inputs.apt-get-ignore-missing }}" == "true" ]; then
|
||||
apt_get_packages="${{ inputs.apt-get }}"
|
||||
for package in ${apt_get_packages// / }
|
||||
do
|
||||
$sudo_prefix apt-get -o Acquire::Retries=${{ inputs.apt-get-retries }} install --ignore-missing -y $package || true
|
||||
done
|
||||
else
|
||||
$sudo_prefix apt-get -o Acquire::Retries=${{ inputs.apt-get-retries }} install -y ${{ inputs.apt-get }}
|
||||
fi
|
||||
|
||||
- name: vcpkg environment
|
||||
id: ctx
|
||||
if: ${{ inputs.vcpkg }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -xe
|
||||
|
||||
# vcpkg hash
|
||||
vcpkg_hash="$(git ls-remote https://github.com/microsoft/vcpkg.git ${{ inputs.vcpkg_branch }} | awk '{ print $1 }')"
|
||||
echo "vcpkg_hash=$vcpkg_hash" >> $GITHUB_OUTPUT
|
||||
|
||||
# vcpkg triplet
|
||||
default_triplet="${{ (runner.os == 'Windows' && 'x64-windows') || (runner.os == 'Linux' && 'x64-linux') || (runner.os == 'macOS' && 'x64-osx') || '' }}"
|
||||
input_triplet=${{ inputs.vcpkg_triplet }}
|
||||
if [ "$input_triplet" == "" ]; then
|
||||
triplet=$default_triplet
|
||||
else
|
||||
triplet=$input_triplet
|
||||
fi
|
||||
echo "triplet=$triplet" >> $GITHUB_OUTPUT
|
||||
if [ "$triplet" == "" ]; then
|
||||
triplet_suffix=""
|
||||
else
|
||||
triplet_suffix=":$triplet"
|
||||
fi
|
||||
echo "triplet_suffix=$triplet_suffix" >> $GITHUB_OUTPUT
|
||||
|
||||
# vcpkg executable
|
||||
vcpkg_target_dir=${{ inputs.vcpkg_dir }}
|
||||
if [[ $vcpkg_target_dir == /* ]]; then
|
||||
vcpkg_exec_path=$vcpkg_target_dir
|
||||
else
|
||||
vcpkg_exec_path=./$vcpkg_target_dir
|
||||
fi
|
||||
vcpkg_bs_exe="${{ (runner.os == 'Windows' && '$vcpkg_exec_path/bootstrap-vcpkg.bat') || '$vcpkg_exec_path/bootstrap-vcpkg.sh' }}"
|
||||
echo "vcpkg_bs_exe=$vcpkg_bs_exe" >> $GITHUB_OUTPUT
|
||||
|
||||
# vcpkg toolchain
|
||||
vcpkg_toolchain=$vcpkg_exec_path/scripts/buildsystems/vcpkg.cmake
|
||||
echo "vcpkg_toolchain=$vcpkg_toolchain" >> $GITHUB_OUTPUT
|
||||
|
||||
# vcpkg cache hash
|
||||
vcpkg_cache_hash="${{ runner.os }}-$vcpkg_hash$triplet_suffix"
|
||||
vcpkg_packages=${{ inputs.vcpkg }}
|
||||
for package in ${vcpkg_packages// / }
|
||||
do
|
||||
vcpkg_cache_hash=$vcpkg_cache_hash-$package
|
||||
done
|
||||
echo "vcpkg_cache_hash=$vcpkg_cache_hash" >> $GITHUB_OUTPUT
|
||||
|
||||
# Attempt to get vcpkg with its packages from the cache before cloning it
|
||||
# The cache key includes the vcpkg version, os, packages and triplet
|
||||
- name: vcpkg cache
|
||||
if: ${{ inputs.vcpkg }}
|
||||
id: cache-vcpkg
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ inputs.vcpkg_dir }}
|
||||
key: ${{ steps.ctx.outputs.vcpkg_cache_hash }}
|
||||
|
||||
- name: vcpkg install
|
||||
if: steps.cache-vcpkg.outputs.cache-hit != 'true' && inputs.vcpkg != ''
|
||||
shell: bash
|
||||
run: |
|
||||
set -xe
|
||||
git clone https://github.com/microsoft/vcpkg.git -b ${{ inputs.vcpkg_branch }} ${{ inputs.vcpkg_dir }}
|
||||
${{ steps.ctx.outputs.vcpkg_bs_exe }}
|
||||
cd ${{ inputs.vcpkg_dir }}
|
||||
packages=${{ inputs.vcpkg }}
|
||||
for package in ${packages// / }
|
||||
do
|
||||
vcpkg install $package${{ steps.ctx.outputs.triplet_suffix }}
|
||||
done
|
250
.github/workflows/ci.yml
vendored
250
.github/workflows/ci.yml
vendored
@ -15,6 +15,9 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
tags:
|
||||
- "boost-*.*.*"
|
||||
|
||||
|
||||
concurrency:
|
||||
group: ${{format('{0}:{1}', github.repository, github.ref)}}
|
||||
@ -26,71 +29,68 @@ env:
|
||||
DEFAULT_BUILD_VARIANT: debug,release
|
||||
|
||||
jobs:
|
||||
cpp-matrix:
|
||||
runs-on: ubuntu-latest
|
||||
name: Generate Test Matrix
|
||||
outputs:
|
||||
matrix: ${{ steps.cpp-matrix.outputs.matrix }}
|
||||
steps:
|
||||
- name: Generate Test Matrix
|
||||
uses: alandefreitas/cpp-actions/cpp-matrix@v1.4.1
|
||||
id: cpp-matrix
|
||||
with:
|
||||
compilers: |
|
||||
gcc >=4.8
|
||||
clang >=3.8
|
||||
msvc >=14.20
|
||||
apple-clang *
|
||||
# mingw *
|
||||
# clang-cl *
|
||||
standards: '>=11'
|
||||
latest-factors: |
|
||||
gcc Coverage UBSan
|
||||
factors: |
|
||||
gcc Asan Shared No-Threads
|
||||
msvc Shared x86
|
||||
clang Time-Trace
|
||||
mingw Shared
|
||||
trace-commands: true
|
||||
|
||||
build:
|
||||
needs: cpp-matrix
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# Latest
|
||||
- { name: 'GCC 11 (Latest): C++17-20', toolset: gcc-11, cxx: g++-11, cc: gcc-11, cxxstd: "17,20", os: ubuntu-22.04, install: [ g++-11 ], sources: [ "ppa:ubuntu-toolchain-r/test" ] }
|
||||
- { name: 'Clang 12 (Latest): C++17-20', toolset: clang, cxx: clang++-12, cc: clang-12, cxxstd: "17,20", os: ubuntu-22.04, install: [ clang-12 ] }
|
||||
- { name: 'MSVC 14.3 (Latest): C++17-20', toolset: msvc-14.3, cxxstd: "17,20", address-model: '32,64', os: windows-2022 }
|
||||
- { name: 'Clang 12 + libc++ (Latest): C++17-20', toolset: clang, cxx: clang++-12, cc: clang-12, cxxstd: "17,20", cxxflags: -stdlib=libc++, linkflags: -stdlib=libc++, os: ubuntu-20.04, install: [ clang-12, libc++-12-dev, libc++abi-12-dev ] }
|
||||
- { name: 'AppleClang (Latest): C++11-17', toolset: clang, cxxstd: "11,14,17", os: macos-11 }
|
||||
|
||||
# Oldest
|
||||
- { name: 'GCC 4.8 (Oldest): C++11', toolset: gcc-4.8, cxx: g++-4.8, cc: gcc-4.8, cxxstd: "11", os: ubuntu-22.04, container: 'ubuntu:18.04', install: [ g++-4.8 ] }
|
||||
- { name: 'Clang 3.8 (Oldest): C++11', toolset: clang, cxx: clang++-3.8, cc: clang-3.8, cxxstd: "11", os: ubuntu-22.04, container: 'ubuntu:16.04', install: [ clang-3.8 ] }
|
||||
- { name: 'MSVC 14.2 (Oldest): C++14-17', toolset: msvc-14.2, cxxstd: "14,17", address-model: '32,64', os: windows-2019 }
|
||||
|
||||
# Special
|
||||
- { name: 'UBSan (GCC 11: C++17-20)', toolset: gcc-11, cxx: g++-11, cc: gcc-11, cxxstd: "17,20", ubsan: true, os: ubuntu-22.04, install: [ g++-11 ], sources: [ "ppa:ubuntu-toolchain-r/test" ] }
|
||||
- { name: 'Shared (GCC)', generator: 'Unix Makefiles', os: ubuntu-22.04, build_shared: true, build_type: Debug, cmake: true }
|
||||
- { name: 'Shared (VS 2019)', toolset: msvc-14.2, generator: 'Visual Studio 16 2019', address-model: '32,64', cxxstd: "17,20", os: windows-2019, build_shared: true, build_type: Debug }
|
||||
- { name: 'Shared (VS 2022)', toolset: msvc-14.3, generator: 'Visual Studio 17 2022', address-model: '32,64', cxxstd: "17,20", os: windows-2022, build_shared: true, build_type: Debug }
|
||||
|
||||
# GCC
|
||||
- { name: 'GCC 10: C++17', toolset: gcc-10, cxx: g++-10, cc: gcc-10, cxxstd: "17", os: ubuntu-22.04, install: [ g++-10 ] }
|
||||
- { name: 'GCC 9: C++17', toolset: gcc-9, cxx: g++-9, cc: gcc-9, cxxstd: "17", os: ubuntu-22.04, install: [ g++-9 ] }
|
||||
- { name: 'GCC 8: C++17', toolset: gcc-8, cxx: g++-8, cc: gcc-8, cxxstd: "17", os: ubuntu-22.04, container: 'ubuntu:18.04', install: [ g++-8 ] }
|
||||
- { name: 'GCC 7: C++14-17', toolset: gcc-7, cxx: g++-7, cc: gcc-7, cxxstd: "14,17", os: ubuntu-22.04, container: 'ubuntu:18.04', install: [ g++-7 ] }
|
||||
- { name: 'GCC 6: C++11-14', toolset: gcc-6, cxx: g++-6, cc: gcc-6, cxxstd: "11,14", os: ubuntu-22.04, container: 'ubuntu:18.04', install: [ g++-6 ] }
|
||||
- { name: 'GCC 5: C++11-14', toolset: gcc-5, cxx: g++-5, cc: gcc-5, cxxstd: "11,14", os: ubuntu-22.04, container: 'ubuntu:16.04', install: [ g++-5 ] }
|
||||
- { name: 'GCC 4.9: C++11', toolset: gcc-4.9, cxx: g++-4.9, cc: gcc-4.9, cxxstd: "11", os: ubuntu-22.04, container: 'ubuntu:16.04', install: [ g++-4.9 ] }
|
||||
|
||||
# Clang
|
||||
- { name: 'Clang 11: C++14-17', toolset: clang, cxx: clang++-11, cc: clang-11, cxxstd: "14,17", os: ubuntu-20.04, install: [ clang-11 ] }
|
||||
- { name: 'Clang 10: C++14-17', toolset: clang, cxx: clang++-10, cc: clang-10, cxxstd: "14,17", os: ubuntu-20.04, install: [ clang-10 ] }
|
||||
- { name: 'Clang 9: C++14-17', toolset: clang, cxx: clang++-9, cc: clang-9, cxxstd: "14,17", os: ubuntu-22.04, container: 'ubuntu:18.04', install: [ clang-9 ] }
|
||||
- { name: 'Clang 8: C++17', toolset: clang, cxx: clang++-8, cc: clang-8, cxxstd: "17", os: ubuntu-22.04, container: 'ubuntu:18.04', install: [ clang-8, g++-7 ], gcc_toolchain: 7 }
|
||||
- { name: 'Clang 7: C++17', toolset: clang, cxx: clang++-7, cc: clang-7, cxxstd: "17", os: ubuntu-22.04, container: 'ubuntu:18.04', install: [ clang-7 ] }
|
||||
- { name: 'Clang 6.0: C++14-17', toolset: clang, cxx: clang++-6.0, cc: clang-6.0, cxxstd: "14,17", os: ubuntu-22.04, container: 'ubuntu:18.04', install: [ clang-6.0 ] }
|
||||
- { name: 'Clang 5.0: C++11-14', toolset: clang, cxx: clang++-5.0, cc: clang-5.0, cxxstd: "11,14", os: ubuntu-22.04, container: 'ubuntu:18.04', install: [ clang-5.0 ] }
|
||||
- { name: 'Clang 4.0: C++11-14', toolset: clang, cxx: clang++-4.0, cc: clang-4.0, cxxstd: "11,14", os: ubuntu-22.04, container: 'ubuntu:18.04', install: [ clang-4.0 ] }
|
||||
include: ${{ fromJSON(needs.cpp-matrix.outputs.matrix) }}
|
||||
|
||||
name: ${{ matrix.name }}
|
||||
timeout-minutes: 120
|
||||
runs-on: ${{matrix.os}}
|
||||
runs-on: ${{matrix.runs-on}}
|
||||
container: ${{matrix.container}}
|
||||
timeout-minutes: 120
|
||||
|
||||
steps:
|
||||
- name: Clone Boost.URL
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup C++
|
||||
uses: alandefreitas/cpp-actions/setup-cpp@v1.4.1
|
||||
id: setup-cpp
|
||||
with:
|
||||
compiler: ${{ matrix.compiler }}
|
||||
version: ${{ matrix.version }}
|
||||
|
||||
- name: Install packages
|
||||
if: ${{ !startsWith(matrix.os, 'windows') && (matrix.container || matrix.install) }}
|
||||
uses: ./.github/actions/package_install
|
||||
uses: alandefreitas/cpp-actions/package-install@v1.4.1
|
||||
id: package-install
|
||||
with:
|
||||
apt-get: ${{ join(matrix.install, ' ') }} ${{ matrix.container && 'sudo software-properties-common tzdata wget curl apt-transport-https make apt-file unzip libssl-dev build-essential autotools-dev autoconf automake g++ libc++-helpers python ruby cpio gcc-multilib g++-multilib pkgconf python3 ccache libpython-dev python3-distutils python3-pip git cmake' }}
|
||||
apt-get-ignore-missing: ${{ matrix.container && 'true' }}
|
||||
apt-get: ${{ matrix.install }}
|
||||
|
||||
- name: Clone Boost
|
||||
uses: alandefreitas/cpp-actions/boost-clone@develop
|
||||
uses: alandefreitas/cpp-actions/boost-clone@v1.4.1
|
||||
id: boost-clone
|
||||
with:
|
||||
branch: ${{ (github.ref_name == 'master' && github.ref_name) || 'develop' }}
|
||||
boost-dir: ../boost-source
|
||||
@ -117,78 +117,160 @@ jobs:
|
||||
latest_std=$(echo $cxxstd | awk -F ',' '{print $NF}')
|
||||
echo "latest_std=$latest_std" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Boost Workflow
|
||||
uses: ./.github/actions/cmake_workflow
|
||||
- name: Boost CMake Workflow
|
||||
uses: alandefreitas/cpp-actions/cmake-workflow@v1.4.1
|
||||
with:
|
||||
source-dir: ../boost-root
|
||||
build-dir: __build_cmake_test__
|
||||
generator: ${{ matrix.generator }}
|
||||
build-type: ${{ matrix.build_type || 'Debug' }}
|
||||
build-type: ${{ matrix.build-type }}
|
||||
build-target: tests boost_url_tests boost_url_limits boost_url_extra
|
||||
run-tests: true
|
||||
install-prefix: $GITHUB_WORKSPACE/.local
|
||||
cxxstd: ${{ steps.patch.outputs.latest_std }}
|
||||
cxx: ${{ matrix.cxx }}
|
||||
cc: ${{ matrix.cc }}
|
||||
cmake-min-version: 3.15 # min-version with cmake --install
|
||||
extra-args: ${{ format('-D Boost_VERBOSE=ON -D BOOST_INCLUDE_LIBRARIES={0} -D BUILD_SHARED_LIBS={1}', steps.patch.outputs.module, (matrix.build_shared && 'ON') || 'OFF') }}
|
||||
cxxstd: ${{ matrix.latest-cxxstd }}
|
||||
cc: ${{ steps.setup-cpp.outputs.cc || matrix.cc }}
|
||||
ccflags: ${{ matrix.ccflags }}
|
||||
cxx: ${{ steps.setup-cpp.outputs.cxx || matrix.cxx }}
|
||||
cxxflags: ${{ matrix.cxxflags }}
|
||||
shared: ${{ matrix.shared }}
|
||||
cmake-version: '>=3.15'
|
||||
extra-args: ${{ format('-D Boost_VERBOSE=ON -D BOOST_INCLUDE_LIBRARIES={0} -D BOOST_URL_DISABLE_THREADS={1}', steps.patch.outputs.module, ( matrix.no-threads && 'ON' ) || 'OFF') }}
|
||||
export-compile-commands: ${{ matrix.time-trace }}
|
||||
package: false
|
||||
package-artifact: false
|
||||
ref-source-dir: ../boost-root/libs/url
|
||||
|
||||
- name: Subdir Workflow
|
||||
uses: ./.github/actions/cmake_workflow
|
||||
- name: Subdirectory Integration Workflow
|
||||
uses: alandefreitas/cpp-actions/cmake-workflow@v1.4.1
|
||||
with:
|
||||
source-dir: ../boost-root/libs/${{ steps.patch.outputs.module }}/test/cmake_test
|
||||
build-dir: __build_cmake_subdir_test__
|
||||
generator: ${{ matrix.generator }}
|
||||
build-type: ${{ matrix.build_type || 'Debug' }}
|
||||
cxxstd: ${{ steps.patch.outputs.latest_std }}
|
||||
cxx: ${{ matrix.cxx }}
|
||||
cc: ${{ matrix.cc }}
|
||||
build-type: ${{ matrix.build_type }}
|
||||
cxxstd: ${{ matrix.latest-cxxstd }}
|
||||
cc: ${{ steps.setup-cpp.outputs.cc || matrix.cc }}
|
||||
ccflags: ${{ matrix.ccflags }}
|
||||
cxx: ${{ steps.setup-cpp.outputs.cxx || matrix.cxx }}
|
||||
cxxflags: ${{ matrix.cxxflags }}
|
||||
shared: ${{ matrix.shared }}
|
||||
install: false
|
||||
cmake-min-version: 3.11
|
||||
extra-args: ${{ format('-D BOOST_CI_INSTALL_TEST=OFF -D BUILD_SHARED_LIBS={0}', (matrix.build_shared && 'ON') || 'OFF') }}
|
||||
cmake-version: '>=3.11'
|
||||
extra-args: -D BOOST_CI_INSTALL_TEST=OFF
|
||||
ref-source-dir: ../boost-root/libs/url/test/cmake_test
|
||||
|
||||
- name: Package Workflow
|
||||
uses: ./.github/actions/cmake_workflow
|
||||
- name: Find Package Integration Workflow
|
||||
uses: alandefreitas/cpp-actions/cmake-workflow@v1.4.1
|
||||
with:
|
||||
source-dir: ../boost-root/libs/${{ steps.patch.outputs.module }}/test/cmake_test
|
||||
build-dir: __build_cmake_install_test__
|
||||
generator: ${{ matrix.generator }}
|
||||
build-type: ${{ matrix.build_type || 'Debug' }}
|
||||
cxxstd: ${{ steps.patch.outputs.latest_std }}
|
||||
cxx: ${{ matrix.cxx }}
|
||||
cc: ${{ matrix.cc }}
|
||||
build-type: ${{ matrix.build-type }}
|
||||
cxxstd: ${{ matrix.latest-cxxstd }}
|
||||
cc: ${{ steps.setup-cpp.outputs.cc || matrix.cc }}
|
||||
ccflags: ${{ matrix.ccflags }}
|
||||
cxx: ${{ steps.setup-cpp.outputs.cxx || matrix.cxx }}
|
||||
cxxflags: ${{ matrix.cxxflags }}
|
||||
shared: ${{ matrix.shared }}
|
||||
install: false
|
||||
extra-args: ${{ format('-D BOOST_CI_INSTALL_TEST=ON -D CMAKE_PREFIX_PATH=$GITHUB_WORKSPACE/.local -D BUILD_SHARED_LIBS={0}', (matrix.build_shared && 'ON') || 'OFF') }}
|
||||
extra-args: -D BOOST_CI_INSTALL_TEST=ON -D CMAKE_PREFIX_PATH=$GITHUB_WORKSPACE/.local
|
||||
package: false
|
||||
package-artifact: false
|
||||
ref-source-dir: ../boost-root/libs/url/test/cmake_test
|
||||
|
||||
- name: Root Workflow
|
||||
uses: ./.github/actions/cmake_workflow
|
||||
- name: Root Project CMake Workflow
|
||||
uses: alandefreitas/cpp-actions/cmake-workflow@v1.4.1
|
||||
with:
|
||||
source-dir: .
|
||||
build-dir: __build_root_test__
|
||||
generator: ${{ matrix.generator }}
|
||||
build-type: ${{ matrix.build_type || 'Debug' }}
|
||||
build-type: ${{ matrix.build-type }}
|
||||
build-target: tests boost_url_tests boost_url_limits boost_url_extra
|
||||
run-tests: false
|
||||
install: false
|
||||
cxxstd: ${{ steps.patch.outputs.latest_std }}
|
||||
cxx: ${{ matrix.cxx }}
|
||||
cc: ${{ matrix.cc }}
|
||||
extra-args: ${{ format('-D Boost_VERBOSE=ON -D BUILD_TESTING=ON -D BUILD_SHARED_LIBS={0} -D BOOST_SRC_DIR="../boost-root"', (matrix.build_shared && 'ON') || 'OFF') }}
|
||||
ref-source-dir: ../boost-root/libs/url
|
||||
cxxstd: ${{ matrix.latest-cxxstd }}
|
||||
cc: ${{ steps.setup-cpp.outputs.cc || matrix.cc }}
|
||||
ccflags: ${{ matrix.ccflags }}
|
||||
cxx: ${{ steps.setup-cpp.outputs.cxx || matrix.cxx }}
|
||||
cxxflags: ${{ matrix.cxxflags }}
|
||||
shared: ${{ matrix.shared }}
|
||||
extra-args: -D Boost_VERBOSE=ON -D BUILD_TESTING=ON -D BOOST_SRC_DIR="../boost-root"
|
||||
package: false
|
||||
package-artifact: false
|
||||
ref-source-dir: .
|
||||
|
||||
- name: Release Workflow
|
||||
uses: ./.github/actions/b2_workflow
|
||||
- name: Boost B2 Workflow
|
||||
uses: alandefreitas/cpp-actions/b2-workflow@v1.4.1
|
||||
with:
|
||||
source-dir: ../boost-root
|
||||
modules: url
|
||||
toolset: ${{ matrix.toolset }}
|
||||
cxx: ${{ (startsWith(matrix.cxx, 'clang') && matrix.cxx) || '' }}
|
||||
toolset: ${{ matrix.b2-toolset }}
|
||||
build-variant: ${{ matrix.build-type }}
|
||||
cxx: ${{ steps.setup-cpp.outputs.cxx || matrix.cxx || '' }}
|
||||
cxxstd: ${{ matrix.cxxstd }}
|
||||
cxxflags: ${{ matrix.cxxflags }}
|
||||
linkflags: ${{ matrix.linkflags }}
|
||||
address-model: ${{ matrix.address-model }}
|
||||
address-model: ${{ (matrix.x86 && '32') || '64' }}
|
||||
asan: ${{ matrix.asan }}
|
||||
ubsan: ${{ matrix.ubsan }}
|
||||
gcc_toolchain: ${{ matrix.gcc_toolchain }}
|
||||
tsan: ${{ matrix.tsan }}
|
||||
shared: ${{ matrix.shared }}
|
||||
|
||||
- name: FlameGraph
|
||||
uses: alandefreitas/cpp-actions/flamegraph@v1.4.1
|
||||
if: matrix.time-trace
|
||||
with:
|
||||
source-dir: ../boost-root/libs/url
|
||||
build-dir: ../boost-root/__build_cmake_test__
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Codecov
|
||||
if: ${{ matrix.coverage }}
|
||||
run: |
|
||||
set -x
|
||||
|
||||
# Generate report
|
||||
gcov_tool="gcov"
|
||||
if command -v "gcov-${{ steps.setup-cpp.outputs.version-major }}.${{ steps.setup-cpp.outputs.version-minor }}" &> /dev/null; then
|
||||
gcov_tool="gcov"
|
||||
elif command -v "gcov-${{ steps.setup-cpp.outputs.version-major }}" &> /dev/null; then
|
||||
gcov_tool="gcov-${{ steps.setup-cpp.outputs.version-major }}"
|
||||
fi
|
||||
lcov -c -q -o "../boost-root/__build_cmake_test__/coverage.info" -d "../boost-root/__build_cmake_test__" --include "$(pwd)/../boost-root/libs/${{steps.patch.outputs.module}}/*" --gcov-tool "$gcov_tool"
|
||||
|
||||
# Upload to codecov
|
||||
bash <(curl -s https://codecov.io/bash) -f "../boost-root/__build_cmake_test__/coverage.info"
|
||||
|
||||
# Summary
|
||||
echo "# Coverage" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "[](https://codecov.io/github/$GITHUB_REPOSITORY/commit/$GITHUB_SHA)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Commit: [](https://codecov.io/github/$GITHUB_REPOSITORY/commit/$GITHUB_SHA)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Branch: [](https://codecov.io/github/$GITHUB_REPOSITORY/commit/$GITHUB_SHA)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
changelog:
|
||||
needs: cpp-matrix
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
name: Changelog Summary
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 120
|
||||
|
||||
steps:
|
||||
- name: Clone cpp-actions
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Avoid the common API rate limit exceeded error in boostorg by including 100 latest commits in any case
|
||||
fetch-depth: 100
|
||||
|
||||
- name: Changelog
|
||||
uses: alandefreitas/cpp-actions/create-changelog@5002c2c59e172031bba5626f6dff319e86d9bda1 # v1.4.1
|
||||
with:
|
||||
thank-non-regular: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
limit: 200
|
||||
tag-pattern: 'boost-.*\..*\..*'
|
||||
|
||||
|
@ -29,6 +29,7 @@ set(__ignore__ ${CMAKE_C_COMPILER})
|
||||
option(BOOST_URL_BUILD_TESTS "Build boost::url tests" ${BUILD_TESTING})
|
||||
option(BOOST_URL_BUILD_FUZZERS "Build boost::url fuzzers" OFF)
|
||||
option(BOOST_URL_BUILD_EXAMPLES "Build boost::url examples" ${BOOST_URL_IS_ROOT})
|
||||
option(BOOST_URL_DISABLE_THREADS "Disable threads" OFF)
|
||||
set(BOOST_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../.." CACHE STRING "Boost source dir to use when running CMake from this directory")
|
||||
|
||||
#######################################################
|
||||
@ -108,6 +109,9 @@ source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/src PREFIX "url" FILES ${BOOST_URL
|
||||
function(boost_url_setup_properties target)
|
||||
target_compile_features(${target} PUBLIC cxx_constexpr)
|
||||
target_compile_definitions(${target} PUBLIC BOOST_URL_NO_LIB=1)
|
||||
if (BOOST_URL_DISABLE_THREADS)
|
||||
target_compile_definitions(${target} PUBLIC BOOST_URL_DISABLE_THREADS=1)
|
||||
endif()
|
||||
target_include_directories(${target} PUBLIC "${PROJECT_SOURCE_DIR}/include")
|
||||
target_link_libraries(${target} PUBLIC ${BOOST_URL_DEPENDENCIES})
|
||||
target_compile_definitions(${target} PUBLIC $<IF:$<BOOL:${BUILD_SHARED_LIBS}>,BOOST_URL_DYN_LINK=1,BOOST_URL_STATIC_LINK=1>)
|
||||
|
Loading…
x
Reference in New Issue
Block a user