diff --git a/.bazelignore b/.bazelignore new file mode 100644 index 0000000..378eac2 --- /dev/null +++ b/.bazelignore @@ -0,0 +1 @@ +build diff --git a/.bazelrc b/.bazelrc new file mode 100644 index 0000000..2ae57e6 --- /dev/null +++ b/.bazelrc @@ -0,0 +1,29 @@ +# Enable logging rc options. +common --announce_rc + +# Enable verbose failures for testing only. +build --verbose_failures + +# Set the default Apple platform to macOS. +build --apple_platform_type=macos + +# Abseil requires C++14 at minimum. +build --enable_platform_specific_config +build:linux --cxxopt=-std=c++17 --host_cxxopt=-std=c++17 +build:macos --cxxopt=-std=c++17 --host_cxxopt=-std=c++17 +build:macos --cxxopt=-mmacos-version-min=10.15 --host_cxxopt=-mmacos-version-min=10.15 +build:windows --cxxopt=/std:c++17 --host_cxxopt=/std:c++17 + +# Enable the runfiles symlink tree on Windows. This makes it possible to build +# the pip package on Windows without an intermediate data-file archive, as the +# build_pip_package script in its current form (as of Aug 2023) uses the +# runfiles symlink tree to decide what to put into the Python wheel. +startup --windows_enable_symlinks +build:windows --enable_runfiles + +# Enable logging error output. +test --test_output=errors +test --test_summary=detailed + +# https://bazel.build/configure/best-practices#bazelrc-file +try-import %workspace%/user.bazelrc diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index b30c028..4136ffa 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -1,21 +1,14 @@ +# ref: https://github.com/actions/runner-images name: build_and_test # Controls when the action will run. -on: - # Triggers the workflow on push or pull request events but only for the master branch - push: - branches: [ master ] - pull_request: - branches: [ master ] - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: +on: [push, pull_request, workflow_dispatch] env: PIP_BREAK_SYSTEM_PACKAGES: 1 # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: - unix: strategy: fail-fast: false @@ -23,35 +16,28 @@ jobs: runs-on: [ubuntu-latest] build_tool: [bazel, cmake] - name: "${{matrix.runs-on}} ${{matrix.build_tool}}" + name: "script ${{matrix.build_tool}}" runs-on: ${{matrix.runs-on}} # Steps represent a sequence of tasks that will be executed as part of the job steps: - name: Show env run: env - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - name: Install bazel + - name: Setup bazel if: matrix.build_tool == 'bazel' - # Install Bazel, see https://docs.bazel.build/versions/master/install-ubuntu.html#step-1-install-required-packages - run: | - sudo apt install curl gnupg - curl -fsSL https://bazel.build/bazel-release.pub.gpg | gpg --dearmor > bazel.gpg - sudo mv bazel.gpg /etc/apt/trusted.gpg.d/ - echo "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list - sudo apt update && sudo apt install bazel -y + uses: bazel-contrib/setup-bazel@0.8.4 + with: + bazelisk-cache: true + disk-cache: ${{ github.workflow }} + repository-cache: true - name: Show bazel version if: matrix.build_tool == 'bazel' run: bazel --version - - name: Update cmake - if: matrix.build_tool == 'cmake' - uses: jwlawson/actions-setup-cmake@v1.14 - - name: Show cmake version if: matrix.build_tool == 'cmake' run: cmake --version diff --git a/.github/workflows/amd64_linux_bazel.yml b/.github/workflows/amd64_linux_bazel.yml new file mode 100644 index 0000000..00e43cd --- /dev/null +++ b/.github/workflows/amd64_linux_bazel.yml @@ -0,0 +1,72 @@ +# ref: https://github.com/actions/runner-images +name: amd64 Linux Bazel + +on: [push, pull_request, workflow_dispatch] + +# Building using the github runner environement directly. +jobs: + native: + strategy: + matrix: + bazel: [ + {compilation_mode: opt}, + {compilation_mode: dbg}, + ] + cpp: [ + {version: 14, flags: "-std=c++14"}, + {version: 17, flags: "-std=c++17"}, + {version: 20, flags: "-std=c++20"}, + ] + python: [ + {version: '3.11'}, + ] + exclude: + # only test `-c dbg` build with C++17 + - cpp: {version: 14} + bazel: {compilation_mode: dbg} + - cpp: {version: 20} + bazel: {compilation_mode: dbg} + fail-fast: false + name: Linux•Bazel(${{ matrix.bazel.compilation_mode }})•C++${{ matrix.cpp.version }}•Python${{ matrix.python.version }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Check Java + run: java -version + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python.version }} + - name: Check Python + run: | + python --version + python -m platform + - uses: bazel-contrib/setup-bazel@0.8.4 + with: + bazelisk-cache: true + disk-cache: ${{ github.workflow }} + repository-cache: true + - name: Check Bazel + run: bazel version + - name: Build + run: > + bazel build + -c ${{ matrix.bazel.compilation_mode }} + --cxxopt=${{ matrix.cpp.flags }} --host_cxxopt=${{ matrix.cpp.flags }} + --subcommands=pretty_print + --enable_bzlmod + //... + - name: Test + run: > + bazel test + -c ${{ matrix.bazel.compilation_mode }} + --cxxopt=${{ matrix.cpp.flags }} --host_cxxopt=${{ matrix.cpp.flags }} + --subcommands=pretty_print + --enable_bzlmod + //... + + amd64_linux_bazel: + runs-on: ubuntu-latest + needs: native + steps: + - uses: actions/checkout@v4 diff --git a/.github/workflows/amd64_linux_cmake.yml b/.github/workflows/amd64_linux_cmake.yml new file mode 100644 index 0000000..c51d239 --- /dev/null +++ b/.github/workflows/amd64_linux_cmake.yml @@ -0,0 +1,74 @@ +# ref: https://github.com/actions/runner-images +name: amd64 Linux CMake + +on: [push, pull_request, workflow_dispatch] + +# Building using the github runner environement directly. +jobs: + native: + strategy: + matrix: + python: [ + {version: '3.9'}, + {version: '3.10'}, + {version: '3.11'}, + {version: '3.12'}, + #{version: '3.13'}, + ] + cmake: [ + {generator: "Unix Makefiles", config: "Release"}, + {generator: "Ninja", config: "Release"}, + #{generator: "Ninja Multi-Config", config: "Release"}, + ] + fail-fast: false + name: Linux•CMake(${{ matrix.cmake.generator }})•Python${{ matrix.python.version }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python.version }} + - name: Check Python + run: | + python --version + python -m platform + - name: Install Python requirements + run: python -m pip install --upgrade -r $(python -c 'import sys; print("./pybind11_abseil/requirements/requirements_lock_%d_%d.txt" % (sys.version_info[:2]))') + - name: Install Ninja + run: | + sudo apt-get update + sudo apt-get install ninja-build + - name: Check CMake + run: cmake --version + - name: Configure + run: > + cmake -S. -Bbuild + -G "${{ matrix.cmake.generator }}" + -DCMAKE_BUILD_TYPE=${{ matrix.cmake.config }} + -DCMAKE_INSTALL_PREFIX=install + - name: Build + run: > + cmake --build build + --config ${{ matrix.cmake.config }} + --target all + -v -j2 + - name: Test + run: > + CTEST_OUTPUT_ON_FAILURE=1 + cmake --build build + --config ${{ matrix.cmake.config }} + --target test + -v + - name: Install + run: > + cmake --build build + --config ${{ matrix.cmake.config }} + --target install + -v + + amd64_linux_cmake: + runs-on: ubuntu-latest + needs: native + steps: + - uses: actions/checkout@v4 diff --git a/.github/workflows/amd64_macos_bazel.yml b/.github/workflows/amd64_macos_bazel.yml new file mode 100644 index 0000000..739da78 --- /dev/null +++ b/.github/workflows/amd64_macos_bazel.yml @@ -0,0 +1,74 @@ +# ref: https://github.com/actions/runner-images +name: amd64 MacOS Bazel + +on: [push, pull_request, workflow_dispatch] + +# Building using the github runner environement directly. +jobs: + native: + strategy: + matrix: + bazel: [ + {compilation_mode: opt}, + {compilation_mode: dbg}, + ] + cpp: [ + #{version: 14, flags: "-std=c++14"}, + {version: 17, flags: "-std=c++17"}, + #{version: 20, flags: "-std=c++20"}, + ] + python: [ + {version: '3.11'}, + ] + exclude: + # only test `-c dbg` build with C++17 + - cpp: {version: 14} + bazel: {compilation_mode: dbg} + - cpp: {version: 20} + bazel: {compilation_mode: dbg} + fail-fast: false + name: MacOS•Bazel(${{ matrix.bazel.compilation_mode }})•C++${{ matrix.cpp.version }}•Python${{ matrix.python.version }} + runs-on: macos-13 # last macos intel based runner + steps: + - uses: actions/checkout@v4 + - name: Set Java to OpenJDK 17 (Temurin) + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: '17' + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python.version }} + - name: Check Python + run: | + python --version + python -m platform + - name: Check Bazel + run: bazel version + - name: Change Python in MODULE.bazel + run: | + sed -i '' -e 's/\(DEFAULT_PYTHON =\) "3.[0-9]*"/\1 "${{ matrix.python.version }}"/g' MODULE.bazel + cat MODULE.bazel + - name: Build + run: > + bazel build + -c ${{ matrix.bazel.compilation_mode }} + --cxxopt=${{ matrix.cpp.flags }} --host_cxxopt=${{ matrix.cpp.flags }} + --subcommands=pretty_print + --enable_bzlmod + //... + - name: Test + run: > + bazel test + -c ${{ matrix.bazel.compilation_mode }} + --cxxopt=${{ matrix.cpp.flags }} --host_cxxopt=${{ matrix.cpp.flags }} + --subcommands=pretty_print + --enable_bzlmod + //... + + amd64_macos_bazel: + runs-on: ubuntu-latest + needs: native + steps: + - uses: actions/checkout@v4 diff --git a/.github/workflows/amd64_macos_cmake.yml b/.github/workflows/amd64_macos_cmake.yml new file mode 100644 index 0000000..cd30d9e --- /dev/null +++ b/.github/workflows/amd64_macos_cmake.yml @@ -0,0 +1,71 @@ +# ref: https://github.com/actions/runner-images +name: amd64 MacOS CMake + +on: [push, pull_request, workflow_dispatch] + +# Building using the github runner environement directly. +jobs: + native: + strategy: + matrix: + python: [ + {version: '3.9'}, + {version: '3.10'}, + {version: '3.11'}, + {version: '3.12'}, + #{version: '3.13'}, + ] + cmake: [ + #{generator: "Xcode", config: Release, build_target: ALL_BUILD, test_target: RUN_TESTS, install_target: install}, + {generator: "Unix Makefiles", config: Release, build_target: all, test_target: test, install_target: install}, + ] + fail-fast: false + name: MacOS•CMake(${{ matrix.cmake.generator }})•Python${{ matrix.python.version }} + runs-on: macos-13 # last macos intel based runner + steps: + - uses: actions/checkout@v4 + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python.version }} + - name: Update Path + run: | + echo "$HOME/Library/Python/${{ matrix.python.version }}/bin" >> $GITHUB_PATH + echo "$HOME/.local/bin" >> $GITHUB_PATH + - name: Check Python + run: python --version + - name: Install Python requirements + run: python -m pip install --upgrade -r $(python -c 'import sys; print("./pybind11_abseil/requirements/requirements_lock_%d_%d.txt" % (sys.version_info[:2]))') + - name: Check CMake + run: cmake --version + - name: Configure + run: > + cmake -S. -Bbuild + -G "${{ matrix.cmake.generator }}" + -DCMAKE_BUILD_TYPE=${{ matrix.cmake.config }} + -DCMAKE_INSTALL_PREFIX=install + - name: Build + run: > + cmake --build build + --config ${{ matrix.cmake.config }} + --target ${{ matrix.cmake.build_target }} + -v -j2 + - name: Test + run: > + CTEST_OUTPUT_ON_FAILURE=1 + cmake --build build + --config ${{ matrix.cmake.config }} + --target ${{ matrix.cmake.test_target }} + -v + - name: Install + run: > + cmake --build build + --config ${{ matrix.cmake.config }} + --target ${{ matrix.cmake.install_target }} + -v + + amd64_macos_cmake: + runs-on: ubuntu-latest + needs: native + steps: + - uses: actions/checkout@v4 diff --git a/.github/workflows/amd64_windows_bazel.yml b/.github/workflows/amd64_windows_bazel.yml new file mode 100644 index 0000000..4dfe7db --- /dev/null +++ b/.github/workflows/amd64_windows_bazel.yml @@ -0,0 +1,75 @@ +# ref: https://github.com/actions/runner-images +name: amd64 Windows Bazel + +on: [push, pull_request, workflow_dispatch] + +# Building using the github runner environement directly. +jobs: + native: + strategy: + matrix: + runner: [ + windows-2022, + #windows-2019, + ] + bazel: [ + {compilation_mode: opt}, + {compilation_mode: dbg}, + ] + cpp: [ + {version: 14, flags: "/std:c++14"}, + {version: 17, flags: "/std:c++17"}, + #{version: 20, flags: "/std:c++20"}, + ] + python: [ + {version: '3.11'}, + ] + exclude: + - runner: windows-2019 + cpp: {version: 20} + # only test -c dbg with VS 2022 version 17 to save compute time + - runner: windows-2019 + bazel: {compilation_mode: dbg} + - cpp: {version: 14} + bazel: {compilation_mode: dbg} + - cpp: {version: 20} + bazel: {compilation_mode: dbg} + fail-fast: false # Don't cancel all jobs if one fails. + name: ${{ matrix.runner }}•Bazel(${{ matrix.bazel.compilation_mode }})•C++${{ matrix.cpp.version }}•Python${{ matrix.python.version }} + runs-on: ${{ matrix.runner }} + steps: + - uses: actions/checkout@v4 + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python.version }} + - name: Check Python + run: | + python --version + python -m platform + - name: Install Bazel + run: choco install bazel + - name: Check Bazel + run: bazel version + - name: Build + run: > + bazel build + -c ${{ matrix.bazel.compilation_mode }} + --cxxopt=${{ matrix.cpp.flags }} --host_cxxopt=${{ matrix.cpp.flags }} + --subcommands=pretty_print + --enable_bzlmod + //... + - name: Test + run: > + bazel test + -c ${{ matrix.bazel.compilation_mode }} + --cxxopt=${{ matrix.cpp.flags }} --host_cxxopt=${{ matrix.cpp.flags }} + --subcommands=pretty_print + --enable_bzlmod + //... + + amd64_windows_bazel: + runs-on: ubuntu-latest + needs: native + steps: + - uses: actions/checkout@v4 diff --git a/.github/workflows/amd64_windows_cmake.yml b/.github/workflows/amd64_windows_cmake.yml new file mode 100644 index 0000000..fa9e408 --- /dev/null +++ b/.github/workflows/amd64_windows_cmake.yml @@ -0,0 +1,69 @@ +# ref: https://github.com/actions/runner-images +name: amd64 Windows CMake + +on: [push, pull_request, workflow_dispatch] + +# Building using the github runner environement directly. +jobs: + native: + strategy: + matrix: + python: [ + {version: '3.11'}, + #{version: '3.12'}, + #{version: '3.13'}, + ] + cmake: [ + {generator: "Visual Studio 17 2022", config: Release, build_target: ALL_BUILD, test_target: RUN_TESTS, install_target: INSTALL}, + ] + fail-fast: false + name: Windows•CMake(${{ matrix.cmake.generator }})•Python${{ matrix.python.version }} + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python.version }} + - name: Check Python + run: | + python --version + python -m platform + - name: Install Python requirements + run: python -m pip install --upgrade -r $(python -c 'import sys; print("./pybind11_abseil/requirements/requirements_lock_%d_%d.txt" % (sys.version_info[:2]))') + - name: Check CMake + run: | + cmake --version + cmake -G || true + - name: Configure + run: > + cmake -S. -Bbuild + -G "${{ matrix.cmake.generator }}" + -DCMAKE_CONFIGURATION_TYPES=${{ matrix.cmake.config }} + -DCMAKE_INSTALL_PREFIX=install + - name: Build + run: > + cmake --build build + --config ${{ matrix.cmake.config }} + --target ${{ matrix.cmake.build_target }} + -v -j2 + - name: Test + shell: bash + run: > + CTEST_OUTPUT_ON_FAILURE=1 + cmake --build build + --config ${{ matrix.cmake.config }} + --target ${{ matrix.cmake.test_target }} + -v + - name: Install + run: > + cmake --build build + --config ${{ matrix.cmake.config }} + --target ${{ matrix.cmake.install_target }} + -v + + amd64_windows_cmake: + runs-on: ubuntu-latest + needs: native + steps: + - uses: actions/checkout@v4 diff --git a/.github/workflows/arm64_macos_bazel.yml b/.github/workflows/arm64_macos_bazel.yml new file mode 100644 index 0000000..c3dc9d9 --- /dev/null +++ b/.github/workflows/arm64_macos_bazel.yml @@ -0,0 +1,74 @@ +# ref: https://github.com/actions/runner-images +name: arm64 MacOS Bazel + +on: [push, pull_request, workflow_dispatch] + +# Building using the github runner environement directly. +jobs: + native: + strategy: + matrix: + bazel: [ + {compilation_mode: opt}, + {compilation_mode: dbg}, + ] + cpp: [ + #{version: 14, flags: "-std=c++14"}, + {version: 17, flags: "-std=c++17"}, + #{version: 20, flags: "-std=c++20"}, + ] + python: [ + {version: '3.11'}, + ] + exclude: + # only test `-c dbg` build with C++17 + - cpp: {version: 14} + bazel: {compilation_mode: dbg} + - cpp: {version: 20} + bazel: {compilation_mode: dbg} + fail-fast: false + name: MacOS•Bazel(${{ matrix.bazel.compilation_mode }})•C++${{ matrix.cpp.version }}•Python${{ matrix.python.version }} + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + - name: Set Java to OpenJDK 17 (Temurin) + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: '17' + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python.version }} + - name: Check Python + run: | + python --version + python -m platform + - name: Check Bazel + run: bazel version + - name: Change Python in MODULE.bazel + run: | + sed -i '' -e 's/\(DEFAULT_PYTHON =\) "3.[0-9]*"/\1 "${{ matrix.python.version }}"/g' MODULE.bazel + cat MODULE.bazel + - name: Build + run: > + bazel build + -c ${{ matrix.bazel.compilation_mode }} + --cxxopt=${{ matrix.cpp.flags }} --host_cxxopt=${{ matrix.cpp.flags }} + --subcommands=pretty_print + --enable_bzlmod + //... + - name: Test + run: > + bazel test + -c ${{ matrix.bazel.compilation_mode }} + --cxxopt=${{ matrix.cpp.flags }} --host_cxxopt=${{ matrix.cpp.flags }} + --subcommands=pretty_print + --enable_bzlmod + //... + + arm64_macos_bazel: + runs-on: ubuntu-latest + needs: native + steps: + - uses: actions/checkout@v4 diff --git a/.github/workflows/arm64_macos_cmake.yml b/.github/workflows/arm64_macos_cmake.yml new file mode 100644 index 0000000..42a8a56 --- /dev/null +++ b/.github/workflows/arm64_macos_cmake.yml @@ -0,0 +1,71 @@ +# ref: https://github.com/actions/runner-images +name: arm64 MacOS CMake + +on: [push, pull_request, workflow_dispatch] + +# Building using the github runner environement directly. +jobs: + native: + strategy: + matrix: + python: [ + {version: '3.9'}, + {version: '3.10'}, + {version: '3.11'}, + {version: '3.12'}, + #{version: '3.13'}, + ] + cmake: [ + #{generator: "Xcode", config: Release, build_target: ALL_BUILD, test_target: RUN_TESTS, install_target: install}, + {generator: "Unix Makefiles", config: Release, build_target: all, test_target: test, install_target: install}, + ] + fail-fast: false + name: MacOS•CMake(${{ matrix.cmake.generator }})•Python${{ matrix.python.version }} + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python.version }} + - name: Update Path + run: | + echo "$HOME/Library/Python/${{ matrix.python.version }}/bin" >> $GITHUB_PATH + echo "$HOME/.local/bin" >> $GITHUB_PATH + - name: Check Python + run: python --version + - name: Install Python requirements + run: python -m pip install --upgrade -r $(python -c 'import sys; print("./pybind11_abseil/requirements/requirements_lock_%d_%d.txt" % (sys.version_info[:2]))') + - name: Check CMake + run: cmake --version + - name: Configure + run: > + cmake -S. -Bbuild + -G "${{ matrix.cmake.generator }}" + -DCMAKE_BUILD_TYPE=${{ matrix.cmake.config }} + -DCMAKE_INSTALL_PREFIX=install + - name: Build + run: > + cmake --build build + --config ${{ matrix.cmake.config }} + --target ${{ matrix.cmake.build_target }} + -v -j2 + - name: Test + run: > + CTEST_OUTPUT_ON_FAILURE=1 + cmake --build build + --config ${{ matrix.cmake.config }} + --target ${{ matrix.cmake.test_target }} + -v + - name: Install + run: > + cmake --build build + --config ${{ matrix.cmake.config }} + --target ${{ matrix.cmake.install_target }} + -v + + arm64_macos_cmake: + runs-on: ubuntu-latest + needs: native + steps: + - uses: actions/checkout@v4 diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 0000000..92a6437 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,16 @@ +# ref: https://github.com/actions/runner-images +name: pre-commit + +# Controls when the action will run. +on: [push, pull_request, workflow_dispatch] + +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + - uses: pre-commit/action@v3.0.0 + with: + # Slow hooks are marked with manual - slow is okay here, run them too + extra_args: --hook-stage manual --all-files diff --git a/.github/workflows/ubuntu-build.yml b/.github/workflows/ubuntu-build.yml new file mode 100644 index 0000000..7287311 --- /dev/null +++ b/.github/workflows/ubuntu-build.yml @@ -0,0 +1,84 @@ +# ref: https://github.com/actions/runner-images +name: ubuntu-build + +on: [push, pull_request, workflow_dispatch] + +concurrency: + group: ci-${{github.workflow}}-${{ github.ref }} + cancel-in-progress: true + +jobs: + cmake: + name: ubuntu-latest cmake + runs-on: ubuntu-latest + steps: + - name: Show env + run: env + - uses: actions/checkout@v4 + - name: Install Build Dependencies + run: > + sudo apt update && + sudo apt install --no-install-recommends -y + cmake make + - name: Show Python version and platform info + run: | + python --version + python -m platform + - name: Show CMake version + run: cmake --version + - name: CMake Configure + run: cmake -S. -Bbuild -DCMAKE_VERBOSE_MAKEFILE=ON + - name: CMake Build + run: cmake --build build -j$(nproc) + + bazel_inner: + strategy: + matrix: + options: [ + {version: 14, flags: "-std=c++14"}, + {version: 17, flags: "-std=c++17"}, + {version: 20, flags: "-std=c++20"}, + ] + fail-fast: false # Don't cancel all jobs if one fails. + name: bazel c++${{ matrix.options.version }} + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: 3.11 # Current default version in MODULE.bazel + - name: Show Python version and platform info + run: | + python --version + python -m platform + - uses: bazel-contrib/setup-bazel@0.8.4 + with: + bazelisk-cache: true + disk-cache: ${{ github.workflow }} + repository-cache: true + - name: Show Bazel version + run: bazel --version + - name: Bazel Build + shell: bash + run: > + bazel build + --cxxopt=${{ matrix.options.flags }} --host_cxxopt=${{ matrix.options.flags }} + --subcommands=pretty_print + --enable_bzlmod + //... + - name: Bazel Test + shell: bash + run: > + bazel test + --cxxopt=${{ matrix.options.flags }} --host_cxxopt=${{ matrix.options.flags }} + --subcommands=pretty_print + --enable_bzlmod + //... + + bazel: + name: ubuntu-latest bazel + runs-on: ubuntu-latest + needs: bazel_inner + steps: + - uses: actions/checkout@v4 diff --git a/CMakeLists.txt b/CMakeLists.txt index ceb65a8..e4cf9ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,14 +1,12 @@ -cmake_minimum_required(VERSION 3.11) +cmake_minimum_required(VERSION 3.18) project(pybind11_abseil LANGUAGES CXX) -include(FetchContent) -include(CTest) - if(NOT DEFINED CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 17) -endif(NOT DEFINED CMAKE_CXX_STANDARD) -set(ABSL_PROPAGATE_CXX_STD ON) -set(BUILD_TESTING OFF) +endif() +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE) @@ -16,19 +14,24 @@ if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24) cmake_policy(SET CMP0135 NEW) endif() -FetchContent_Declare( - abseil-cpp - URL https://github.com/abseil/abseil-cpp/archive/refs/tags/20230802.0.tar.gz - URL_HASH - SHA256=59d2976af9d6ecf001a81a35749a6e551a335b949d34918cfade07737b9d93c5) +# ============================================================================ +# Options -FetchContent_Declare( - pybind11 - URL https://github.com/pybind/pybind11/archive/refs/heads/master.tar.gz) +option(USE_SYSTEM_ABSEIL "Force usage of system provided abseil-cpp" OFF) +option(USE_SYSTEM_PYBIND "Force usage of system provided pybind11" OFF) -FetchContent_MakeAvailable(abseil-cpp pybind11) +# ============================================================================ +# Testing +include(CTest) + +# ============================================================================ +# Find Python +find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module) + +# ============================================================================ +# Build dependencies +add_subdirectory(cmake/dependencies dependencies) set(TOP_LEVEL_DIR ${CMAKE_CURRENT_LIST_DIR}) include_directories(${TOP_LEVEL_DIR} ${pybind11_INCLUDE_DIRS}) - add_subdirectory(pybind11_abseil) diff --git a/MODULE.bazel b/MODULE.bazel index 93fcf79..c7a33c0 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -3,72 +3,50 @@ module( version = "head", ) -bazel_dep( - name = "bazel_skylib", - version = "1.5.0", -) - -bazel_dep( - name = "abseil-cpp", - version = "20240116.0", - repo_name = "com_google_absl", -) - -bazel_dep( - name = "rules_cc", - version = "0.0.9", -) - -bazel_dep( - name = "rules_python", - version = "0.31.0", -) - -bazel_dep( - name = "platforms", - version = "0.0.8" -) - -bazel_dep( - name = "pybind11_bazel", - version = "2.11.1.bzl.2", -) +# Only direct dependencies need to be listed below. +# Please keep the versions in sync with the versions in the WORKSPACE file. +# see https://registry.bazel.build/ +bazel_dep(name = "bazel_skylib", version = "1.7.1") +bazel_dep(name = "abseil-cpp", version = "20240722.0.bcr.2", repo_name = "com_google_absl") +bazel_dep(name = "platforms", version = "0.0.10") +bazel_dep(name = "rules_cc", version = "0.0.16") +bazel_dep(name = "rules_python", version = "0.40.0") +bazel_dep(name = "pybind11_bazel", version = "2.13.6") #### DEV ONLY DEPENDENCIES BELOW HERE #### SUPPORTED_PYTHON_VERSIONS = [ - "3.12", - "3.11", - "3.10", - "3.9", - "3.8" + "3.12", + "3.11", + "3.10", + "3.9", + "3.8", ] DEFAULT_PYTHON = "3.11" -python = use_extension("@rules_python//python/extensions:python.bzl", "python", dev_dependency=True) +python = use_extension("@rules_python//python/extensions:python.bzl", "python", dev_dependency = True) + [ - python.toolchain( - python_version = version, - is_default = version == DEFAULT_PYTHON, - ) - for version in SUPPORTED_PYTHON_VERSIONS + python.toolchain( + ignore_root_user_error = True, # needed for CI + is_default = version == DEFAULT_PYTHON, + python_version = version, + ) + for version in SUPPORTED_PYTHON_VERSIONS ] -use_repo( - python, - python = "python_versions", -) +use_repo(python, python = "python_versions") -pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip", dev_dependency=True) -[ - pip.parse( - hub_name = "pypi", - python_version = version, - requirements_lock = "//pybind11_abseil/requirements:requirements_lock_" + version.replace('.','_') + ".txt", - ) - for version in SUPPORTED_PYTHON_VERSIONS +pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip", dev_dependency = True) +[ + pip.parse( + hub_name = "pypi", + python_version = version, + requirements_lock = "//pybind11_abseil/requirements:requirements_lock_" + version.replace(".", "_") + ".txt", + ) + for version in SUPPORTED_PYTHON_VERSIONS ] use_repo(pip, "pypi") diff --git a/README.md b/README.md index f1ad3fb..e992123 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,30 @@ # Pybind11 bindings for the Abseil C++ Common Libraries -![build_and_test](https://github.com/pybind/pybind11_abseil/workflows/build_and_test/badge.svg) +Github-CI: +| OS \ Build system | Bazel | CMake | +|:------- | :---: | :---: | +| Linux (`amd64`) | [![Build Status][amd64_linux_bazel_status]][amd64_linux_bazel_link] | [![Build Status][amd64_linux_cmake_status]][amd64_linux_cmake_link] | +| MacOS (`amd64`) | [![Build Status][amd64_macos_bazel_status]][amd64_macos_bazel_link] | [![Build Status][amd64_macos_cmake_status]][amd64_macos_cmake_link] | +| MacOS (`arm64`) | [![Build Status][arm64_macos_bazel_status]][arm64_macos_bazel_link] | [![Build Status][arm64_macos_cmake_status]][arm64_macos_cmake_link] | +| Windows (`amd64`) | [![Build Status][amd64_windows_bazel_status]][amd64_windows_bazel_link] | [![Build Status][amd64_windows_cmake_status]][amd64_windows_cmake_link] | + +[amd64_linux_bazel_status]: ./../../actions/workflows/amd64_linux_bazel.yml/badge.svg +[amd64_linux_bazel_link]: ./../../actions/workflows/amd64_linux_bazel.yml +[amd64_macos_bazel_status]: ./../../actions/workflows/amd64_macos_bazel.yml/badge.svg +[amd64_macos_bazel_link]: ./../../actions/workflows/amd64_macos_bazel.yml +[arm64_macos_bazel_status]: ./../../actions/workflows/arm64_macos_bazel.yml/badge.svg +[arm64_macos_bazel_link]: ./../../actions/workflows/arm64_macos_bazel.yml +[amd64_windows_bazel_status]: ./../../actions/workflows/amd64_windows_bazel.yml/badge.svg +[amd64_windows_bazel_link]: ./../../actions/workflows/amd64_windows_bazel.yml + +[amd64_linux_cmake_status]: ./../../actions/workflows/amd64_linux_cmake.yml/badge.svg +[amd64_linux_cmake_link]: ./../../actions/workflows/amd64_linux_cmake.yml +[amd64_macos_cmake_status]: ./../../actions/workflows/amd64_macos_cmake.yml/badge.svg +[amd64_macos_cmake_link]: ./../../actions/workflows/amd64_macos_cmake.yml +[arm64_macos_cmake_status]: ./../../actions/workflows/arm64_macos_cmake.yml/badge.svg +[arm64_macos_cmake_link]: ./../../actions/workflows/arm64_macos_cmake.yml +[amd64_windows_cmake_status]: ./../../actions/workflows/amd64_windows_cmake.yml/badge.svg +[amd64_windows_cmake_link]: ./../../actions/workflows/amd64_windows_cmake.yml [TOC] diff --git a/WORKSPACE b/WORKSPACE index 2d8e524..2e6bd4d 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1,12 +1,5 @@ -workspace(name = "com_google_pybind11_abseil") -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - -# To update a PINNED dependency to a new revision, -# a) update URL and strip_prefix to the new git commit hash -# b) get the sha256 hash of the commit by running: -# curl -L https://github.com/<...>.tar.gz | sha256sum -# On Mac, run curl -L https://github.com/<...>.tar.gz | shasum -a 256 -# and update the sha256 with the result. +workspace(name = "pybind11_abseil") +load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository", "new_git_repository") ################################################################################ # @@ -15,39 +8,65 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") # ################################################################################ -## `bazel_skylib` (PINNED) +## `bazel_skylib` # Needed for Abseil. -http_archive( - name = "bazel_skylib", # 2023-05-31T19:24:07Z - sha256 = "08c0386f45821ce246bbbf77503c973246ed6ee5c3463e41efc197fa9bc3a7f4", - strip_prefix = "bazel-skylib-288731ef9f7f688932bd50e704a91a45ec185f9b", - urls = ["https://github.com/bazelbuild/bazel-skylib/archive/288731ef9f7f688932bd50e704a91a45ec185f9b.zip"], +git_repository( + name = "bazel_skylib", + commit = "27d429d8d036af3d010be837cc5924de1ca8d163", + #tag = "1.7.1", + remote = "https://github.com/bazelbuild/bazel-skylib.git", +) +load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") +bazel_skylib_workspace() + +## Bazel rules... +git_repository( + name = "platforms", + commit = "05ec3a3df23fde62471f8288e344cc021dd87bab", + #tag = "0.0.10", + remote = "https://github.com/bazelbuild/platforms.git", +) + +git_repository( + name = "rules_java", + commit = "767e4410850453a10ccf89aa1cededf9de05c72e", + #tag = "8.6.3", + remote = "https://github.com/bazelbuild/rules_java.git", ) -## `abseil-cpp` (PINNED) +load("@rules_java//java:rules_java_deps.bzl", "rules_java_dependencies") +rules_java_dependencies() + +# note that the following line is what is minimally required from protobuf for the java rules +# consider using the protobuf_deps() public API from @com_google_protobuf//:protobuf_deps.bzl +load("@com_google_protobuf//bazel/private:proto_bazel_features.bzl", "proto_bazel_features") # buildifier: disable=bzl-visibility +proto_bazel_features(name = "proto_bazel_features") + +# register toolchains +load("@rules_java//java:repositories.bzl", "rules_java_toolchains") +rules_java_toolchains() + +## abseil-cpp # https://github.com/abseil/abseil-cpp -http_archive( +## Abseil-cpp +git_repository( name = "com_google_absl", - sha256 = "59d2976af9d6ecf001a81a35749a6e551a335b949d34918cfade07737b9d93c5", # SHARED_ABSL_SHA - strip_prefix = "abseil-cpp-20230802.0", - urls = [ - "https://github.com/abseil/abseil-cpp/archive/refs/tags/20230802.0.tar.gz" - ], + commit = "4447c7562e3bc702ade25105912dce503f0c4010", + #tag = "20240722.0", + remote = "https://github.com/abseil/abseil-cpp.git", ) -http_archive( +git_repository( name = "rules_python", - sha256 = "c68bdc4fbec25de5b5493b8819cfc877c4ea299c0dcb15c244c5a00208cde311", - strip_prefix = "rules_python-0.31.0", - url = "https://github.com/bazelbuild/rules_python/releases/download/0.31.0/rules_python-0.31.0.tar.gz", + commit = "1944874f6ba507f70d8c5e70df84622e0c783254", + #tag = "0.40.0", + remote = "https://github.com/bazelbuild/rules_python.git", ) load("@rules_python//python:repositories.bzl", "py_repositories", "python_register_multi_toolchains") - py_repositories() load("@rules_python//python/pip_install:repositories.bzl", "pip_install_dependencies") - pip_install_dependencies() DEFAULT_PYTHON = "3.11" @@ -86,33 +105,23 @@ multi_pip_parse( ) load("@pypi//:requirements.bzl", "install_deps") - install_deps() - -## `pybind11_bazel` (PINNED) +## `pybind11_bazel` # https://github.com/pybind/pybind11_bazel -http_archive( - name = "pybind11_bazel", - strip_prefix = "pybind11_bazel-2.11.1.bzl.2", - sha256 = "e2ba5f81f3bf6a3fc0417448d49389cc7950bebe48c42c33dfeb4dd59859b9a4", - urls = ["https://github.com/pybind/pybind11_bazel/releases/download/v2.11.1.bzl.2/pybind11_bazel-2.11.1.bzl.2.tar.gz"], +git_repository( + name = "pybind11_bazel", + commit = "2b6082a4d9d163a52299718113fa41e4b7978db5", + #tag = "v2.13.6", # 2024/10/21 + remote = "https://github.com/pybind/pybind11_bazel.git", ) -## `pybind11` (FLOATING) +## `pybind11` # https://github.com/pybind/pybind11 -http_archive( - name = "pybind11", - build_file = "@pybind11_bazel//:pybind11.BUILD", - strip_prefix = "pybind11-master", - urls = ["https://github.com/pybind/pybind11/archive/refs/heads/master.tar.gz"], - # For easy local testing with pybind11 releases: - # * Comment out the 2 lines above. - # * Uncomment and update the 3 lines below. - # * To compute the sha256 string: - # * Download the .tar.gz file (e.g. curl or wget). - # * sha256sum v2.10.4.tar.gz - # strip_prefix = "pybind11-2.10.4", - # sha256 = "832e2f309c57da9c1e6d4542dedd34b24e4192ecb4d62f6f4866a737454c9970", - # urls = ["https://github.com/pybind/pybind11/archive/refs/tags/v2.10.4.tar.gz"], +new_git_repository( + name = "pybind11", + build_file = "@pybind11_bazel//:pybind11-BUILD.bazel", + commit = "a2e59f0e7065404b44dfe92a28aca47ba1378dc4", + #tag = "v2.13.6", + remote = "https://github.com/pybind/pybind11.git", ) diff --git a/cmake/dependencies/CMakeLists.txt b/cmake/dependencies/CMakeLists.txt new file mode 100644 index 0000000..1359e58 --- /dev/null +++ b/cmake/dependencies/CMakeLists.txt @@ -0,0 +1,50 @@ +include(FetchContent) +set(BUILD_SHARED_LIBS ON) +set(BUILD_TESTING OFF) + +message(CHECK_START "Checking for external dependencies") +list(APPEND CMAKE_MESSAGE_INDENT " ") + +if(NOT TARGET absl::base) + if(USE_SYSTEM_ABSEIL) + # Version omitted, as absl only allows EXACT version matches + find_package(absl REQUIRED) + else() + message(CHECK_START "Fetching Abseil-cpp") + list(APPEND CMAKE_MESSAGE_INDENT " ") + # ensure that abseil also installs itself, since we are using it in our + # public API + set(ABSL_ENABLE_INSTALL ON) + set(ABSL_PROPAGATE_CXX_STD ON) + set(ABSL_USE_SYSTEM_INCLUDES ON) + set(ABSL_BUILD_TESTING OFF) + FetchContent_Declare( + absl + GIT_REPOSITORY "https://github.com/abseil/abseil-cpp.git" + GIT_TAG "20240722.0" + GIT_SHALLOW TRUE) + FetchContent_MakeAvailable(absl) + list(POP_BACK CMAKE_MESSAGE_INDENT) + message(CHECK_PASS "fetched") + endif() +endif() + +if(NOT TARGET pybind11::pybind11_headers) + if(USE_SYSTEM_PYBIND) + find_package(pybind11 2.13.6 REQUIRED) + else() + message(CHECK_START "Fetching pybind11") + list(APPEND CMAKE_MESSAGE_INDENT " ") + FetchContent_Declare( + pybind11 + GIT_REPOSITORY "https://github.com/pybind/pybind11.git" + GIT_TAG "v2.13.6" + GIT_SHALLOW TRUE) + FetchContent_MakeAvailable(pybind11) + list(POP_BACK CMAKE_MESSAGE_INDENT) + message(CHECK_PASS "fetched") + endif() +endif() + +list(POP_BACK CMAKE_MESSAGE_INDENT) +message(CHECK_PASS "all dependencies found") diff --git a/pybind11_abseil/CMakeLists.txt b/pybind11_abseil/CMakeLists.txt index d1b7483..7550190 100644 --- a/pybind11_abseil/CMakeLists.txt +++ b/pybind11_abseil/CMakeLists.txt @@ -42,14 +42,18 @@ target_link_libraries(ok_status_singleton_pyinit_google3 # ok_status_singleton ======================================================= -add_library(ok_status_singleton SHARED ok_status_singleton_py_extension_stub.cc) +pybind11_add_module(ok_status_singleton MODULE + ok_status_singleton_py_extension_stub.cc) add_library(pybind11_abseil::ok_status_singleton ALIAS ok_status_singleton) +# note: macOS is APPLE and also UNIX ! +if(APPLE) + set_target_properties(ok_status_singleton PROPERTIES SUFFIX ".so") +endif() + target_include_directories(ok_status_singleton INTERFACE $) -set_target_properties(ok_status_singleton PROPERTIES PREFIX "") - target_link_libraries(ok_status_singleton PUBLIC ok_status_singleton_pyinit_google3) @@ -150,14 +154,29 @@ target_link_libraries(status_pyinit_google3 PUBLIC register_status_bindings) # status ==================================================================== -add_library(status SHARED status_py_extension_stub.cc) -add_library(pybind11_abseil::status ALIAS status) +pybind11_add_module(status_py_extension_stub MODULE status_py_extension_stub.cc) +set_target_properties(status_py_extension_stub PROPERTIES LIBRARY_OUTPUT_NAME + "status") + +# note: macOS is APPLE and also UNIX ! +if(APPLE) + set_target_properties( + status_py_extension_stub + PROPERTIES SUFFIX ".so" INSTALL_RPATH "@loader_path;@loader_path/../.libs") +elseif(UNIX) + set_target_properties(status_py_extension_stub + PROPERTIES INSTALL_RPATH "$ORIGIN:$ORIGIN/../.libs") +endif() + +add_library(pybind11_abseil::status ALIAS status_py_extension_stub) -target_include_directories(status INTERFACE $) +target_include_directories(status_py_extension_stub + INTERFACE $) -set_target_properties(status PROPERTIES PREFIX "") +set_target_properties(status_py_extension_stub PROPERTIES PREFIX "") -target_link_libraries(status PUBLIC status_pyinit_google3 absl::status) +target_link_libraries(status_py_extension_stub PUBLIC status_pyinit_google3 + absl::status) # import_status_module ========================================================= @@ -167,7 +186,7 @@ add_library(pybind11_abseil::import_status_module ALIAS import_status_module) target_include_directories(import_status_module INTERFACE $) -target_link_libraries(import_status_module PUBLIC status) +add_dependencies(import_status_module status_py_extension_stub) # status_casters =============================================================== @@ -180,23 +199,24 @@ target_include_directories(status_casters target_link_libraries(status_casters INTERFACE import_status_module status_caster statusor_caster) -add_subdirectory(tests) +if(BUILD_TESTING) + add_subdirectory(tests) +endif() if(CMAKE_INSTALL_PYDIR) # Copying to two target directories for simplicity. It is currently unknown # how to determine here which copy is actually being used. install( - TARGETS status ok_status_singleton + TARGETS status_py_extension_stub ok_status_singleton EXPORT pybind11_abseilTargets LIBRARY DESTINATION ${CMAKE_INSTALL_PYDIR}/pybind11_abseil ARCHIVE DESTINATION ${CMAKE_INSTALL_PYDIR}/pybind11_abseil RUNTIME DESTINATION ${CMAKE_INSTALL_PYDIR}/pybind11_abseil) install( - TARGETS status ok_status_singleton + TARGETS status_py_extension_stub ok_status_singleton EXPORT pybind11_abseil_cppTargets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}) - endif() diff --git a/pybind11_abseil/absl_casters.h b/pybind11_abseil/absl_casters.h index a465f4a..e021d79 100644 --- a/pybind11_abseil/absl_casters.h +++ b/pybind11_abseil/absl_casters.h @@ -667,6 +667,9 @@ template struct type_caster> : variant_caster> {}; +template <> +struct type_caster + : void_caster {}; #endif } // namespace detail diff --git a/pybind11_abseil/tests/BUILD b/pybind11_abseil/tests/BUILD index d42a88d..448b852 100644 --- a/pybind11_abseil/tests/BUILD +++ b/pybind11_abseil/tests/BUILD @@ -130,6 +130,7 @@ pybind_extension( srcs = ["status_example.cc"], deps = [ "//pybind11_abseil:status_casters", + "@com_google_absl//absl/memory", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", ], diff --git a/pybind11_abseil/tests/CMakeLists.txt b/pybind11_abseil/tests/CMakeLists.txt index 1204321..f7f390e 100644 --- a/pybind11_abseil/tests/CMakeLists.txt +++ b/pybind11_abseil/tests/CMakeLists.txt @@ -1,6 +1,6 @@ # cpp_capsule_tools_testing ==================================================== -pybind11_add_module(cpp_capsule_tools_testing SHARED +pybind11_add_module(cpp_capsule_tools_testing MODULE cpp_capsule_tools_testing.cc) target_link_libraries( @@ -26,7 +26,7 @@ add_test( # absl_example ================================================================= -pybind11_add_module(absl_example SHARED absl_example.cc) +pybind11_add_module(absl_example MODULE absl_example.cc) target_link_libraries( absl_example @@ -57,7 +57,7 @@ add_test( # missing_import =============================================================== -pybind11_add_module(missing_import SHARED missing_import.cc) +pybind11_add_module(missing_import MODULE missing_import.cc) target_compile_options(missing_import PUBLIC -UNDEBUG) @@ -83,7 +83,7 @@ add_test( # status_example =============================================================== -pybind11_add_module(status_example SHARED status_example.cc) +pybind11_add_module(status_example MODULE status_example.cc) target_link_libraries(status_example PRIVATE status_casters absl::status absl::statusor) diff --git a/pybind11_abseil/tests/absl_example.cc b/pybind11_abseil/tests/absl_example.cc index 576e5ca..00943b8 100644 --- a/pybind11_abseil/tests/absl_example.cc +++ b/pybind11_abseil/tests/absl_example.cc @@ -344,6 +344,18 @@ std::vector> Identity( return value; } +bool CheckVariant(const absl::variant variant, + bool given, int value) { + if (!given && !absl::holds_alternative(variant)) return true; + if (given && absl::holds_alternative(variant) && + absl::get(variant) == value) + return true; + return false; +} + +absl::variant MakeVariant() { return {}; } +absl::variant MakeVariant(int value) { return value; } + } // namespace test } // namespace pybind11 @@ -487,6 +499,15 @@ PYBIND11_MODULE(absl_example, m) { m.def("VariantToInt", &VariantToInt); m.def("Identity", &Identity); m.def("IdentityWithCopy", &IdentityWithCopy); + + m.def("check_variant", &CheckVariant, + arg("variant") = absl::variant{}, + arg("given") = false, arg("value") = 0); + m.def("make_variant", + (absl::variant (*)())&MakeVariant); + m.def("make_variant", + (absl::variant (*)(int))&MakeVariant, + arg("value")); } } // namespace test diff --git a/pybind11_abseil/tests/absl_test.py b/pybind11_abseil/tests/absl_test.py index 49a9ffd..dda6948 100644 --- a/pybind11_abseil/tests/absl_test.py +++ b/pybind11_abseil/tests/absl_test.py @@ -612,6 +612,21 @@ def test_variant(self): else: self.assertNotEqual(objs, vector) + def test_pass_default_nullopt(self): + self.assertTrue(absl_example.check_variant()) + + def test_pass_value(self): + self.assertTrue(absl_example.check_variant(5, True, 5)) + + def test_pass_none(self): + self.assertTrue(absl_example.check_variant(None, False)) + + def test_return_value(self): + self.assertEqual(absl_example.make_variant(5), 5) + + def test_return_none(self): + self.assertIsNone(absl_example.make_variant()) + if __name__ == '__main__': absltest.main() diff --git a/pybind11_abseil/tests/cpp_capsule_tools_testing.cc b/pybind11_abseil/tests/cpp_capsule_tools_testing.cc index a26742b..7f659fc 100644 --- a/pybind11_abseil/tests/cpp_capsule_tools_testing.cc +++ b/pybind11_abseil/tests/cpp_capsule_tools_testing.cc @@ -3,6 +3,7 @@ // All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +#include #if true // go/pybind11_include_order #include #endif @@ -19,11 +20,16 @@ PYBIND11_MODULE(cpp_capsule_tools_testing, m) { namespace cpp_capsule_tools = pybind11_abseil::cpp_capsule_tools; m.def("make_bad_capsule", [](bool pass_name) { - // https://docs.python.org/3/c-api/capsule.html: - // The pointer argument may not be NULL. + // https://docs.python.org/3/c-api/capsule.html: + // The pointer argument may not be NULL. +#if (defined(_WIN64) || defined(_WIN32)) + // see C2466 cannot allocate an array of constant size 0 + int* dummy_pointee = nullptr; +#else int dummy_pointee[] = {}; // This will become a dangling pointer when this // function returns: We don't want the pointer to be used. Hopefully if it // is used unintentionally, one of the sanitizers will flag it. +#endif return py::capsule(static_cast(dummy_pointee), pass_name ? "NotGood" : nullptr); }); diff --git a/pybind11_abseil/tests/status_example.cc b/pybind11_abseil/tests/status_example.cc index a5e10c7..da2bf26 100644 --- a/pybind11_abseil/tests/status_example.cc +++ b/pybind11_abseil/tests/status_example.cc @@ -1,5 +1,10 @@ #include +#include +#include +#include + +#include "absl/memory/memory.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "pybind11_abseil/status_casters.h" @@ -88,7 +93,7 @@ absl::StatusOr> ReturnUniquePtrStatusOr(int value) { class IntGetter { public: - virtual ~IntGetter() { } + virtual ~IntGetter() {} virtual absl::StatusOr Get(int i) const = 0; }; @@ -134,11 +139,16 @@ PYBIND11_MODULE(status_example, m) { }); m.def("make_bad_capsule", [](bool pass_name) { - // https://docs.python.org/3/c-api/capsule.html: - // The pointer argument may not be NULL. + // https://docs.python.org/3/c-api/capsule.html: + // The pointer argument may not be NULL. +#if (defined(_WIN64) || defined(_WIN32)) + // see C2466 cannot allocate an array of constant size 0 + int* dummy_pointee = nullptr; +#else int dummy_pointee[] = {}; // This will become a dangling pointer when this // function returns: We don't want the pointer to be used. Hopefully if it // is used unintentionally, one of the sanitizers will flag it. +#endif return capsule(static_cast(dummy_pointee), pass_name ? "NotGood" : nullptr); }); @@ -200,8 +210,8 @@ PYBIND11_MODULE(status_example, m) { class_(m, "IntGetter") .def(init()) .def("Get", &IntGetter::Get); - m.def("call_get_redirect_to_python", &CallGetRedirectToPython, - arg("ptr"), arg("i")); + m.def("call_get_redirect_to_python", &CallGetRedirectToPython, arg("ptr"), + arg("i")); // Needed to exercise raw_code() != code(). m.def("status_from_int_code", [](int code, const std::string& msg) { diff --git a/pybind11_abseil/tests/status_testing_no_cpp_eh_test_lib.py b/pybind11_abseil/tests/status_testing_no_cpp_eh_test_lib.py index e1b0a2d..5068716 100644 --- a/pybind11_abseil/tests/status_testing_no_cpp_eh_test_lib.py +++ b/pybind11_abseil/tests/status_testing_no_cpp_eh_test_lib.py @@ -54,7 +54,7 @@ def cb(): else: expected = ( r"INVALID_ARGUMENT: Unable to cast Python instance of type to C\+\+ type 'absl::(\w*::)?Status'" + r" 'list'> to C\+\+ type ('absl::(\w*::)?Status'|'\?')" ) self.assertRegex(self.tm.CallCallbackWithStatusReturn(cb), expected) @@ -118,7 +118,7 @@ def cb(): else: expected = ( r"INVALID_ARGUMENT: Unable to cast Python instance of type to C\+\+ type 'absl::(\w*::)?StatusOr'" + r" 'str'> to C\+\+ type ('absl::(\w*::)?StatusOr'|'\?')" ) self.assertRegex(self.tm.CallCallbackWithStatusOrIntReturn(cb), expected) diff --git a/scripts/build_and_run_tests_bazel.sh b/scripts/build_and_run_tests_bazel.sh index 113e363..c1ddd13 100755 --- a/scripts/build_and_run_tests_bazel.sh +++ b/scripts/build_and_run_tests_bazel.sh @@ -19,10 +19,15 @@ fi echo "Building and testing in $PWD using 'python' (version $PYVERSION)." -bazel clean --expunge # Force a dep update - -BAZEL_CXXOPTS="-std=c++17" bazel test ... --test_output=errors "$@" --enable_bzlmod -BAZEL_CXXOPTS="-std=c++20" bazel test ... --test_output=errors "$@" --enable_bzlmod - -BAZEL_CXXOPTS="-std=c++17" bazel test ... --test_output=errors "$@" --noenable_bzlmod -BAZEL_CXXOPTS="-std=c++20" bazel test ... --test_output=errors "$@" --noenable_bzlmod +bazel clean --expunge # Force a deep update + +# Can't use BAZEL_CXXOPTS since it will be override by the bazelrc cxxopt need +# to use --cxxopt on the command line instead which will override the bazelrc +# cxxopt config. +bazel test --cxxopt=-std=c++14 ... --test_output=errors "$@" --enable_bzlmod +bazel test --cxxopt=-std=c++17 ... --test_output=errors "$@" --enable_bzlmod +bazel test --cxxopt=-std=c++20 ... --test_output=errors "$@" --enable_bzlmod + +#bazel test --cxxopt=-std=c++14 ... --test_output=errors "$@" --noenable_bzlmod --enable_workspace +bazel test --cxxopt=-std=c++17 ... --test_output=errors "$@" --noenable_bzlmod --enable_workspace +bazel test --cxxopt=-std=c++20 ... --test_output=errors "$@" --noenable_bzlmod --enable_workspace diff --git a/scripts/build_and_run_tests_cmake.sh b/scripts/build_and_run_tests_cmake.sh index 73a2fa9..b6dc855 100755 --- a/scripts/build_and_run_tests_cmake.sh +++ b/scripts/build_and_run_tests_cmake.sh @@ -54,11 +54,11 @@ if [[ $is_in_virtual_env == "false" ]]; then if ! [ -d "$VENV_DIR" ]; then echo "Installing..." echo -e "\e[33mInstalling a virtualenv to $VENV_DIR. The setup is long the first time, please wait.\e[0m" - virtualenv -p $PYBIN $VENV_DIR + virtualenv -p "$PYBIN" "$VENV_DIR" else echo -e "\e[33mReusing virtualenv from $VENV_DIR.\e[0m" fi - source $VENV_DIR/bin/activate + source "${VENV_DIR}/bin/activate" fi # We only exit the virtualenv if we created one. @@ -75,8 +75,10 @@ pip3 install --upgrade -r $(python3 -c 'import sys; print("./pybind11_abseil/req echo "Building and testing in $PWD using 'python' (version $PYVERSION)." -export PYTHON_BIN_PATH=`which python3` -export PYTHON_LIB_PATH=`python3 -c "import sysconfig; print(sysconfig.get_path('include'))"` +PYTHON_BIN_PATH="$(which python3)" +export PYTHON_BIN_PATH +PYTHON_LIB_PATH=$(python3 -c "import sysconfig; print(sysconfig.get_path('include'))") +export PYTHON_LIB_PATH echo "Using PYTHON_BIN_PATH: $PYTHON_BIN_PATH" echo "Using PYTHON_LIB_PATH: $PYTHON_LIB_PATH"