2
0
mirror of https://github.com/boostorg/url.git synced 2026-01-19 04:42:15 +00:00

simplify CI and CML

This commit is contained in:
alandefreitas
2023-04-14 21:31:52 -03:00
committed by Alan de Freitas
parent 963bf5a4b7
commit c518dbaa04
26 changed files with 1756 additions and 11305 deletions

View File

@@ -116,9 +116,9 @@ def generate(compiler_ranges, cxx_range, max_cxx=2, coverage=True, docs=True, as
coverage_desc[2] = 'codecov'
latest_compilers = [coverage_desc] + latest_compilers
if cmake:
cmake_desc = latest_gcc[:]
cmake_desc[2] = 'cmake-install'
compilers = [cmake_desc] + compilers
# cmake_desc = latest_gcc[:]
# cmake_desc[2] = 'cmake-install'
# compilers = [cmake_desc] + compilers
cmake_desc = latest_gcc[:]
cmake_desc[2] = 'cmake'

141
.github/actions/b2_workflow/action.yml vendored Normal file
View File

@@ -0,0 +1,141 @@
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: Setup msvc dev-cmd
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@v1
- 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 Normal file
View File

@@ -0,0 +1,314 @@
#
# 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 Normal file
View File

@@ -0,0 +1,220 @@
#!/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

@@ -0,0 +1,534 @@
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

@@ -0,0 +1,206 @@
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

@@ -26,7 +26,7 @@ env:
DEFAULT_BUILD_VARIANT: debug,release
jobs:
posix:
build:
defaults:
run:
shell: bash
@@ -35,482 +35,160 @@ jobs:
fail-fast: false
matrix:
include:
# Linux, gcc
- toolset: gcc-4.8
cxxstd: "11"
os: ubuntu-22.04
container: ubuntu:18.04
install:
- g++-4.8
- toolset: gcc-4.9
cxxstd: "11"
os: ubuntu-22.04
container: ubuntu:16.04
install:
- g++-4.9
- toolset: gcc-5
cxxstd: "11,14"
os: ubuntu-22.04
container: ubuntu:16.04
install:
- g++-5
- toolset: gcc-6
cxxstd: "11,14"
os: ubuntu-22.04
container: ubuntu:18.04
install:
- g++-6
- toolset: gcc-7
cxxstd: "14,17"
os: ubuntu-22.04
container: ubuntu:18.04
install:
- g++-7
- toolset: gcc-8
cxxstd: "17"
os: ubuntu-22.04
container: ubuntu:18.04
install:
- g++-8
- toolset: gcc-9
cxxstd: "17"
os: ubuntu-22.04
install:
- g++-9
- toolset: gcc-10
cxxstd: "17"
os: ubuntu-22.04
install:
- g++-10
- toolset: gcc-11
cxxstd: "17,20"
os: ubuntu-22.04
install:
- g++-11
sources:
- "ppa:ubuntu-toolchain-r/test"
- name: UBSAN
toolset: gcc-11
cxxstd: "17,20"
ubsan: 1
os: ubuntu-22.04
install:
- g++-11
sources:
- "ppa:ubuntu-toolchain-r/test"
# 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 }
# Linux, clang
- toolset: clang
compiler: clang++-3.8
cxxstd: "11"
os: ubuntu-22.04
container: ubuntu:16.04
install:
- clang-3.8
- toolset: clang
compiler: clang++-4.0
cxxstd: "11,14"
os: ubuntu-22.04
container: ubuntu:18.04
install:
- clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "11,14"
os: ubuntu-22.04
container: ubuntu:18.04
install:
- clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "14,17"
os: ubuntu-22.04
container: ubuntu:18.04
install:
- clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "17"
os: ubuntu-22.04
container: ubuntu:18.04
install:
- clang-7
- toolset: clang
compiler: clang++-8
cxxstd: "17"
os: ubuntu-22.04
container: ubuntu:18.04
install:
- clang-8
- g++-7
gcc_toolchain: 7
- toolset: clang
compiler: clang++-9
cxxstd: "14,17"
os: ubuntu-22.04
container: ubuntu:18.04
install:
- clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "14,17"
os: ubuntu-20.04
install:
- clang-10
- toolset: clang
compiler: clang++-11
cxxstd: "14,17"
os: ubuntu-20.04
install:
- clang-11
- toolset: clang
compiler: clang++-12
cxxstd: "17,20"
os: ubuntu-22.04
install:
- clang-12
- toolset: clang
compiler: 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
# 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 }
- toolset: clang
cxxstd: "11,14,17"
os: macos-11
# 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 }
- name: CMake tests
cmake_tests: 1
os: ubuntu-22.04
# 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 ] }
name: ${{ matrix.name }}
timeout-minutes: 120
runs-on: ${{matrix.os}}
container: ${{matrix.container}}
steps:
- name: Setup environment
run: |
if [ -f "/etc/debian_version" ]
then
echo "DEBIAN_FRONTEND=noninteractive" >> $GITHUB_ENV
export DEBIAN_FRONTEND=noninteractive
fi
if [ -n "${{matrix.container}}" ]
then
echo "GHA_CONTAINER=${{matrix.container}}" >> $GITHUB_ENV
if [ -f "/etc/debian_version" ]
then
apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y 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
# install pip:
python_version=$(python3 -c 'import sys; print("{0.major}.{0.minor}".format(sys.version_info))')
if [[ ${python_version} =~ ^3\.[0-5]$ ]]; then
true
else
apt-get install -y python3-distutils
fi
wget https://bootstrap.pypa.io/pip/$python_version/get-pip.py
python3 get-pip.py
# install git:
# apt-get install -y git
apt-add-repository ppa:git-core/ppa
apt-get -o Acquire::Retries=$NET_RETRY_COUNT update && apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y git
# install cmake:
# apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y cmake
sudo pip3 install cmake
fi
fi
git config --global pack.threads 0
- uses: actions/checkout@v3
- name: Clone Boost.URL
uses: actions/checkout@v3
- name: Install packages
if: matrix.install
run: |
SOURCE_KEYS=(${{join(matrix.source_keys, ' ')}})
SOURCES=(${{join(matrix.sources, ' ')}})
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
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 -E apt-add-repository "${APT_ADD_REPO_ARGS[@]}" && break || sleep 2
done
done
fi
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y ${{join(matrix.install, ' ')}}
- name: Setup GCC Toolchain
if: matrix.gcc_toolchain
run: |
GCC_TOOLCHAIN_ROOT="$HOME/gcc-toolchain"
echo "GCC_TOOLCHAIN_ROOT=\"$GCC_TOOLCHAIN_ROOT\"" >> $GITHUB_ENV
MULTIARCH_TRIPLET="$(dpkg-architecture -qDEB_HOST_MULTIARCH)"
mkdir -p "$GCC_TOOLCHAIN_ROOT"
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/${{matrix.gcc_toolchain}}" "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}"
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
BUILD_JOBS=$((nproc || sysctl -n hw.ncpu) 2> /dev/null)
echo "BUILD_JOBS=$BUILD_JOBS" >> $GITHUB_ENV
echo "CMAKE_BUILD_PARALLEL_LEVEL=$BUILD_JOBS" >> $GITHUB_ENV
DEPINST_ARGS=()
GIT_VERSION="$(git --version | sed -e 's/git version //')"
if $(dpkg --compare-versions "$GIT_VERSION" ge 2.8.0)
then
DEPINST_ARGS+=("--git_args" "--jobs $GIT_FETCH_JOBS")
fi
cd ..
git clone -b "$BOOST_BRANCH" --depth 1 "https://github.com/boostorg/boost.git" "boost-root"
cd boost-root
# mkdir -p libs/$LIBRARY
# cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
# git submodule update --init tools/boostdep
git submodule update --init --recursive
if [ ! -d "libs/$LIBRARY" ]; then
mkdir -p libs/$LIBRARY
fi
find libs/$LIBRARY -mindepth 1 -delete
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
DEPINST_ARGS+=("$LIBRARY")
python tools/boostdep/depinst/depinst.py "${DEPINST_ARGS[@]}"
if [ -z "${{matrix.cmake_tests}}" ]
then
./bootstrap.sh
./b2 headers
if [ -n "${{matrix.compiler}}" -o -n "$GCC_TOOLCHAIN_ROOT" ]
then
echo -n "using ${{matrix.toolset}} : : ${{matrix.compiler}}" > ~/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
fi
- name: Run tests
if: matrix.cmake_tests == ''
run: |
cd ../boost-root
B2_ARGS=("-j" "$BUILD_JOBS" "toolset=${{matrix.toolset}}" "cxxstd=${{matrix.cxxstd}}")
if [ -n "${{matrix.build_variant}}" ]
then
B2_ARGS+=("variant=${{matrix.build_variant}}")
else
B2_ARGS+=("variant=$DEFAULT_BUILD_VARIANT")
fi
if [ -n "${{matrix.threading}}" ]
then
B2_ARGS+=("threading=${{matrix.threading}}")
fi
if [ -n "${{matrix.ubsan}}" ]
then
export UBSAN_OPTIONS="print_stacktrace=1"
B2_ARGS+=("cxxflags=-fsanitize=undefined -fno-sanitize-recover=undefined" "linkflags=-fsanitize=undefined -fuse-ld=gold" "define=UBSAN=1" "debug-symbols=on" "visibility=global")
fi
if [ -n "${{matrix.cxxflags}}" ]
then
B2_ARGS+=("cxxflags=${{matrix.cxxflags}}")
fi
if [ -n "${{matrix.linkflags}}" ]
then
B2_ARGS+=("linkflags=${{matrix.linkflags}}")
fi
B2_ARGS+=("libs/$LIBRARY/test")
./b2 "${B2_ARGS[@]}"
- name: Run CMake tests
if: matrix.cmake_tests != ''
run: |
cd ../boost-root
git submodule update --init --recursive
cd libs/$LIBRARY
mkdir __build__ && cd __build__
cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
cmake --build . --target install
windows:
strategy:
fail-fast: false
matrix:
include:
#- toolset: msvc-14.1
# cxxstd: "14,17,latest"
# addrmd: 32,64
# os: windows-2016
- toolset: msvc-14.2
cxxstd: "14,17"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.3
cxxstd: "17,20"
addrmd: 32,64
os: windows-2022
# - toolset: gcc
# cxxstd: "11,14,17"
# addrmd: 64
# os: windows-2019
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs %GIT_FETCH_JOBS%" %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
- name: Run tests
shell: cmd
run: |
cd ../boost-root
b2 -j %NUMBER_OF_PROCESSORS% libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release
CMake:
defaults:
run:
shell: bash
strategy:
fail-fast: false
matrix:
include:
- { os: ubuntu-22.04, build_shared: ON, build_type: Debug, generator: 'Unix Makefiles' }
- { os: ubuntu-22.04, build_shared: OFF, build_type: Debug, generator: 'Unix Makefiles' }
- { os: windows-2019, build_shared: ON, build_type: Debug, generator: 'Visual Studio 16 2019' }
- { os: windows-2019, build_shared: OFF, build_type: Debug, generator: 'Visual Studio 16 2019' }
- { os: windows-2022, build_shared: ON, build_type: Debug, generator: 'Visual Studio 17 2022' }
- { os: windows-2022, build_shared: OFF, build_type: Debug, generator: 'Visual Studio 17 2022' }
timeout-minutes: 120
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- name: Fetch Boost.CI
uses: actions/checkout@v3
if: ${{ !startsWith(matrix.os, 'windows') && (matrix.container || matrix.install) }}
uses: ./.github/actions/package_install
id: package-install
with:
repository: boostorg/boost-ci
ref: master
path: boost-ci-cloned
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' }}
- name: Get CI scripts folder
run: |
# Copy ci folder if not testing Boost.CI
[[ "$GITHUB_REPOSITORY" =~ "boost-ci" ]] || cp -r boost-ci-cloned/ci .
rm -rf boost-ci-cloned
- name: Setup Boost
env: {B2_DONT_BOOTSTRAP: 1}
run: source ci/github/install.sh
- name: Clone Boost
uses: ./.github/actions/boost_clone
with:
boost_dir: ../boost-source
branch: ${{ (github.ref_name == 'master' && github.ref_name) || 'develop' }}
scan-modules-dir: .
scan-modules-ignore: url
- name: Run CMake tests
- name: Patch Boost
working-directory: ../boost-source
id: patch
shell: bash
run: |
cd "$BOOST_ROOT"
mkdir __build_cmake_test__ && cd __build_cmake_test__
cmake -G "${{matrix.generator}}" -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBOOST_INCLUDE_LIBRARIES=$SELF -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DBUILD_TESTING=ON -DBoost_VERBOSE=ON ..
cmake --build . --target tests boost_url_tests boost_url_limits boost_url_extra --config ${{matrix.build_type}}
ctest --output-on-failure --build-config ${{matrix.build_type}}
- name: Run CMake subdir tests
run: |
cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_test" # New unified folder
[ -d "$cmake_test_folder" ] || cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_subdir_test"
cd "$cmake_test_folder"
mkdir __build_cmake_subdir_test__ && cd __build_cmake_subdir_test__
cmake -G "${{matrix.generator}}" -DBOOST_CI_INSTALL_TEST=OFF -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBUILD_SHARED_LIBS=${{matrix.build_shared}} ..
cmake --build . --config ${{matrix.build_type}}
ctest --output-on-failure --build-config ${{matrix.build_type}}
- name: Install Library
run: |
cd "$BOOST_ROOT"
mkdir __build_cmake_install_test__ && cd __build_cmake_install_test__
cmake -G "${{matrix.generator}}" -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBOOST_INCLUDE_LIBRARIES=$SELF -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DCMAKE_INSTALL_PREFIX=~/.local -DBoost_VERBOSE=ON -DBoost_DEBUG=ON ..
cmake --build . --target install --config ${{matrix.build_type}}
- name: Run CMake install tests
run: |
cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_test" # New unified folder
[ -d "$cmake_test_folder" ] || cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_install_test"
cd "$cmake_test_folder"
mkdir __build_cmake_install_test__ && cd __build_cmake_install_test__
cmake -G "${{matrix.generator}}" -DBOOST_CI_INSTALL_TEST=ON -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DCMAKE_PREFIX_PATH=~/.local ..
cmake --build . --config ${{matrix.build_type}}
ctest --output-on-failure --build-config ${{matrix.build_type}}
set -xe
module=${GITHUB_REPOSITORY#*/}
echo "module=$module" >> $GITHUB_OUTPUT
workspace_root=$(echo "$GITHUB_WORKSPACE" | sed 's/\\/\//g')
rm -r "libs/$module" || true
cd ..
mkdir boost-root || true
cp -r "boost-source"/* "boost-root"
cd boost-root
mkdir "libs/$module"
cp -r "$workspace_root"/* "libs/$module"
cxxstd=${{ matrix.cxxstd }}
latest_std=$(echo $cxxstd | awk -F ',' '{print $NF}')
echo "latest_std=$latest_std" >> $GITHUB_OUTPUT
- name: Boost Workflow
uses: ./.github/actions/cmake_workflow
with:
source-dir: ../boost-root
build-dir: __build_cmake_test__
generator: ${{ matrix.generator }}
build-type: ${{ matrix.build_type || 'Debug' }}
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') }}
ref-source-dir: ../boost-root/libs/url
- name: Subdir Workflow
uses: ./.github/actions/cmake_workflow
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 }}
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') }}
ref-source-dir: ../boost-root/libs/url/test/cmake_test
- name: Package Workflow
uses: ./.github/actions/cmake_workflow
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 }}
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') }}
ref-source-dir: ../boost-root/libs/url/test/cmake_test
- name: Root Workflow
uses: ./.github/actions/cmake_workflow
with:
source-dir: .
build-dir: __build_root_test__
generator: ${{ matrix.generator }}
build-type: ${{ matrix.build_type || 'Debug' }}
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
- name: Release Workflow
uses: ./.github/actions/b2_workflow
with:
source-dir: ../boost-root
modules: url
toolset: ${{ matrix.toolset }}
cxx: ${{ (startsWith(matrix.cxx, 'clang') && matrix.cxx) || '' }}
cxxstd: ${{ matrix.cxxstd }}
cxxflags: ${{ matrix.cxxflags }}
linkflags: ${{ matrix.linkflags }}
address-model: ${{ matrix.address-model }}
ubsan: ${{ matrix.ubsan }}
gcc_toolchain: ${{ matrix.gcc_toolchain }}

View File

@@ -8,149 +8,125 @@
# Official repository: https://github.com/boostorg/url
#
#######################################################
### Project ###
#######################################################
cmake_minimum_required(VERSION 3.8...3.16)
set(BOOST_URL_VERSION 2)
if(BOOST_SUPERPROJECT_VERSION)
set(BOOST_URL_VERSION ${BOOST_SUPERPROJECT_VERSION})
endif()
project(boost_url VERSION "${BOOST_URL_VERSION}" LANGUAGES CXX)
set(BOOST_URL_IS_ROOT OFF)
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
set(BOOST_URL_IS_ROOT ON)
endif()
if(BOOST_URL_IS_ROOT)
include(CTest)
endif()
if(NOT BOOST_SUPERPROJECT_VERSION)
option(BOOST_URL_INSTALL "Install boost::url files" ${BOOST_URL_IS_ROOT})
option(BOOST_URL_BUILD_TESTS "Build boost::url tests" ${BUILD_TESTING})
option(BOOST_URL_BUILD_FUZZERS "Build boost::json fuzzers" ${BOOST_URL_BUILD_TESTS})
option(BOOST_URL_BUILD_EXAMPLES "Build boost::url examples" ${BOOST_URL_IS_ROOT})
else()
set(BOOST_URL_BUILD_TESTS ${BUILD_TESTING})
endif()
if (BOOST_SUPERPROJECT_VERSION)
set(BOOST_URL_FIND_PACKAGE_BOOST OFF)
elseif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../CMakeLists.txt" AND
EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../Jamroot" AND
EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../boost-build.jam" AND
EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../bootstrap.sh" AND
EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../libs")
set(BOOST_URL_FIND_PACKAGE_BOOST OFF)
else()
set(BOOST_URL_FIND_PACKAGE_BOOST ON)
endif()
set(BOOST_URL_VERSION ${BOOST_SUPERPROJECT_VERSION})
endif ()
project(boost_url VERSION "${BOOST_URL_VERSION}" LANGUAGES CXX)
set(BOOST_URL_IS_ROOT OFF)
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
set(BOOST_URL_IS_ROOT ON)
endif ()
set(__ignore__ CMAKE_C_COMPILER)
if (BOOST_URL_FIND_PACKAGE_BOOST)
find_package(Boost 1.78.0 REQUIRED COMPONENTS container)
elseif (BOOST_URL_IS_ROOT)
set(BOOST_URL_UNIT_TEST_LIBRARIES container filesystem unordered json regex beast)
set(BOOST_INCLUDE_LIBRARIES url ${BOOST_URL_UNIT_TEST_LIBRARIES})
set(BOOST_EXCLUDE_LIBRARIES url)
#######################################################
### Options ###
#######################################################
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})
set(BOOST_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../.." CACHE STRING "Boost source dir to use when running CMake from this directory")
#######################################################
### Boost modules ###
#######################################################
# The boost super-project requires one explicit dependency per-line.
set(BOOST_URL_DEPENDENCIES
Boost::align
Boost::assert
Boost::config
Boost::core
Boost::mp11
Boost::optional
Boost::static_assert
Boost::system
Boost::throw_exception
Boost::type_traits
Boost::variant2
)
foreach (BOOST_URL_DEPENDENCY ${BOOST_URL_DEPENDENCIES})
if (BOOST_URL_DEPENDENCY MATCHES "^[ ]*Boost::([A-Za-z0-9_]+)[ ]*$")
list(APPEND BOOST_URL_INCLUDE_LIBRARIES ${CMAKE_MATCH_1})
endif ()
endforeach ()
set(BOOST_URL_UNIT_TEST_LIBRARIES container filesystem unordered)
set(BOOST_URL_EXAMPLE_LIBRARIES json regex beast)
set(BOOST_INCLUDE_LIBRARIES ${BOOST_URL_INCLUDE_LIBRARIES} ${BOOST_URL_UNIT_TEST_LIBRARIES} ${BOOST_URL_EXAMPLE_LIBRARIES})
set(BOOST_EXCLUDE_LIBRARIES url)
#######################################################
### Add Boost Subdirectory ###
#######################################################
if (NOT BOOST_SUPERPROJECT_VERSION)
set(CMAKE_FOLDER Dependencies)
add_subdirectory(../.. Dependencies/boost EXCLUDE_FROM_ALL)
unset(CMAKE_FOLDER)
endif()
# Find absolute BOOST_SRC_DIR
if (NOT IS_ABSOLUTE ${BOOST_SRC_DIR})
set(BOOST_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${BOOST_SRC_DIR}")
endif ()
include(GNUInstallDirs)
# Validate BOOST_SRC_DIR
set(BOOST_SRC_DIR_IS_VALID ON)
foreach (F "CMakeLists.txt" "Jamroot" "boost-build.jam" "bootstrap.sh" "libs")
if (NOT EXISTS "${BOOST_SRC_DIR}/${F}")
message(STATUS "${BOOST_SRC_DIR}/${F} does not exist. Fallback to find_package.")
set(BOOST_SRC_DIR_IS_VALID OFF)
break()
endif ()
endforeach ()
# Create Boost interface targets
if (BOOST_SRC_DIR_IS_VALID)
set(BOOST_EXCLUDE_LIBRARIES ${PROJECT_NAME})
set(PREV_BUILD_TESTING ${BUILD_TESTING})
set(BUILD_TESTING OFF CACHE BOOL "Build the tests." FORCE)
add_subdirectory(${BOOST_SRC_DIR} Dependencies/boost EXCLUDE_FROM_ALL)
set(BUILD_TESTING ${PREV_BUILD_TESTING} CACHE BOOL "Build the tests." FORCE)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${BOOST_SRC_DIR}/tools/cmake/include")
else ()
find_package(Boost REQUIRED COMPONENTS container)
foreach (BOOST_INCLUDE_LIBRARY ${BOOST_INCLUDE_LIBRARIES})
if (NOT TARGET Boost::${BOOST_INCLUDE_LIBRARY})
add_library(Boost::${BOOST_INCLUDE_LIBRARY} ALIAS Boost::headers)
endif ()
endforeach ()
endif ()
unset(CMAKE_FOLDER)
endif ()
#######################################################
### Library ###
#######################################################
file(GLOB_RECURSE BOOST_URL_HEADERS CONFIGURE_DEPENDS include/boost/*.hpp include/boost/*.natvis)
file(GLOB_RECURSE BOOST_URL_SOURCES CONFIGURE_DEPENDS src/*.cpp)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/include/boost PREFIX "" FILES ${BOOST_URL_HEADERS})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/src PREFIX "url" FILES ${BOOST_URL_SOURCES})
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_SUPERPROJECT_VERSION)
target_include_directories(${target} PUBLIC "${PROJECT_SOURCE_DIR}/include")
else()
target_include_directories(${target}
PUBLIC
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
endif()
if (BOOST_URL_FIND_PACKAGE_BOOST)
target_link_libraries(${target}
PUBLIC
Boost::headers
)
else()
target_link_libraries(${target}
PUBLIC
Boost::align
Boost::assert
Boost::config
Boost::core
Boost::mp11
Boost::optional
Boost::static_assert
Boost::system
Boost::throw_exception
Boost::type_traits
Boost::variant2
)
endif()
if(BUILD_SHARED_LIBS)
target_compile_definitions(${target} PUBLIC BOOST_URL_DYN_LINK=1)
else()
target_compile_definitions(${target} PUBLIC BOOST_URL_STATIC_LINK=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>)
target_compile_definitions(${target} PRIVATE BOOST_URL_SOURCE)
endfunction()
file(GLOB_RECURSE BOOST_URL_HEADERS CONFIGURE_DEPENDS
include/boost/*.hpp
include/boost/*.ipp
include/boost/*.natvis
)
file(GLOB_RECURSE BOOST_URL_SOURCES CONFIGURE_DEPENDS src/*.cpp)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/include/boost PREFIX "" FILES ${BOOST_URL_HEADERS})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/src PREFIX "url" FILES ${BOOST_URL_SOURCES})
add_library(boost_url ${BOOST_URL_HEADERS} ${BOOST_URL_SOURCES})
add_library(Boost::url ALIAS boost_url)
boost_url_setup_properties(boost_url)
if(BUILD_SHARED_LIBS)
target_compile_definitions(boost_url PUBLIC BOOST_URL_DYN_LINK=1)
else()
target_compile_definitions(boost_url PUBLIC BOOST_URL_STATIC_LINK=1)
endif()
target_compile_definitions(boost_url PRIVATE BOOST_URL_SOURCE)
if(BOOST_URL_INSTALL AND NOT BOOST_SUPERPROJECT_VERSION)
install(TARGETS boost_url
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/boost
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING
PATTERN "*.hpp"
PATTERN "*.ipp"
)
endif()
if(BOOST_URL_BUILD_TESTS)
#######################################################
### Tests ###
#######################################################
if (BOOST_URL_BUILD_TESTS)
if (BOOST_URL_IS_ROOT)
include(CTest)
endif ()
add_subdirectory(test)
endif()
endif ()
if(BOOST_URL_BUILD_EXAMPLES)
if (BOOST_URL_BUILD_EXAMPLES)
add_subdirectory(example)
endif()
endif ()

View File

@@ -7,20 +7,12 @@
# Official repository: https://github.com/boostorg/url
#
source_group("" FILES
file_router.cpp
)
add_executable(file_router
file_router.cpp
)
set_property(TARGET file_router PROPERTY FOLDER "Examples")
add_executable(file_router file_router.cpp)
target_link_libraries(file_router PRIVATE Boost::url Boost::filesystem)
if (TARGET boost_filesystem AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
get_target_property(FS_IS_IMPORTED boost_filesystem IMPORTED)
if (FS_IS_IMPORTED)
target_compile_options(boost_filesystem PUBLIC -Wno-error=restrict)
endif()
target_compile_options(boost_filesystem PUBLIC $<$<BOOL:${FS_IS_IMPORTED}>:-Wno-error=restrict>)
endif()
source_group("" FILES file_router.cpp)
set_property(TARGET file_router PROPERTY FOLDER "Examples")

View File

@@ -7,13 +7,7 @@
# Official repository: https://github.com/boostorg/url
#
source_group("" FILES
finicky.cpp
)
add_executable(finicky
finicky.cpp
)
set_property(TARGET finicky PROPERTY FOLDER "Examples")
add_executable(finicky finicky.cpp)
target_link_libraries(finicky PRIVATE Boost::url Boost::json Boost::regex)
source_group("" FILES finicky.cpp)
set_property(TARGET finicky PROPERTY FOLDER "Examples")

View File

@@ -7,15 +7,7 @@
# Official repository: https://github.com/boostorg/url
#
source_group("" FILES
magnet.cpp
filter_view.hpp
)
add_executable(magnet
magnet.cpp
filter_view.hpp
)
set_property(TARGET magnet PROPERTY FOLDER "Examples")
add_executable(magnet magnet.cpp filter_view.hpp)
target_link_libraries(magnet PRIVATE Boost::url)
source_group("" FILES magnet.cpp filter_view.hpp)
set_property(TARGET magnet PROPERTY FOLDER "Examples")

View File

@@ -7,13 +7,7 @@
# Official repository: https://github.com/boostorg/url
#
source_group("" FILES
mailto.cpp
)
add_executable(mailto
mailto.cpp
)
set_property(TARGET mailto PROPERTY FOLDER "Examples")
add_executable(mailto mailto.cpp)
target_link_libraries(mailto PRIVATE Boost::url)
source_group("" FILES mailto.cpp)
set_property(TARGET mailto PROPERTY FOLDER "Examples")

View File

@@ -7,13 +7,7 @@
# Official repository: https://github.com/boostorg/url
#
source_group("" FILES
qrcode.cpp
)
add_executable(qrcode
qrcode.cpp
)
set_property(TARGET qrcode PROPERTY FOLDER "Examples")
add_executable(qrcode qrcode.cpp)
target_link_libraries(qrcode PRIVATE Boost::url)
source_group("" FILES qrcode.cpp)
set_property(TARGET qrcode PROPERTY FOLDER "Examples")

View File

@@ -7,13 +7,7 @@
# Official repository: https://github.com/boostorg/url
#
source_group("" FILES
suffix_list.cpp
)
add_executable(suffix_list
suffix_list.cpp
)
set_property(TARGET suffix_list PROPERTY FOLDER "Examples")
add_executable(suffix_list suffix_list.cpp)
target_link_libraries(suffix_list PRIVATE Boost::url)
source_group("" FILES suffix_list.cpp)
set_property(TARGET suffix_list PROPERTY FOLDER "Examples")

View File

@@ -8,16 +8,19 @@
# Official repository: https://github.com/boostorg/url
#
# Custom target for all tests
if(NOT TARGET boost_url_all_tests)
add_custom_target(boost_url_all_tests)
set_property(TARGET boost_url_all_tests PROPERTY FOLDER Dependencies)
endif()
set(SUITE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/../extra/test_main.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../extra/test_suite.hpp)
add_subdirectory(unit)
add_subdirectory(extra)
add_subdirectory(limits)
add_subdirectory(unit)
#add_subdirectory(wpt)
if (BOOST_URL_BUILD_FUZZERS)
if (BOOST_URL_BUILD_FUZZERS AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_subdirectory(fuzz)
endif()

View File

@@ -10,28 +10,17 @@ cmake_minimum_required(VERSION 3.5...3.16)
project(cmake_subdir_test LANGUAGES CXX)
if(BOOST_CI_INSTALL_TEST)
find_package(boost_url REQUIRED)
find_package(Boost CONFIG REQUIRED COMPONENTS url)
else()
set(DEPENDENCIES
# boostdep --brief url
# Primary dependencies
align assert config core mp11 optional static_assert system throw_exception type_traits variant2
# Secondary dependencies
detail move predef utility winapi preprocessor io
)
foreach (dep ${DEPENDENCIES})
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../../${dep}/CMakeLists.txt")
add_subdirectory(../../../${dep} boostorg/${dep})
endif()
endforeach()
set(BOOST_URL_BUILD_TESTS OFF CACHE BOOL "Build the tests." FORCE)
add_subdirectory(../.. boostorg/url)
endif()
add_executable(main main.cpp)
target_link_libraries(main Boost::url)
enable_testing()
add_test(NAME main COMMAND main)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
if (BUILD_TESTING)
enable_testing()
add_test(NAME main COMMAND main)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
endif()

View File

@@ -8,34 +8,18 @@
# Official repository: https://github.com/boostorg/url
#
set(TEST_FILES
Jamfile
test_suite.cpp
)
# Files
set(TEST_FILES Jamfile test_suite.cpp)
file(GLOB_RECURSE SUITE_FILES CONFIGURE_DEPENDS
../../extra/*.cpp
../../extra/*.hpp
../../extra/*.ipp
)
#set(SUITE_FILES ../../extra/test_main.cpp ../../extra/test_suite.hpp)
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${TEST_FILES})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/../../extra PREFIX "_extra" FILES ${SUITE_FILES})
# Test target
add_executable(boost_url_extra ${TEST_FILES} ${SUITE_FILES})
target_include_directories(boost_url_extra PRIVATE . ../../extra)
if (BOOST_URL_FIND_PACKAGE_BOOST)
target_link_libraries(boost_url_extra PRIVATE Boost::headers)
else()
target_link_libraries(boost_url_extra PRIVATE
Boost::align
Boost::config
Boost::core
Boost::optional
Boost::type_traits
Boost::system
Boost::variant2)
endif()
target_link_libraries(boost_url_extra PRIVATE Boost::url)
# Folders
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${TEST_FILES})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/../../extra PREFIX "_extra" FILES ${SUITE_FILES})
# CTest Target
add_test(NAME boost_url_extra COMMAND boost_url_extra)
add_dependencies(boost_url_all_tests boost_url_extra)

View File

@@ -5,23 +5,25 @@
# https://www.boost.org/LICENSE_1_0.txt
#
source_group("" FILES
fuzz_parse.cpp
)
# Files
source_group("" FILES fuzz_parse.cpp)
function(add_boost_url_fuzzer NAME SOURCE)
add_library(fuzzerlib_${NAME} ${SOURCE})
set_property(TARGET fuzzerlib_${NAME} PROPERTY FOLDER "fuzzing")
function(add_boost_url_fuzzer NAME SOURCE_FILES)
# Fuzzer library
add_library(fuzzerlib_${NAME} ${SOURCE_FILES})
target_link_libraries(fuzzerlib_${NAME} PRIVATE Boost::url)
set_property(TARGET fuzzerlib_${NAME} PROPERTY FOLDER "fuzzing")
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_executable(fuzzer_${NAME} ${SOURCE})
set_property(TARGET fuzzer_${NAME} PROPERTY FOLDER "fuzzing")
# Fuzzer executable
add_executable(fuzzer_${NAME} ${SOURCE_FILES})
target_link_libraries(fuzzer_${NAME} PRIVATE Boost::url)
target_compile_options(fuzzer_${NAME} PRIVATE -g -O1 -fsanitize=fuzzer,address,undefined)
target_link_options(fuzzer_${NAME} PRIVATE -fsanitize=fuzzer,address,undefined)
target_compile_options(fuzzer_${NAME} PRIVATE -g -O2 -fsanitize=fuzzer,address,undefined -fno-sanitize-recover=undefined)
target_link_libraries(fuzzer_${NAME} PRIVATE -fsanitize=fuzzer -fuse-ld=lld)
# Custom target to run fuzzer executable
add_custom_target(fuzz_${NAME} fuzzer_${NAME} -rss_limit_mb=8192 -max_total_time=30 -timeout=30 DEPENDS fuzz_${NAME})
set_property(TARGET fuzzer_${NAME} PROPERTY FOLDER "fuzzing")
endif ()
endfunction()

View File

@@ -7,30 +7,21 @@
# Official repository: https://github.com/boostorg/url
#
set(SUITE_FILES ../../extra/test_main.cpp ../../extra/test_suite.hpp)
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES limits.cpp Jamfile)
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/../../extra PREFIX "_extra" FILES ${SUITE_FILES})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/../../src PREFIX "url" FILES ${BOOST_URL_SOURCES})
# Boost.URL library variant for limits
add_library(boost_url_small_limits ${BOOST_URL_HEADERS} ${BOOST_URL_SOURCES})
boost_url_setup_properties(boost_url_small_limits)
target_compile_definitions(boost_url_small_limits PUBLIC BOOST_URL_MAX_SIZE=16 BOOST_URL_NO_LIB=1)
# Test target
add_executable(boost_url_limits limits.cpp Jamfile ${SUITE_FILES})
target_include_directories(boost_url_limits PRIVATE ../../include ../../extra ../../..)
if (BOOST_URL_FIND_PACKAGE_BOOST)
target_link_libraries(boost_url_limits PRIVATE Boost::headers)
else()
target_link_libraries(boost_url_limits PRIVATE
Boost::align
Boost::config
Boost::core
Boost::optional
Boost::type_traits
Boost::system
Boost::variant2)
endif()
target_link_libraries(boost_url_limits PRIVATE boost_url_small_limits)
# Folders
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES limits.cpp Jamfile)
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/../../extra PREFIX "_extra" FILES ${SUITE_FILES})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/../../src PREFIX "url" FILES ${BOOST_URL_SOURCES})
# CTest target
add_test(NAME boost_url_limits COMMAND boost_url_limits)
add_dependencies(boost_url_all_tests boost_url_limits)

View File

@@ -8,131 +8,39 @@
# Official repository: https://github.com/boostorg/url
#
# Global tests target
if(NOT TARGET tests)
add_custom_target(tests)
set_property(TARGET tests PROPERTY FOLDER Dependencies)
endif()
set(BOOST_URL_TESTS_FILES
CMakeLists.txt
Jamfile
test_rule.hpp
authority_view.cpp
doc_3_urls.cpp
doc_grammar.cpp
decode_view.cpp
encode.cpp
encoding_opts.cpp
error.cpp
error_types.cpp
format.cpp
grammar.cpp
host_type.cpp
ignore_case.cpp
ipv4_address.cpp
ipv6_address.cpp
natvis.cpp
optional.cpp
param.cpp
params_base.cpp
params_encoded_view.cpp
params_view.cpp
params_encoded_base.cpp
params_encoded_ref.cpp
params_ref.cpp
parse.cpp
parse_path.cpp
parse_query.cpp
pct_string_view.cpp
scheme.cpp
segments_base.cpp
segments_encoded_base.cpp
segments_encoded_ref.cpp
segments_encoded_view.cpp
segments_ref.cpp
segments_view.cpp
snippets.cpp
static_url.cpp
string_view.cpp
url.cpp
url_base.cpp
url_view.cpp
url_view_base.cpp
urls.cpp
variant.cpp
grammar/alnum_chars.cpp
grammar/alpha_chars.cpp
grammar/charset.cpp
grammar/ci_string.cpp
grammar/dec_octet_rule.cpp
grammar/delim_rule.cpp
grammar/digit_chars.cpp
grammar/grammar_error.cpp
grammar/grammar_parse.cpp
grammar/hexdig_chars.cpp
grammar/literal_rule.cpp
grammar/lut_chars.cpp
grammar/not_empty_rule.cpp
grammar/optional_rule.cpp
grammar/range_rule.cpp
grammar/recycled.cpp
grammar/string_token.cpp
grammar/string_view_base.cpp
grammar/token_rule.cpp
grammar/tuple_rule.cpp
grammar/type_traits.cpp
grammar/unsigned_rule.cpp
grammar/variant_rule.cpp
grammar/vchars.cpp
rfc/absolute_uri_rule.cpp
rfc/authority_rule.cpp
rfc/gen_delim_chars.cpp
rfc/ipv4_address_rule.cpp
rfc/ipv6_address_rule.cpp
rfc/origin_form_rule.cpp
rfc/pchars.cpp
rfc/pct_encoded_rule.cpp
rfc/query_rule.cpp
rfc/relative_ref_rule.cpp
rfc/reserved_chars.cpp
rfc/sub_delim_chars.cpp
rfc/unreserved_chars.cpp
rfc/uri_rule.cpp
rfc/uri_reference_rule.cpp
example/router/router.cpp
compat/ada.cpp
)
set(SUITE_FILES ../../extra/test_main.cpp ../../extra/test_suite.hpp)
# Files
file(GLOB_RECURSE BOOST_URL_TESTS_FILES CONFIGURE_DEPENDS *.cpp *.hpp)
list(APPEND BOOST_URL_TESTS_FILES CMakeLists.txt Jamfile)
set(EXAMPLE_FILES ../../example/router/impl/matches.cpp ../../example/router/detail/impl/router.cpp)
# Test target
add_executable(boost_url_tests ${BOOST_URL_TESTS_FILES} ${SUITE_FILES} ${EXAMPLE_FILES})
target_include_directories(boost_url_tests PRIVATE . ../../extra ../../example/router)
target_link_libraries(boost_url_tests PUBLIC Boost::url)
foreach (BOOST_URL_UNIT_TEST_LIBRARY ${BOOST_URL_UNIT_TEST_LIBRARIES})
target_link_libraries(boost_url_tests PUBLIC Boost::${BOOST_URL_UNIT_TEST_LIBRARY})
endforeach ()
# Compile options
target_compile_options(boost_url_tests PUBLIC $<$<CXX_COMPILER_ID:GNU>:-Wno-unused-but-set-variable>)
target_compile_options(boost_url_tests PUBLIC $<$<CXX_COMPILER_ID:GNU>:-Wno-unused-function>)
if (TARGET boost_filesystem AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
get_target_property(FS_IS_IMPORTED boost_filesystem IMPORTED)
target_compile_options(boost_filesystem PUBLIC $<$<BOOL:${FS_IS_IMPORTED}>:-Wno-error=restrict>)
endif()
# Folders
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${BOOST_URL_TESTS_FILES})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/../../extra PREFIX "_extra" FILES ${SUITE_FILES})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/../../example/router PREFIX "_router" FILES ${EXAMPLE_FILES})
add_executable(boost_url_tests ${BOOST_URL_TESTS_FILES} ${SUITE_FILES} ${EXAMPLE_FILES})
target_include_directories(boost_url_tests PRIVATE . ../../extra)
target_include_directories(boost_url_tests PRIVATE ../../example/router)
# The include dependencies are found in the CMakeLists.txt
# of the root project directory.
# See: BOOST_URL_UNIT_TEST_LIBRARIES
target_link_libraries(boost_url_tests PRIVATE
Boost::url
Boost::container
Boost::filesystem
Boost::unordered)
# CTest target
add_test(NAME boost_url_tests COMMAND boost_url_tests)
add_dependencies(boost_url_all_tests boost_url_tests)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(
boost_url_tests
PUBLIC
-Wno-unused-but-set-variable
-Wno-unused-function)
if (TARGET boost_filesystem AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
get_target_property(FS_IS_IMPORTED boost_filesystem IMPORTED)
if (FS_IS_IMPORTED)
target_compile_options(boost_filesystem PUBLIC -Wno-restrict)
endif()
endif()
endif()

View File

@@ -1,33 +0,0 @@
//
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@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/boostorg/url
//
// Test that header file is self-contained.
#include <boost/url/grammar/detail/copied_strings.hpp>
#include "test_suite.hpp"
namespace boost {
namespace urls {
namespace grammar {
struct copied_strings_test
{
void
run()
{
}
};
TEST_SUITE(
copied_strings_test,
"boost.url.grammar.copied_strings");
} // grammar
} // urls
} // boost

View File

@@ -1224,7 +1224,12 @@ struct url_test
resolve(base, base, base);
BOOST_TEST_CSTR_EQ(base.buffer(), "http://www.example.com/user/");
}
}
// complete string comparison
{
url_view u("https://user:p%61ss@www.%65xample.com:443/p%61th/to/page?k%65y=h%65llo%20world#fr%61gment");
BOOST_TEST_EQ(u, url_view("https://user:pass@www.example.com:443/path/to/page?key=hello%20world#fragment"));
}
}

View File

@@ -1,26 +0,0 @@
#
# Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
# Copyright (c) 2021 DMitry Arkhipov (grisumbras@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/boostorg/url
#
if(NOT TARGET tests)
add_custom_target(tests)
set_property(TARGET tests PROPERTY FOLDER Dependencies)
endif()
set(F
CMakeLists.txt
main.cpp
)
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "" FILES ${F})
add_executable(boost_wpt_tests ${F})
target_include_directories(boost_wpt_tests PRIVATE . ../../extra)
target_link_libraries(boost_wpt_tests PRIVATE Boost::url Boost::json)
add_test(NAME boost_url_tests COMMAND boost_url_tests)
add_dependencies(tests boost_url_tests)

View File

@@ -1,137 +0,0 @@
//
// Copyright (c) 2021 Vinnie Falco (vinnie dot falco at gmail dot 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/boostorg/url
//
#include <boost/json.hpp>
#include <boost/url.hpp>
#include "test_suite.hpp"
#include <cstdlib>
#include <iostream>
#include <stdexcept>
#include <fstream>
#include <string>
/*
Runs tests against the web-platform-tests set
of input vectors. Paths to zero or more files
must be provided on the command line. The names
have to match the original names from this
repo:
https://github.com/web-platform-tests/wpt/tree/master/url/resources
or
https://github.com/web-platform-tests/wpt/tree/982c7addc45086db44c44e5c442c97703409d675/url/resources
*/
namespace json = boost::json;
using namespace boost::urls;
test_suite::debug_stream Log(std::cout);
int fail_ = 0;
int total_ = 0;
json::value
read_json(char const* path)
{
std::ostringstream oss;
std::ifstream f(path);
oss << f.rdbuf();
std::string s = oss.str();
return json::parse(s);
}
string_view
filename(char const* path)
{
string_view s(path);
#ifdef _MSC_VER
auto n = s.find_last_of('\\');
#else
auto n = s.find_last_of('/');
#endif
if(n == string_view::npos)
return s;
return s.substr(n + 1);
}
void
do_setters_scheme(json::array const& ja)
{
for(auto const& jv : ja)
{
++total_;
auto href = jv.at("href").as_string();
url u = parse_uri_reference(href).value();
auto const& ex = jv.at("expected").as_object();
try
{
u.set_scheme(jv.at("new_value").as_string());
}
catch(std::exception const& e)
{
if(ex.at("href").as_string() != href)
{
Log << "caught exception: " << e.what() << std::endl;
Log << "set_scheme failed: " << href <<
", " << jv.at("new_value") << std::endl;
++fail_;
}
}
}
}
void
do_setters_user(json::array const& ja)
{
for(auto const& jv : ja)
{
++total_;
auto href = jv.at("href").as_string();
url u = parse_uri_reference(href).value();
// VFALCO TODO
}
}
void
do_setters_tests(json::value const& jv)
{
for(auto const& v : jv.as_object())
{
if(v.key() == "protocol")
do_setters_scheme(v.value().as_array());
}
}
int main(int argc, char** argv)
{
for(int i = 1; i < argc; ++i)
{
try
{
auto jv = read_json(argv[i]);
auto s = filename(argv[i]);
Log << "file: " << s << std::endl;
if(s == "setters_tests.json")
do_setters_tests(jv);
}
catch(std::exception const& e)
{
Log << "caught exception: " << e.what() << std::endl;
}
}
if(fail_ == 0)
Log << total_ << " total success" << std::endl;
else
Log << fail_ << " of " << total_ << " failures" << std::endl;
if(fail_ > 0)
return EXIT_FAILURE;
return EXIT_SUCCESS;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff