vcpkg/scripts/boost/generate-ports.ps1
2020-09-04 23:35:38 -07:00

440 lines
14 KiB
PowerShell

[CmdletBinding()]
param (
$libraries = @(),
$version = "1.73.0",
$portsDir = $null
)
$scriptsDir = split-path -parent $MyInvocation.MyCommand.Definition
if ($null -eq $portsDir)
{
$portsDir = "$scriptsDir/../../ports"
}
# Optionally clear this array when moving to a new boost version
$port_versions = @{
"asio" = 1;
"context" = 1;
"coroutine" = 1;
"fiber" = 1;
"filesystem" = 1;
"graph-parallel" = 1;
"iostreams" = 1;
"locale" = 1;
"log" = 1;
"mpi" = 1;
"parameter-python" = 1;
"poly-collection" = 1;
"python" = 1;
"safe-numerics" = 1;
"stacktrace" = 1;
"test" = 1;
"wave" = 1;
"boost" = 1
}
$per_port_data = @{
"fiber" = @{ "supports" = "windows&!uwp&!arm" };
"filesystem" = @{ "supports" = "!uwp" };
"iostreams" = @{ "supports" = "!uwp" };
"context" = @{ "supports" = "!uwp" };
"stacktrace" = @{ "supports" = "!uwp" };
"coroutine" = @{ "supports" = "!arm&!uwp" };
"test" = @{ "supports" = "!uwp" };
"wave" = @{ "supports" = "!uwp" };
"log" = @{ "supports" = "!uwp" };
"locale" = @{
"supports" = "!uwp";
"features" = @(
"Feature: icu"
"Build-Depends: icu"
"Description: ICU backend for Boost.Locale"
)};
"python" = @{
"supports" = "!uwp&!(arm&windows)";
"features" = @(
"Feature: python2"
"Build-Depends: python2 (windows)"
"Description: Build with Python2 support"
)};
"regex" = @{ "features" = @(
"Feature: icu"
"Build-Depends: icu"
"Description: ICU backend for Boost.Regex"
)}
}
function TransformReference()
{
param (
[string]$library
)
if ($per_port_data[$library].supports)
{
"$library ($($per_port_data[$library].supports))"
}
else
{
"$library"
}
}
function Generate()
{
param (
[string]$Name,
[string]$PortName,
[string]$Hash,
[bool]$NeedsBuild,
$Depends = @()
)
$controlDeps = ($Depends | sort) -join ", "
mkdir "$portsDir/boost-$PortName" -erroraction SilentlyContinue | out-null
$controlLines = @(
"# Automatically generated by boost-vcpkg-helpers/generate-ports.ps1"
"Source: boost-$PortName"
"Version: $version"
)
if ($port_versions[$PortName])
{
$controlLines += @("Port-Version: $($port_versions[$PortName])")
}
$controlLines += @(
"Build-Depends: $controlDeps"
"Homepage: https://github.com/boostorg/$Name"
"Description: Boost $Name module"
)
if ($per_port_data[$PortName].supports)
{
$controlLines += @("Supports: $($per_port_data[$PortName].supports)")
}
if ($per_port_data[$PortName].features)
{
$controlLines += @("") + $per_port_data[$PortName].features
}
$controlLines | out-file -enc ascii "$portsDir/boost-$PortName/CONTROL"
$portfileLines = @(
"# Automatically generated by boost-vcpkg-helpers/generate-ports.ps1"
""
)
if ($PortName -eq "system")
{
$portfileLines += @(
"vcpkg_buildpath_length_warning(37)"
""
)
}
$portfileLines += @(
"vcpkg_from_github("
" OUT_SOURCE_PATH SOURCE_PATH"
" REPO boostorg/$Name"
" REF boost-$version"
" SHA512 $Hash"
" HEAD_REF master"
)
$patches = ls $portsDir/boost-$PortName/*.patch
if ($patches.Count -eq 0)
{
}
elseif ($patches.Count -eq 1)
{
$portfileLines += @(" PATCHES $($patches.name)")
}
else
{
$portfileLines += @(" PATCHES")
foreach ($patch in $patches)
{
$portfileLines += @(" $($patches.name)")
}
}
$portfileLines += @(
")"
""
)
if (Test-Path "$scriptsDir/post-source-stubs/$PortName.cmake")
{
$portfileLines += @(get-content "$scriptsDir/post-source-stubs/$PortName.cmake")
}
if ($NeedsBuild)
{
$portfileLines += @(
"include(`${CURRENT_INSTALLED_DIR}/share/boost-build/boost-modular-build.cmake)"
)
# b2-options.cmake contains port-specific build options
if (Test-Path "$portsDir/boost-$PortName/b2-options.cmake")
{
$portfileLines += @(
"boost_modular_build("
" SOURCE_PATH `${SOURCE_PATH}"
" BOOST_CMAKE_FRAGMENT `"`${CMAKE_CURRENT_LIST_DIR}/b2-options.cmake`""
")"
)
}
else
{
$portfileLines += @(
"boost_modular_build(SOURCE_PATH `${SOURCE_PATH})"
)
}
}
$portfileLines += @(
"include(`${CURRENT_INSTALLED_DIR}/share/boost-vcpkg-helpers/boost-modular-headers.cmake)"
"boost_modular_headers(SOURCE_PATH `${SOURCE_PATH})"
)
if (Test-Path "$scriptsDir/post-build-stubs/$PortName.cmake")
{
$portfileLines += @(get-content "$scriptsDir/post-build-stubs/$PortName.cmake")
}
$portfileLines | out-file -enc ascii "$portsDir/boost-$PortName/portfile.cmake"
}
if (!(Test-Path "$scriptsDir/boost"))
{
"Cloning boost..."
pushd $scriptsDir
try
{
git clone https://github.com/boostorg/boost --branch boost-$version
}
finally
{
popd
}
}
else
{
pushd $scriptsDir/boost
try
{
git fetch
git checkout -f boost-$version
}
finally
{
popd
}
}
$libraries_found = ls $scriptsDir/boost/libs -directory | % name | % {
if ($_ -match "numeric")
{
"numeric_conversion"
"interval"
"odeint"
"ublas"
"safe_numerics"
}
elseif ($_ -eq "headers")
{
}
else
{
$_
}
}
mkdir $scriptsDir/downloads -erroraction SilentlyContinue | out-null
if ($libraries.Length -eq 0)
{
$libraries = $libraries_found
}
$libraries_in_boost_port = @()
foreach ($library in $libraries)
{
"Handling boost/$library..."
$archive = "$scriptsDir/downloads/$library-boost-$version.tar.gz"
if (!(Test-Path $archive))
{
"Downloading boost/$library..."
& @(vcpkg fetch aria2)[-1] "https://github.com/boostorg/$library/archive/boost-$version.tar.gz" -d "$scriptsDir/downloads" -o "$library-boost-$version.tar.gz"
}
$hash = vcpkg hash $archive
$unpacked = "$scriptsDir/libs/$library-boost-$version"
if (!(Test-Path $unpacked))
{
"Unpacking boost/$library..."
mkdir $scriptsDir/libs -erroraction SilentlyContinue | out-null
pushd $scriptsDir/libs
try
{
cmake -E tar xf $archive
}
finally
{
popd
}
}
pushd $unpacked
try
{
$groups = $(
findstr /si /C:"include <boost/" include/*
findstr /si /C:"include <boost/" src/*
) |
% { $_ `
-replace "^[^:]*:","" `
-replace "boost/numeric/conversion/","boost/numeric_conversion/" `
-replace "boost/functional/hash.hpp","boost/container_hash/hash.hpp" `
-replace "boost/detail/([^/]+)/","boost/`$1/" `
-replace " *# *include *<boost/([a-zA-Z0-9\._]*)(/|>).*", "`$1" `
-replace "/|\.hp?p?| ","" } | group | % name | % {
# mappings
Write-Verbose "${library}: $_"
if ($_ -match "aligned_storage") { "type_traits" }
elseif ($_ -match "noncopyable|ref|swap|get_pointer|checked_delete|visit_each") { "core" }
elseif ($_ -eq "type") { "core" }
elseif ($_ -eq "concept") { "concept_check" }
elseif ($_ -match "unordered_") { "unordered" }
elseif ($_ -match "cstdint|integer_fwd|integer_traits") { "integer" }
elseif ($_ -match "call_traits|operators|current_function|cstdlib|next_prior|compressed_pair") { "utility" }
elseif ($_ -match "^version|^workaround") { "config" }
elseif ($_ -match "enable_shared_from_this|shared_ptr|make_shared|make_unique|intrusive_ptr|scoped_ptr|pointer_cast|pointer_to_other|weak_ptr|shared_array|scoped_array") { "smart_ptr" }
elseif ($_ -match "iterator_adaptors|generator_iterator|pointee") { "iterator" }
elseif ($_ -eq "regex_fwd") { "regex" }
elseif ($_ -eq "make_default") { "convert" }
elseif ($_ -eq "foreach_fwd") { "foreach" }
elseif ($_ -eq "cerrno") { "system" }
elseif ($_ -eq "circular_buffer_fwd") { "circular_buffer" }
elseif ($_ -eq "archive") { "serialization" }
elseif ($_ -match "none|none_t") { "optional" }
elseif ($_ -eq "limits") { "compatibility" }
elseif ($_ -match "cstdfloat|math_fwd") { "math" }
elseif ($_ -eq "cast") { "conversion"; "numeric_conversion" } # DEPRECATED header file, includes <boost/polymorphic_cast.hpp> and <boost/numeric/conversion/cast.hpp>
elseif ($_ -match "polymorphic_cast|implicit_cast") { "conversion" }
elseif ($_ -eq "nondet_random") { "random" }
elseif ($_ -eq "memory_order") { "atomic" }
elseif ($_ -match "blank|blank_fwd|numeric_traits") { "detail" }
elseif ($_ -match "is_placeholder|mem_fn") { "bind" }
elseif ($_ -eq "exception_ptr") { "exception" }
elseif ($_ -match "multi_index_container|multi_index_container_fwd") { "multi_index" }
elseif ($_ -eq "lexical_cast") { "lexical_cast"; "math" }
elseif ($_ -match "token_iterator|token_functions") { "tokenizer" }
elseif ($_ -eq "numeric" -and $library -notmatch "numeric_conversion|interval|odeint|ublas") { "numeric_conversion"; "interval"; "odeint"; "ublas" }
elseif ($_ -eq "io_fwd") { "io" }
else { $_ }
} | group | % name | ? { $_ -ne $library }
#"`nFor ${library}:"
" [known] " + $($groups | ? { $libraries_found -contains $_ })
" [unknown] " + $($groups | ? { $libraries_found -notcontains $_ })
$deps = @($groups | ? { $libraries_found -contains $_ })
$deps = @($deps | ? {
# Boost contains cycles, so remove a few dependencies to break the loop.
(($library -notmatch "core|assert|mpl|detail|throw_exception|type_traits|^exception") -or ($_ -notmatch "utility")) `
-and `
(($library -notmatch "assert") -or ($_ -notmatch "integer"))`
-and `
(($library -notmatch "range") -or ($_ -notmatch "algorithm"))`
-and `
(($library -ne "config") -or ($_ -notmatch "integer"))`
-and `
(($library -notmatch "multiprecision") -or ($_ -notmatch "random|math"))`
-and `
(($library -notmatch "lexical_cast") -or ($_ -notmatch "math"))`
-and `
(($library -notmatch "functional") -or ($_ -notmatch "function"))`
-and `
(($library -notmatch "detail") -or ($_ -notmatch "static_assert|integer|mpl|type_traits"))`
-and `
($_ -notmatch "mpi")`
-and `
(($library -notmatch "spirit") -or ($_ -notmatch "serialization"))`
-and `
(($library -notmatch "throw_exception") -or ($_ -notmatch "^exception"))`
-and `
(($library -notmatch "iostreams") -or ($_ -notmatch "random"))`
-and `
(($library -notmatch "utility|concept_check") -or ($_ -notmatch "iterator"))
} | % { $_ -replace "_","-" } | % {
"boost-" + (TransformReference $_)
})
$deps += @("boost-vcpkg-helpers")
$needsBuild = $false
if ((Test-Path $unpacked/build/Jamfile.v2) -and $library -ne "metaparse" -and $library -ne "graph_parallel")
{
$deps += @("boost-build", "boost-modular-build-helper")
$needsBuild = $true
}
if ($library -eq "python")
{
$deps += @("python3")
$needsBuild = $true
}
elseif ($library -eq "iostreams")
{
$deps += @("zlib", "bzip2", "liblzma", "zstd")
}
elseif ($library -eq "locale")
{
$deps += @("libiconv (!uwp&!windows)", "boost-system")
}
elseif ($library -eq "asio")
{
$deps += @("openssl")
}
elseif ($library -eq "mpi")
{
$deps += @("mpi")
}
$portName = $library -replace "_","-"
Generate `
-Name $library `
-PortName $portName `
-Hash $hash `
-Depends $deps `
-NeedsBuild $needsBuild
$libraries_in_boost_port += @(TransformReference $portName)
}
finally
{
popd
}
}
if ($libraries_in_boost_port.length -gt 1) {
# Generate master boost control file which depends on each individual library
# mpi is excluded due to it having a dependency on msmpi/openmpi
$boostDependsList = @($libraries_in_boost_port | % { "boost-$_" -replace "python","python (!v120)" } | ? { $_ -notmatch "boost-mpi" }) -join ", "
@(
"# Automatically generated by boost-vcpkg-helpers/generate-ports.ps1"
"Source: boost"
"Version: $version"
"Port-Version: $($port_versions.boost)"
"Homepage: https://boost.org"
"Description: Peer-reviewed portable C++ source libraries"
"Build-Depends: $boostDependsList"
""
"Feature: mpi"
"Description: Build with MPI support"
"Build-Depends: boost-mpi"
) | out-file -enc ascii $portsDir/boost/CONTROL
"set(VCPKG_POLICY_EMPTY_PACKAGE enabled)`n" | out-file -enc ascii $portsDir/boost/portfile.cmake
}
return