Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 157 additions & 0 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,160 @@ jobs:
${{ runner.temp }}/${{ env.BASELINE_FILE }}
${{ runner.temp }}/${{ env.COMPARE_FILE }}
${{ runner.temp }}/${{ env.COMPARE_OUT_FILE }}
crossrepo:
name: Cross-Repo Validation
runs-on: ubuntu-latest
container:
image: swift:6.3-jammy
steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Install apt dependencies
run: apt-get -qq update && apt-get -qq -y install curl ninja-build
- name: Install CMake 3.30.2
run: |
ARCH=`uname -m`
curl -sL https://github.com/Kitware/CMake/releases/download/v3.30.2/cmake-3.30.2-linux-$ARCH.tar.gz -O
tar xzf cmake-3.30.2-linux-$ARCH.tar.gz
export PATH="`pwd`/cmake-3.30.2-linux-$ARCH/bin:$PATH"
echo "PATH=$PATH" >> $GITHUB_ENV
cmake --version
- name: Compare CMakeLists.txt against swiftlang/swift/Runtimes/Supplemental
id: compare
env:
UPSTREAM_DIR: https://raw.githubusercontent.com/swiftlang/swift/refs/heads/main/Runtimes/Supplemental/StringProcessing
MODULES: _StringProcessing _RegexParser
shell: bash
run: |
set -u

# `-f` so a file moving upstream reports a fetch error rather than
# diffing against a 404 page.
for module in $MODULES; do
if ! curl -fsSL "$UPSTREAM_DIR/$module/CMakeLists.txt" \
-o "upstream-$module-CMakeLists.txt"; then
echo "result=fetch-failed" >> "$GITHUB_OUTPUT"
echo "Could not fetch $module/CMakeLists.txt from swiftlang/swift."
exit 1
fi
done

: > "$RUNNER_TEMP/cmake-diff.txt"
status=0
for module in $MODULES; do
if ! diff -u \
--label "swiftlang/swift: Runtimes/Supplemental/StringProcessing/$module/CMakeLists.txt" \
--label "this repo: Sources/$module/CMakeLists.txt" \
"upstream-$module-CMakeLists.txt" \
"Sources/$module/CMakeLists.txt" \
>> "$RUNNER_TEMP/cmake-diff.txt"; then
status=1
fi
done

if [ "$status" -eq 0 ]; then
echo "result=match" >> "$GITHUB_OUTPUT"
echo "Both CMakeLists.txt files match swiftlang/swift."
else
echo "result=differs" >> "$GITHUB_OUTPUT"
cat "$RUNNER_TEMP/cmake-diff.txt"
fi
exit "$status"
- name: Configure CMake
id: configure
if: ${{ !cancelled() }}
run: cmake -G Ninja -S Sources -B build -DCMAKE_BUILD_TYPE=Release
- name: Build
id: build
if: ${{ !cancelled() }}
run: cmake --build build
- name: Verdict
if: ${{ always() }}
env:
COMPARE_OUTCOME: ${{ steps.compare.outcome }}
COMPARE_RESULT: ${{ steps.compare.outputs.result }}
CONFIGURE_OUTCOME: ${{ steps.configure.outcome }}
BUILD_OUTCOME: ${{ steps.build.outcome }}
shell: bash
run: |
set -u

# Report to the step log and to the job summary page.
emit() { printf '%s\n' "$@" | tee -a "$GITHUB_STEP_SUMMARY"; }

failed=0

# --- the CMake build ---
if [ "$CONFIGURE_OUTCOME" = failure ] || [ "$BUILD_OUTCOME" = failure ]; then
failed=1
if [ "$CONFIGURE_OUTCOME" = failure ]; then
stage='CMake configuration'
else
stage='CMake build'
fi
emit \
"## :x: $stage failed" \
'' \
'The CMake build of `_RegexParser` and `_StringProcessing` is broken.' \
"See the \"$stage\" step above for the output." \
''
fi

# --- the comparison against swiftlang/swift ---
case "${COMPARE_RESULT:-}" in
match)
;;
differs)
failed=1
emit \
'## :warning: `CMakeLists.txt` differs from swiftlang/swift' \
'' \
'<details><summary>Diff to apply upstream</summary>' \
'' \
'```diff'
tee -a "$GITHUB_STEP_SUMMARY" < "$RUNNER_TEMP/cmake-diff.txt"
emit '```' '' '</details>' ''
;;
fetch-failed)
failed=1
emit \
'## :x: Could not fetch the upstream `CMakeLists.txt` files'
;;
*)
failed=1
emit \
"## :x: Comparison did not complete (outcome: ${COMPARE_OUTCOME:-unknown})"
;;
esac

# --- all clear ---
if [ "$failed" -eq 0 ]; then
emit \
'## :white_check_mark: Cross-repo validation passed'
fi

exit "$failed"
required:
name: Required
runs-on: ubuntu-latest
needs:
- tests
- soundness
- bench
if: always() # Runs even if previous jobs fail so it can evaluate them
steps:
- name: Install required tools
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends coreutils jq
- name: Check upstream job statuses
env:
NEEDS_JSON: ${{ toJSON(needs) }}
run: |
failed=$(printf '%s' "$NEEDS_JSON" | jq -r 'to_entries | map(select(.value.result != "success")) | .[] | "\(.key): \(.value.result)"')
if [ -n "$failed" ]; then
echo "The following required jobs did not succeed:"
printf '%s\n' "$failed"
exit 1
fi
echo "All required jobs succeeded."
7 changes: 2 additions & 5 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
// swift-tools-version:6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let availabilityDefinition = PackageDescription.SwiftSetting.unsafeFlags([
Expand Down Expand Up @@ -46,7 +44,6 @@ let publicStdlibSettings: [PackageDescription.SwiftSetting] = [
let package = Package(
name: "swift-experimental-string-processing",
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "_StringProcessing",
targets: ["_StringProcessing"]),
Expand All @@ -69,11 +66,10 @@ let package = Package(
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
name: "_RegexParser",
dependencies: [],
exclude: ["CMakeLists.txt"],
packageAccess: false,
swiftSettings: privateStdlibSettings),
.testTarget(
Expand All @@ -90,6 +86,7 @@ let package = Package(
"_RegexParser",
"_CUnicode",
],
exclude: ["CMakeLists.txt", "_CUnicode"],
packageAccess: false,
swiftSettings: publicStdlibSettings),
.target(
Expand Down
92 changes: 92 additions & 0 deletions Sources/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#===-----------------------------------------------------------------------===#
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2026 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See https://swift.org/LICENSE.txt for license information
#
#===-----------------------------------------------------------------------===#

# NOTE: This build configuration is only to validate that the settings
# match between the swiftlang/swift project and this one, not for
# producing installable libraries.

cmake_minimum_required(VERSION 3.26)

project(SwiftStringProcessing
VERSION 1.0.0
LANGUAGES C Swift)

include(GNUInstallDirs)

set(CMAKE_Swift_LANGUAGE_VERSION 5)
set(CMAKE_C_STANDARD 99)

option(BUILD_SHARED_LIBS "Build shared libraries" YES)

set(SwiftStringProcessing_INSTALL_LIBDIR "${CMAKE_INSTALL_LIBDIR}/swift"
CACHE STRING "Destination for the built libraries")

#===-----------------------------------------------------------------------===#
# Compiler flags
#===-----------------------------------------------------------------------===#

add_compile_options(
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -disable-implicit-concurrency-module-import>"
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -disable-implicit-string-processing-module-import>")

foreach(definition
"SwiftStdlib 5.7:macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0"
"SwiftStdlib 5.8:macOS 13.3, iOS 16.4, watchOS 9.4, tvOS 16.4"
"SwiftStdlib 5.9:macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0"
"SwiftStdlib 6.0:macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0"
"SwiftStdlib 6.1:macOS 15.4, iOS 18.4, watchOS 11.4, tvOS 18.4, visionOS 2.4"
"SwiftStdlib 6.2:macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0"
"SwiftStdlib 6.3:macOS 26.4, iOS 26.4, watchOS 26.4, tvOS 26.4, visionOS 26.4"
"SwiftStdlib 6.4:macOS 27.0, iOS 27.0, watchOS 27.0, tvOS 27.0, visionOS 27.0"
"SwiftStdlib 6.5:macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, visionOS 9999")
add_compile_options(
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -define-availability -Xfrontend \"${definition}\">")
endforeach()

add_compile_options(
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-enable-upcoming-feature MemberImportVisibility>")

#===-----------------------------------------------------------------------===#
# Shims for the runtime build
#===-----------------------------------------------------------------------===#
#
# The module files call into helpers that only exist in the Swift runtime's
# build. Define just enough here for them to resolve. Each shim below is a no-op,
# so this configuration builds and links the two modules but does *not* produce
# an installable stdlib component.

# In the runtime build `swiftCore` is a real target. Standalone, the stdlib
# comes from the toolchain and needs no explicit link.
if(NOT TARGET swiftCore)
add_library(swiftCore INTERFACE)
endif()

# Library evolution and `.swiftinterface` emission.
function(emit_swift_interface target)
endfunction()

function(install_swift_interface target)
endfunction()

# Darwin packaging metadata, irrelevant to a standalone build.
function(generate_plist name version target)
endfunction()

function(embed_manifest target)
endfunction()

#===-----------------------------------------------------------------------===#
# Modules
#===-----------------------------------------------------------------------===#

# Order matters: _StringProcessing links _RegexParser.
add_subdirectory(_RegexParser)
add_subdirectory(_StringProcessing)
49 changes: 49 additions & 0 deletions Sources/_RegexParser/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
add_library(swift_RegexParser
Regex/TreeProtocols.swift
Regex/Parse/DelimiterLexing.swift
Regex/Parse/Source.swift
Regex/Parse/CharacterPropertyClassification.swift
Regex/Parse/LexicalAnalysis.swift
Regex/Parse/SyntaxOptions.swift
Regex/Parse/CaptureList.swift
Regex/Parse/CompilerInterface.swift
Regex/Parse/CaptureStructure.swift
Regex/Parse/Parse.swift
Regex/Parse/SourceLocation.swift
Regex/Parse/Diagnostics.swift
Regex/Parse/Sema.swift
Regex/Printing/RenderRanges.swift
Regex/Printing/PrettyPrinter.swift
Regex/Printing/PrintAsCanonical.swift
Regex/Printing/DumpAST.swift
Regex/AST/ASTAction.swift
Regex/AST/AST.swift
Regex/AST/CustomCharClass.swift
Regex/AST/Quantification.swift
Regex/AST/Conditional.swift
Regex/AST/MatchingOptions.swift
Regex/AST/ASTProtocols.swift
Regex/AST/Group.swift
Regex/AST/Atom.swift
Utility/TypeConstruction.swift
Utility/Misc.swift
Utility/AllScalars.swift
Utility/Errors.swift
Utility/MissingUnicode.swift)

target_link_libraries(swift_RegexParser PRIVATE
swiftCore
$<$<BOOL:${SwiftSwiftDirectRuntime_FOUND}>:swiftSwiftDirectRuntime>)

set_target_properties(swift_RegexParser PROPERTIES
Swift_MODULE_NAME _RegexParser)

install(TARGETS swift_RegexParser
ARCHIVE DESTINATION "${SwiftStringProcessing_INSTALL_LIBDIR}"
LIBRARY DESTINATION "${SwiftStringProcessing_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
emit_swift_interface(swift_RegexParser)
install_swift_interface(swift_RegexParser)

generate_plist(swiftRegexParser "${CMAKE_PROJECT_VERSION}" swift_RegexParser)
embed_manifest(swift_RegexParser)
Loading
Loading