ci: set up cpp-actions matrix

This commit is contained in:
alandefreitas 2023-06-08 02:41:41 -03:00 committed by Alan de Freitas
parent fd72f3fce1
commit 381033202c
7 changed files with 170 additions and 1495 deletions

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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

View File

@ -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 "[![codecov](https://codecov.io/github/$GITHUB_REPOSITORY/commit/$GITHUB_SHA/graphs/sunburst.svg)](https://codecov.io/github/$GITHUB_REPOSITORY/commit/$GITHUB_SHA)" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Commit: [![codecov](https://codecov.io/github/$GITHUB_REPOSITORY/commit/$GITHUB_SHA/graph/badge.svg)](https://codecov.io/github/$GITHUB_REPOSITORY/commit/$GITHUB_SHA)" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Branch: [![codecov](https://codecov.io/github/$GITHUB_REPOSITORY/branch/$GITHUB_REF_NAME/graph/badge.svg)](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-.*\..*\..*'

View File

@ -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>)