Add CMake build with Conan and Ninja

This commit is contained in:
2025-12-24 17:45:43 +00:00
parent cb0b06cd30
commit 1d5cdfb6e4
9 changed files with 205 additions and 715 deletions

View File

@@ -1,734 +1,63 @@
name: Tests name: CMake
on: on:
workflow_dispatch:
push: push:
branches: branches: [main, "3.*"]
- 'main'
- '3.*'
pull_request: pull_request:
branches: branches: [main, "3.*"]
- 'main' workflow_dispatch:
- '3.*'
permissions: permissions:
contents: read contents: read
concurrency:
# https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#concurrency
# 'group' must be a key uniquely representing a PR or push event.
# github.workflow is the workflow name
# github.actor is the user invoking the workflow
# github.head_ref is the source branch of the PR or otherwise blank
# github.run_id is a unique number for the current run
group: ${{ github.workflow }}-${{ github.actor }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
env:
FORCE_COLOR: 1
jobs: jobs:
build-context: build:
name: Change detection
# To use boolean outputs from this job, parse them as JSON.
# Here's some examples:
#
# if: fromJSON(needs.build-context.outputs.run-docs)
#
# ${{
# fromJSON(needs.build-context.outputs.run-tests)
# && 'truthy-branch'
# || 'falsy-branch'
# }}
#
uses: ./.github/workflows/reusable-context.yml
check-docs:
name: Docs
needs: build-context
if: fromJSON(needs.build-context.outputs.run-docs)
uses: ./.github/workflows/reusable-docs.yml
check-abi:
name: 'Check if the ABI has changed'
runs-on: ubuntu-22.04 # 24.04 causes spurious errors
needs: build-context
if: needs.build-context.outputs.run-tests == 'true'
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install dependencies
run: |
sudo ./.github/workflows/posix-deps-apt.sh
sudo apt-get install -yq abigail-tools
- name: Build CPython
env:
CFLAGS: -g3 -O0
run: |
# Build Python with the libpython dynamic library
./configure --enable-shared
make -j4
- name: Check for changes in the ABI
id: check
run: |
if ! make check-abidump; then
echo "Generated ABI file is not up to date."
echo "Please add the release manager of this branch as a reviewer of this PR."
echo ""
echo "The up to date ABI file should be attached to this build as an artifact."
echo ""
echo "To learn more about this check: https://devguide.python.org/getting-started/setup-building/index.html#regenerate-the-abi-dump"
echo ""
exit 1
fi
- name: Generate updated ABI files
if: ${{ failure() && steps.check.conclusion == 'failure' }}
run: |
make regen-abidump
- uses: actions/upload-artifact@v4
name: Publish updated ABI files
if: ${{ failure() && steps.check.conclusion == 'failure' }}
with:
name: abi-data
path: ./Doc/data/*.abi
check-autoconf-regen:
name: 'Check if Autoconf files are up to date'
# Don't use ubuntu-latest but a specific version to make the job
# reproducible: to get the same tools versions (autoconf, aclocal, ...)
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
container: defaults:
image: ghcr.io/python/autoconf:2025.01.02.12581854023 run:
timeout-minutes: 60 shell: bash
needs: build-context
if: needs.build-context.outputs.run-tests == 'true'
steps: steps:
- name: Install Git
run: |
apt update && apt install git -yq
git config --global --add safe.directory "$GITHUB_WORKSPACE"
- uses: actions/checkout@v5 - uses: actions/checkout@v5
with:
fetch-depth: 1
persist-credentials: false
- name: Check Autoconf and aclocal versions
run: |
grep "Generated by GNU Autoconf 2.72" configure
grep "aclocal 1.16.5" aclocal.m4
grep -q "runstatedir" configure
grep -q "PKG_PROG_PKG_CONFIG" aclocal.m4
- name: Regenerate autoconf files
# Same command used by Tools/build/regen-configure.sh ($AUTORECONF)
run: autoreconf -ivf -Werror
- name: Check for changes
run: |
git add -u
changes=$(git status --porcelain)
# Check for changes in regenerated files
if test -n "$changes"; then
echo "Generated files not up to date."
echo "Perhaps you forgot to run make regen-configure ;)"
echo "configure files must be regenerated with a specific version of autoconf."
echo "$changes"
echo ""
git diff --staged || true
exit 1
fi
check-generated-files: - name: Set up Python
name: 'Check if generated files are up to date' uses: actions/setup-python@v5
# Don't use ubuntu-latest but a specific version to make the job
# reproducible: to get the same tools versions (autoconf, aclocal, ...)
runs-on: ubuntu-24.04
timeout-minutes: 60
needs: build-context
if: needs.build-context.outputs.run-tests == 'true'
steps:
- uses: actions/checkout@v5
with: with:
persist-credentials: false python-version: "3.12"
- uses: actions/setup-python@v5
with: - name: Install build tooling
python-version: '3.x' run: |
- name: Runner image version python -m pip install --upgrade pip
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV" python -m pip install "conan==2.5.0"
- name: Restore config.cache sudo apt-get update
sudo apt-get install -y ninja-build
- name: Cache Conan downloads
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
path: config.cache path: ~/.conan2
# Include env.pythonLocation in key to avoid changes in environment when setup-python updates Python key: conan-${{ runner.os }}-${{ hashFiles('conanfile.txt') }}
key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ needs.build-context.outputs.config-hash }}-${{ env.pythonLocation }} restore-keys: |
- name: Install dependencies conan-${{ runner.os }}-
run: sudo ./.github/workflows/posix-deps-apt.sh
- name: Add ccache to PATH - name: Prepare Conan profile
run: echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV" run: conan profile detect --force
- name: Configure ccache action
uses: hendrikmuhs/ccache-action@v1.2 - name: Install Conan toolchain
with: run: conan install . --output-folder=build --build=missing
save: false
- name: Configure CPython - name: Configure CMake (Ninja)
run: | run: |
# Build Python with the libpython dynamic library source build/conanrun.sh
./configure --config-cache --with-pydebug --enable-shared cmake -S . -B build -G Ninja \
- name: Build CPython -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE=Release
- name: Build
run: | run: |
make -j4 regen-all source build/conanrun.sh
make regen-stdlib-module-names regen-sbom regen-unicodedata cmake --build build --config Release
- name: Check for changes
- name: Test
run: | run: |
git add -u source build/conanrun.sh
changes=$(git status --porcelain) ctest --test-dir build --output-on-failure --build-config Release
# Check for changes in regenerated files
if test -n "$changes"; then
echo "Generated files not up to date."
echo "Perhaps you forgot to run make regen-all or build.bat --regen. ;)"
echo "configure files must be regenerated with a specific version of autoconf."
echo "$changes"
echo ""
git diff --staged || true
exit 1
fi
- name: Check exported libpython symbols
run: make smelly
- name: Check limited ABI symbols
run: make check-limited-abi
- name: Check for unsupported C global variables
if: github.event_name == 'pull_request' # $GITHUB_EVENT_NAME
run: make check-c-globals
build-windows:
name: >-
Windows
${{ fromJSON(matrix.free-threading) && '(free-threading)' || '' }}
needs: build-context
if: fromJSON(needs.build-context.outputs.run-windows-tests)
strategy:
fail-fast: false
matrix:
arch:
- x64
- Win32
- arm64
free-threading:
- false
- true
exclude:
# Skip Win32 on free-threaded builds
- { arch: Win32, free-threading: true }
uses: ./.github/workflows/reusable-windows.yml
with:
arch: ${{ matrix.arch }}
free-threading: ${{ matrix.free-threading }}
build-windows-msi:
name: >- # ${{ '' } is a hack to nest jobs under the same sidebar category
Windows MSI${{ '' }}
needs: build-context
if: fromJSON(needs.build-context.outputs.run-windows-msi)
strategy:
fail-fast: false
matrix:
arch:
- x86
- x64
- arm64
uses: ./.github/workflows/reusable-windows-msi.yml
with:
arch: ${{ matrix.arch }}
build-macos:
name: >-
macOS
${{ fromJSON(matrix.free-threading) && '(free-threading)' || '' }}
needs: build-context
if: needs.build-context.outputs.run-tests == 'true'
strategy:
fail-fast: false
matrix:
# Cirrus and macos-14 are M1, macos-13 is default GHA Intel.
# macOS 13 only runs tests against the GIL-enabled CPython.
# Cirrus used for upstream, macos-14 for forks.
os:
- ghcr.io/cirruslabs/macos-runner:sonoma
- macos-14
- macos-13
is-fork: # only used for the exclusion trick
- ${{ github.repository_owner != 'python' }}
free-threading:
- false
- true
exclude:
- os: ghcr.io/cirruslabs/macos-runner:sonoma
is-fork: true
- os: macos-14
is-fork: false
- os: macos-13
free-threading: true
uses: ./.github/workflows/reusable-macos.yml
with:
config_hash: ${{ needs.build-context.outputs.config-hash }}
free-threading: ${{ matrix.free-threading }}
os: ${{ matrix.os }}
build-ubuntu:
name: >-
Ubuntu
${{ fromJSON(matrix.free-threading) && '(free-threading)' || '' }}
${{ fromJSON(matrix.bolt) && '(bolt)' || '' }}
needs: build-context
if: needs.build-context.outputs.run-tests == 'true'
strategy:
fail-fast: false
matrix:
bolt:
- false
- true
free-threading:
- false
- true
os:
- ubuntu-24.04
- ubuntu-24.04-arm
exclude:
# Do not test BOLT with free-threading, to conserve resources
- bolt: true
free-threading: true
# BOLT currently crashes during instrumentation on aarch64
- os: ubuntu-24.04-arm
bolt: true
uses: ./.github/workflows/reusable-ubuntu.yml
with:
config_hash: ${{ needs.build-context.outputs.config-hash }}
bolt-optimizations: ${{ matrix.bolt }}
free-threading: ${{ matrix.free-threading }}
os: ${{ matrix.os }}
build-ubuntu-ssltests:
name: 'Ubuntu SSL tests with OpenSSL'
runs-on: ${{ matrix.os }}
timeout-minutes: 60
needs: build-context
if: needs.build-context.outputs.run-tests == 'true'
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04]
openssl_ver: [3.0.16, 3.1.8, 3.2.4, 3.3.3, 3.4.1]
# See Tools/ssl/make_ssl_data.py for notes on adding a new version
env:
OPENSSL_VER: ${{ matrix.openssl_ver }}
MULTISSL_DIR: ${{ github.workspace }}/multissl
OPENSSL_DIR: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}
LD_LIBRARY_PATH: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}/lib
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false
- name: Runner image version
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
- name: Restore config.cache
uses: actions/cache@v4
with:
path: config.cache
key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ needs.build-context.outputs.config-hash }}
- name: Register gcc problem matcher
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
- name: Install dependencies
run: sudo ./.github/workflows/posix-deps-apt.sh
- name: Configure OpenSSL env vars
run: |
echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> "$GITHUB_ENV"
echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> "$GITHUB_ENV"
echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> "$GITHUB_ENV"
- name: 'Restore OpenSSL build'
id: cache-openssl
uses: actions/cache@v4
with:
path: ./multissl/openssl/${{ env.OPENSSL_VER }}
key: ${{ matrix.os }}-multissl-openssl-${{ env.OPENSSL_VER }}
- name: Install OpenSSL
if: steps.cache-openssl.outputs.cache-hit != 'true'
run: python3 Tools/ssl/multissltests.py --steps=library --base-directory "$MULTISSL_DIR" --openssl "$OPENSSL_VER" --system Linux
- name: Add ccache to PATH
run: |
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
- name: Configure ccache action
uses: hendrikmuhs/ccache-action@v1.2
with:
save: false
- name: Configure CPython
run: ./configure CFLAGS="-fdiagnostics-format=json" --config-cache --enable-slower-safety --with-pydebug --with-openssl="$OPENSSL_DIR"
- name: Build CPython
run: make -j4
- name: Display build info
run: make pythoninfo
- name: SSL tests
run: ./python Lib/test/ssltests.py
build-wasi:
name: 'WASI'
needs: build-context
if: needs.build-context.outputs.run-tests == 'true'
uses: ./.github/workflows/reusable-wasi.yml
with:
config_hash: ${{ needs.build-context.outputs.config-hash }}
test-hypothesis:
name: "Hypothesis tests on Ubuntu"
runs-on: ubuntu-24.04
timeout-minutes: 60
needs: build-context
if: needs.build-context.outputs.run-tests == 'true'
env:
OPENSSL_VER: 3.0.16
PYTHONSTRICTEXTENSIONBUILD: 1
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false
- name: Register gcc problem matcher
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
- name: Install dependencies
run: sudo ./.github/workflows/posix-deps-apt.sh
- name: Configure OpenSSL env vars
run: |
echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> "$GITHUB_ENV"
echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> "$GITHUB_ENV"
echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> "$GITHUB_ENV"
- name: 'Restore OpenSSL build'
id: cache-openssl
uses: actions/cache@v4
with:
path: ./multissl/openssl/${{ env.OPENSSL_VER }}
key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }}
- name: Install OpenSSL
if: steps.cache-openssl.outputs.cache-hit != 'true'
run: python3 Tools/ssl/multissltests.py --steps=library --base-directory "$MULTISSL_DIR" --openssl "$OPENSSL_VER" --system Linux
- name: Add ccache to PATH
run: |
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
- name: Configure ccache action
uses: hendrikmuhs/ccache-action@v1.2
with:
save: false
- name: Setup directory envs for out-of-tree builds
run: |
echo "CPYTHON_RO_SRCDIR=$(realpath -m "${GITHUB_WORKSPACE}"/../cpython-ro-srcdir)" >> "$GITHUB_ENV"
echo "CPYTHON_BUILDDIR=$(realpath -m "${GITHUB_WORKSPACE}"/../cpython-builddir)" >> "$GITHUB_ENV"
- name: Create directories for read-only out-of-tree builds
run: mkdir -p "$CPYTHON_RO_SRCDIR" "$CPYTHON_BUILDDIR"
- name: Bind mount sources read-only
run: sudo mount --bind -o ro "$GITHUB_WORKSPACE" "$CPYTHON_RO_SRCDIR"
- name: Runner image version
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
- name: Restore config.cache
uses: actions/cache@v4
with:
path: ${{ env.CPYTHON_BUILDDIR }}/config.cache
key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ needs.build-context.outputs.config-hash }}
- name: Configure CPython out-of-tree
working-directory: ${{ env.CPYTHON_BUILDDIR }}
run: |
../cpython-ro-srcdir/configure \
--config-cache \
--with-pydebug \
--enable-slower-safety \
--with-openssl="$OPENSSL_DIR"
- name: Build CPython out-of-tree
working-directory: ${{ env.CPYTHON_BUILDDIR }}
run: make -j4
- name: Display build info
working-directory: ${{ env.CPYTHON_BUILDDIR }}
run: make pythoninfo
- name: Remount sources writable for tests
# some tests write to srcdir, lack of pyc files slows down testing
run: sudo mount "$CPYTHON_RO_SRCDIR" -oremount,rw
- name: Setup directory envs for out-of-tree builds
run: |
echo "CPYTHON_BUILDDIR=$(realpath -m "${GITHUB_WORKSPACE}"/../cpython-builddir)" >> "$GITHUB_ENV"
- name: "Create hypothesis venv"
working-directory: ${{ env.CPYTHON_BUILDDIR }}
run: |
VENV_LOC=$(realpath -m .)/hypovenv
VENV_PYTHON=$VENV_LOC/bin/python
echo "HYPOVENV=${VENV_LOC}" >> "$GITHUB_ENV"
echo "VENV_PYTHON=${VENV_PYTHON}" >> "$GITHUB_ENV"
./python -m venv "$VENV_LOC" && "$VENV_PYTHON" -m pip install -r "${GITHUB_WORKSPACE}/Tools/requirements-hypothesis.txt"
- name: 'Restore Hypothesis database'
id: cache-hypothesis-database
uses: actions/cache@v4
with:
path: ${{ env.CPYTHON_BUILDDIR }}/.hypothesis/
key: hypothesis-database-${{ github.head_ref || github.run_id }}
restore-keys: |
hypothesis-database-
- name: "Run tests"
working-directory: ${{ env.CPYTHON_BUILDDIR }}
run: |
# Most of the excluded tests are slow test suites with no property tests
#
# (GH-104097) test_sysconfig is skipped because it has tests that are
# failing when executed from inside a virtual environment.
"${VENV_PYTHON}" -m test \
-W \
--slowest \
-j4 \
--timeout 900 \
-x test_asyncio \
-x test_multiprocessing_fork \
-x test_multiprocessing_forkserver \
-x test_multiprocessing_spawn \
-x test_concurrent_futures \
-x test_socket \
-x test_subprocess \
-x test_signal \
-x test_sysconfig
- uses: actions/upload-artifact@v4
if: always()
with:
name: hypothesis-example-db
path: ${{ env.CPYTHON_BUILDDIR }}/.hypothesis/examples/
build-asan:
name: 'Address sanitizer'
runs-on: ${{ matrix.os }}
timeout-minutes: 60
needs: build-context
if: needs.build-context.outputs.run-tests == 'true'
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04]
env:
OPENSSL_VER: 3.0.16
PYTHONSTRICTEXTENSIONBUILD: 1
ASAN_OPTIONS: detect_leaks=0:allocator_may_return_null=1:handle_segv=0
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false
- name: Runner image version
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
- name: Restore config.cache
uses: actions/cache@v4
with:
path: config.cache
key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ needs.build-context.outputs.config-hash }}
- name: Register gcc problem matcher
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
- name: Install dependencies
run: sudo ./.github/workflows/posix-deps-apt.sh
- name: Set up GCC-10 for ASAN
uses: egor-tensin/setup-gcc@v1
with:
version: 10
- name: Configure OpenSSL env vars
run: |
echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> "$GITHUB_ENV"
echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> "$GITHUB_ENV"
echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> "$GITHUB_ENV"
- name: 'Restore OpenSSL build'
id: cache-openssl
uses: actions/cache@v4
with:
path: ./multissl/openssl/${{ env.OPENSSL_VER }}
key: ${{ matrix.os }}-multissl-openssl-${{ env.OPENSSL_VER }}
- name: Install OpenSSL
if: steps.cache-openssl.outputs.cache-hit != 'true'
run: python3 Tools/ssl/multissltests.py --steps=library --base-directory "$MULTISSL_DIR" --openssl "$OPENSSL_VER" --system Linux
- name: Add ccache to PATH
run: |
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
- name: Configure ccache action
uses: hendrikmuhs/ccache-action@v1.2
with:
save: ${{ github.event_name == 'push' }}
max-size: "200M"
- name: Configure CPython
run: ./configure --config-cache --with-address-sanitizer --without-pymalloc
- name: Build CPython
run: make -j4
- name: Display build info
run: make pythoninfo
- name: Tests
run: xvfb-run make ci
build-san:
name: >- # ${{ '' } is a hack to nest jobs under the same sidebar category
Sanitizers${{ '' }}
needs: build-context
if: needs.build-context.outputs.run-tests == 'true'
strategy:
fail-fast: false
matrix:
check-name:
- Thread
free-threading:
- false
- true
sanitizer:
- TSan
include:
- check-name: Undefined behavior
sanitizer: UBSan
free-threading: false
uses: ./.github/workflows/reusable-san.yml
with:
sanitizer: ${{ matrix.sanitizer }}
config_hash: ${{ needs.build-context.outputs.config-hash }}
free-threading: ${{ matrix.free-threading }}
cross-build-linux:
name: Cross build Linux
runs-on: ubuntu-latest
timeout-minutes: 60
needs: build-context
if: needs.build-context.outputs.run-tests == 'true'
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false
- name: Runner image version
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
- name: Restore config.cache
uses: actions/cache@v4
with:
path: config.cache
key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ needs.build-context.outputs.config-hash }}
- name: Register gcc problem matcher
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
- name: Set build dir
run:
# an absolute path outside of the working directoy
echo "BUILD_DIR=$(realpath ${{ github.workspace }}/../build)" >> "$GITHUB_ENV"
- name: Install dependencies
run: sudo ./.github/workflows/posix-deps-apt.sh
- name: Configure host build
run: ./configure --prefix="$BUILD_DIR/host-python"
- name: Install host Python
run: make -j8 install
- name: Run test subset with host build
run: |
"$BUILD_DIR/host-python/bin/python3" -m test test_sysconfig test_site test_embed
- name: Configure cross build
run: ./configure --prefix="$BUILD_DIR/cross-python" --with-build-python="$BUILD_DIR/host-python/bin/python3"
- name: Install cross Python
run: make -j8 install
- name: Run test subset with host build
run: |
"$BUILD_DIR/cross-python/bin/python3" -m test test_sysconfig test_site test_embed
# CIFuzz job based on https://google.github.io/oss-fuzz/getting-started/continuous-integration/
cifuzz:
name: CIFuzz
runs-on: ubuntu-latest
timeout-minutes: 60
needs: build-context
if: needs.build-context.outputs.run-ci-fuzz == 'true'
permissions:
security-events: write
strategy:
fail-fast: false
matrix:
sanitizer: [address, undefined, memory]
steps:
- name: Build fuzzers (${{ matrix.sanitizer }})
id: build
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
oss-fuzz-project-name: cpython3
sanitizer: ${{ matrix.sanitizer }}
- name: Run fuzzers (${{ matrix.sanitizer }})
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with:
fuzz-seconds: 600
oss-fuzz-project-name: cpython3
output-sarif: true
sanitizer: ${{ matrix.sanitizer }}
- name: Upload crash
if: failure() && steps.build.outcome == 'success'
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.sanitizer }}-artifacts
path: ./out/artifacts
- name: Upload SARIF
if: always() && steps.build.outcome == 'success'
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: cifuzz-sarif/results.sarif
checkout_path: cifuzz-sarif
all-required-green: # This job does nothing and is only used for the branch protection
name: All required checks pass
runs-on: ubuntu-latest
timeout-minutes: 5
needs:
- build-context # Transitive dependency, needed to access `run-tests` value
- check-docs
- check-autoconf-regen
- check-generated-files
- build-windows
- build-windows-msi
- build-macos
- build-ubuntu
- build-ubuntu-ssltests
- build-wasi
- test-hypothesis
- build-asan
- build-san
- cross-build-linux
- cifuzz
if: always()
steps:
- name: Check whether the needed jobs succeeded or failed
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe
with:
allowed-failures: >-
build-windows-msi,
build-ubuntu-ssltests,
test-hypothesis,
cifuzz,
allowed-skips: >-
${{
!fromJSON(needs.build-context.outputs.run-docs)
&& '
check-docs,
'
|| ''
}}
${{
needs.build-context.outputs.run-tests != 'true'
&& '
check-autoconf-regen,
check-generated-files,
build-macos,
build-ubuntu,
build-ubuntu-ssltests,
build-wasi,
test-hypothesis,
build-asan,
build-san,
cross-build-linux,
'
|| ''
}}
${{
!fromJSON(needs.build-context.outputs.run-windows-tests)
&& '
build-windows,
'
|| ''
}}
${{
!fromJSON(needs.build-context.outputs.run-ci-fuzz)
&& '
cifuzz,
'
|| ''
}}
jobs: ${{ toJSON(needs) }}

5
.gitignore vendored
View File

@@ -174,3 +174,8 @@ Python/frozen_modules/MANIFEST
# People's custom https://docs.anthropic.com/en/docs/claude-code/memory configs. # People's custom https://docs.anthropic.com/en/docs/claude-code/memory configs.
/.claude/ /.claude/
CLAUDE.local.md CLAUDE.local.md
# CMake/Conan build outputs
/build/
CMakeUserPresets.json
CMakePresets.json
compile_commands.json

61
CMakeLists.txt Normal file
View File

@@ -0,0 +1,61 @@
cmake_minimum_required(VERSION 3.22)
project(Typthon VERSION 3.14.0 LANGUAGES C)
# Allow using compilers provided by Conan if available
if(EXISTS "${CMAKE_BINARY_DIR}/conan_toolchain.cmake")
include("${CMAKE_BINARY_DIR}/conan_toolchain.cmake")
endif()
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/version.h.in
${CMAKE_CURRENT_BINARY_DIR}/generated/typthon/version.h
@ONLY
)
add_library(typthon_core STATIC src/runtime.c)
target_include_directories(
typthon_core
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_BINARY_DIR}/generated
)
target_compile_features(typthon_core PUBLIC c_std_11)
add_executable(typthon src/main.c)
target_link_libraries(typthon PRIVATE typthon_core)
include(GNUInstallDirs)
install(
TARGETS typthon_core typthon
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/generated/typthon/version.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/typthon
)
include(CTest)
if(BUILD_TESTING)
add_executable(typthon_smoketest tests/smoke.c)
target_include_directories(
typthon_smoketest
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_BINARY_DIR}/generated
)
target_link_libraries(typthon_smoketest PRIVATE typthon_core)
add_test(NAME typthon_cli COMMAND typthon --version)
add_test(NAME typthon_runtime_version COMMAND typthon_smoketest)
endif()

3
cmake/version.h.in Normal file
View File

@@ -0,0 +1,3 @@
#pragma once
#define TYPTHON_VERSION "@PROJECT_VERSION@"

7
conanfile.txt Normal file
View File

@@ -0,0 +1,7 @@
[tool_requires]
cmake/3.30.5
ninja/1.12.1
[generators]
CMakeDeps
CMakeToolchain

15
include/typthon/runtime.h Normal file
View File

@@ -0,0 +1,15 @@
#pragma once
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
const char *typthon_version(void);
void typthon_print_banner(FILE *output);
#ifdef __cplusplus
}
#endif

40
src/main.c Normal file
View File

@@ -0,0 +1,40 @@
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "typthon/runtime.h"
#include "typthon/version.h"
static void print_usage(void) {
printf("Typthon %s\n", typthon_version());
printf("usage: typthon [--version] [--help]\n");
printf("This is a lightweight bootstrap for the Typthon runtime.\n");
}
int main(int argc, char **argv) {
bool show_help = false;
bool show_version = false;
for (int i = 1; i < argc; ++i) {
if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
show_help = true;
} else if (strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-V") == 0) {
show_version = true;
} else {
fprintf(stderr, "unknown option: %s\n", argv[i]);
return 1;
}
}
if (show_help) {
print_usage();
return 0;
}
if (show_version || argc == 1) {
typthon_print_banner(stdout);
return 0;
}
return 0;
}

14
src/runtime.c Normal file
View File

@@ -0,0 +1,14 @@
#include "typthon/runtime.h"
#include "typthon/version.h"
const char *typthon_version(void) {
return TYPTHON_VERSION;
}
void typthon_print_banner(FILE *output) {
if (output == NULL) {
return;
}
fprintf(output, "Typthon %s\n", typthon_version());
}

16
tests/smoke.c Normal file
View File

@@ -0,0 +1,16 @@
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "typthon/runtime.h"
#include "typthon/version.h"
int main(void) {
const char *version = typthon_version();
assert(version != NULL);
assert(strlen(version) > 0);
printf("Typthon runtime version: %s\n", version);
typthon_print_banner(stdout);
return 0;
}