diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index cd67ece4097c..ce76720cd01b 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -9,11 +9,15 @@ # For Orchestrator related PRs /src/cephadm @ceph/orchestrators +/src/cephadm/cephadmlib/daemons/smb.py @ceph/orchestrators @ceph/smb /src/pybind/mgr/orchestrator @ceph/orchestrators /src/pybind/mgr/rook @ceph/orchestrators /src/pybind/mgr/cephadm @ceph/orchestrators +/src/pybind/mgr/cephadm/services/smb.py @ceph/orchestrators @ceph/smb /src/pybind/mgr/test_orchestrator @ceph/orchestrators +/src/pybind/mgr/smb @ceph/orchestrators @ceph/smb /src/python-common @ceph/orchestrators +/src/python-common/ceph/smb @ceph/orchestrators @ceph/smb /qa/workunits/cephadm @ceph/orchestrators /qa/tasks/cephadm.py @ceph/orchestrators /qa/tasks/cephadm_cases @ceph/orchestrators @@ -181,3 +185,19 @@ README* @ceph/doc-writers /src/test/cls_version @ceph/rgw /src/test/rgw @ceph/rgw /src/test/test_rgw* @ceph/rgw + +# build scripts and tools +/ceph.spec.in @ceph/build-sig +/container @ceph/build-sig +/debian @ceph/build-sig +/do_cmake.sh @ceph/build-sig +/install-deps.sh @ceph/build-sig +/make-debs.sh @ceph/build-sig +/make-srpm.sh @ceph/build-sig +/run-make-check.sh @ceph/build-sig +/src/script/build-with-container.py @ceph/build-sig +/src/script/buildcontainer-setup.sh @ceph/build-sig +/src/script/run-make.sh @ceph/build-sig + +# cephfs proxy +/src/libcephfs_proxy @ceph/smb diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 000000000000..9215b9a93513 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,399 @@ +# Ceph Coding Agent Instructions + +## Repository Overview + +Ceph is a scalable distributed storage system providing object, block, and file storage in a unified platform. The codebase is large (hundreds of megabytes) with many CMakeLists.txt files across the project. + +**Primary Languages & Technologies:** +- C++ (main codebase - follows Google C++ Style Guide with modifications) +- Python 3 (management tools, tests) +- CMake (build system using Ninja) +- Bash (scripts and utilities) + +**Key Components:** +- **MON (Monitor)**: Cluster membership and state (`src/mon/`) +- **OSD (Object Storage Daemon)**: Data storage and replication (`src/osd/`) +- **MDS (Metadata Server)**: CephFS metadata (`src/mds/`) +- **MGR (Manager)**: Cluster management and monitoring (`src/mgr/`) +- **RGW (RADOS Gateway)**: Object storage API (S3/Swift) (`src/rgw/`) +- **Client Libraries**: librados, librbd, libcephfs (`src/librados/`, `src/librbd/`, etc.) + +## Critical Build Requirements + +**IMPORTANT: Git Submodule Handling** +- **DO NOT commit submodule updates** unless specifically working on submodule version updates +- Use `git add ` instead of `git add .` to avoid accidentally staging submodule changes +- Submodules include: `ceph-erasure-code-corpus`, `ceph-object-corpus`, `src/BLAKE3`, and others +- If submodules appear modified in `git status`, verify you haven't unintentionally updated them + +### Prerequisites (MUST run before building) +```bash +# 1. Initialize submodules (REQUIRED - will fail without this) +git submodule update --init --recursive --recommend-shallow --progress + +# 2. Install dependencies +./install-deps.sh + +# 3. For Ubuntu/Debian, also install (verified necessary): +apt install python3-routes +``` + +### Build Process (Standard Development Build) +```bash +# From repository root: +./do_cmake.sh +cd build +ninja -j3 # Use -j3 or lower to avoid OOM; each job needs ~2.5GB RAM +``` + +**IMPORTANT BUILD NOTES:** +- `do_cmake.sh` creates **Debug builds** by default (if `.git` exists). Debug builds are 5x slower than release builds. +- For performance testing, always use: `ARGS="-DCMAKE_BUILD_TYPE=RelWithDebInfo" ./do_cmake.sh` +- The `build/` directory must NOT exist before running `do_cmake.sh` (script will exit with error) +- Build can take 40-60GB disk space. Ensure adequate space before starting. +- Memory: Plan for ~2.5GB RAM per ninja job. Use `-j` to limit jobs on constrained systems. +- If you see `g++: fatal error: Killed signal terminated program cc1plus`, reduce ninja jobs. + +### Running Tests + +**Unit Tests (ctest):** +```bash +cd build +ninja # Ensure build is complete first +ctest -j$(nproc) # Run all tests in parallel + +# To run specific tests: +ctest -R + +# For verbose output: +ctest -V -R +``` + +**Note:** Targets starting with `unittest_*` are run by ctest. Targets starting with `ceph_test_*` must be run manually. + +**Make Check (Full Test Suite):** +```bash +# From repository root: +./run-make-check.sh + +# Or manually: +cd build +ninja check -j$(nproc) +``` + +**Prerequisites for make check:** +- `ulimit -n` must be >= 1024 (script sets this automatically) +- `hostname --fqdn` must work (will fail otherwise) +- Sufficient file descriptors and AIO resources + +**Test logs on failure:** Located in `build/Testing/Temporary/` + +**Standalone Tests:** +```bash +cd build +../qa/run-standalone.sh # Runs standalone test suite +``` + +Note: Standalone tests are more extensive and take longer. Capture output to file for analysis. + +### Development Cluster (vstart) + +Start a local test cluster for development: +```bash +cd build +ninja vstart # Builds minimal required components +../src/vstart.sh --debug --new -x --localhost --bluestore +./bin/ceph -s # Check cluster status + +# Test commands: +./bin/rbd create foo --size 1000 +./bin/rados -p foo bench 30 write + +# Stop cluster: +../src/stop.sh +``` + +**vstart Options:** +- `--new` or `-n`: Start fresh cluster, destroying existing data +- `--debug` or `-d`: Enable debug logging +- `--localhost` or `-l`: Bind to localhost only +- `--bluestore` or `-b`: Use BlueStore backend (default) +- `-x`: Enable cephx authentication (on by default) +- No flags: Reuses existing cluster data (preserves data between restarts) + +## Coding Standards + +### C++ Code (src/) +- Follow Google C++ Style Guide with Ceph modifications (see `CodingStyle` file) +- **Naming:** + - Functions: `use_underscores()` (NOT CamelCase) + - Classes: `CamelCase` with `m_` prefix for members + - Structs (data containers): `lowercase_t` + - Constants: `ALL_CAPS` (NOT Google's kConstantName style) + - Enums: `ALL_CAPS` +- **Formatting:** + - Indent: 2 spaces (NO tabs) + - Always use braces for conditionals, even one-liners + - No spaces inside conditionals: `if (foo)` not `if ( foo )` +- **Headers:** Use `#pragma once` (preferred over include guards) +- Use `.clang-format` for C++ code formatting + +### Python Code +- Follow PEP-8 strictly for new code +- Multiple `tox.ini` files exist for Python linting (mypy, flake8, pylint): + - `src/pybind/tox.ini` (includes mypy type checking) + - `src/cephadm/tox.ini` + - `src/ceph-volume/tox.ini` + - `src/python-common/tox.ini` + - `qa/tox.ini` +- Run Python tests with `tox` in the relevant directory before submitting + +### Commit Messages +- **Title Format:** `: ` (max 72 chars) + - Examples: `mon: add perf counter for finisher`, `doc/mgr: fix typo` +- **Body:** Explain both "what" changed and "why", not just "what" changed +- **Required:** `Signed-off-by: Your Name ` (use `git commit -s`) +- **Optional:** `Fixes: http://tracker.ceph.com/issues/XXXXX` (before Signed-off-by) + +**Common Subsystems:** +- Core daemons: `mon`, `osd`, `mds`, `mgr`, `rgw` +- Client libraries: `rados`, `rbd`, `librados`, `librbd`, `libcephfs` +- Filesystems: `cephfs`, `cephfs-shell`, `cephfs-top` +- Management: `mgr/dashboard`, `mgr/orchestrator`, `mgr/telemetry`, `cephadm`, `ceph-volume` +- Storage backends: `bluestore`, `objectstore`, `rocksdb` +- Core libraries: `common`, `global`, `msg`, `auth`, `crush`, `osdc` +- Erasure coding: `erasure-code`, `cls` +- Testing/QA: `qa`, `qa/suites`, `qa/tasks` +- Build/Infrastructure: `build`, `cmake`, `debian`, `rpm`, `doc`, `admin` +- Tools: `tools`, `rbd-mirror`, `rbd-nbd`, `ceph-fuse` +- Other: `crimson`, `pybind`, `python-common`, `compressor`, `crypto` +- Use path-based prefix for subdirectories: `mgr/dashboard`, `qa/suites`, `src/pybind` + +## Common Build Patterns + +### CMake Options (via ARGS) +```bash +# Performance build: +ARGS="-DCMAKE_BUILD_TYPE=RelWithDebInfo" ./do_cmake.sh + +# Without RADOS Gateway: +ARGS="-DWITH_RADOSGW=OFF" ./do_cmake.sh + +# Use system Boost: +ARGS="-DWITH_SYSTEM_BOOST=ON" ./do_cmake.sh + +# Enable ccache/sccache (auto-detected and used if available in PATH): +# No manual configuration needed - do_cmake.sh detects them automatically + +# Custom compiler: +ARGS="-DCMAKE_C_COMPILER=gcc-12 -DCMAKE_CXX_COMPILER=g++-12" ./do_cmake.sh +``` + +### Building Specific Targets +```bash +cd build +ninja # Build only specific target +``` + +## Container Builds + +Use `src/script/build-with-container.py` for isolated builds: + +```bash +# Build on CentOS 9: +./src/script/build-with-container.py -d centos9 -b build.centos9 -e build + +# Build on Ubuntu 22.04: +./src/script/build-with-container.py -d ubuntu22.04 -b build.u2204 -e build + +# Run tests in container: +./src/script/build-with-container.py -e tests + +# Interactive shell: +./src/script/build-with-container.py -e interactive +``` + +## CI/CD Workflows + +**GitHub Actions Workflows (`.github/workflows/`):** +- `pr-checklist.yml`: Validates PR checklist completion +- `check-license.yml`: Ensures no GPL code in certain areas +- `pr-check-deps.yml`: Dependency validation +- Other workflows for backports, triage, etc. + +**Jenkins CI:** +- Triggered by PRs or comment: `jenkins test make check` +- Runs full `run-make-check.sh` on Sepia Lab infrastructure +- Results posted back to GitHub PR + +## Directory Structure + +**Essential Paths:** +``` +ceph/ +├── src/ # All source code +│ ├── mon/ # Monitor daemon +│ ├── osd/ # OSD daemon +│ ├── mds/ # MDS daemon +│ ├── mgr/ # Manager daemon +│ ├── rgw/ # RADOS Gateway +│ ├── client/ # Client-side code +│ ├── common/ # Common utilities +│ ├── msg/ # Messaging layer +│ ├── auth/ # Authentication +│ ├── cls/ # Object classes +│ ├── librados/ # RADOS client library +│ ├── librbd/ # RBD client library +│ ├── pybind/ # Python bindings +│ ├── test/ # Unit tests +│ ├── script/ # Build and utility scripts +│ └── vstart.sh # Development cluster script +├── qa/ # Integration test suites (teuthology) +├── doc/ # Documentation (RST format) +├── cmake/ # CMake modules +├── build/ # Build directory (created by do_cmake.sh) +├── CMakeLists.txt # Root CMake configuration +├── do_cmake.sh # CMake wrapper script +├── install-deps.sh # Dependency installation +├── run-make-check.sh # Full test suite runner +└── .clang-format # C++ formatting rules +``` + +## Common Pitfalls & Solutions + +### Build Failures +1. **"No such file or directory" for submodule files:** + - **Solution:** Run `git submodule update --init --recursive --recommend-shallow` + +2. **"g++: fatal error: Killed":** + - **Solution:** Out of memory. Use `ninja -j2` or `ninja -j1` + +3. **"'build' dir already exists":** + - **Solution:** `rm -rf build` then re-run `do_cmake.sh` + +4. **Python module import errors:** + - **Solution:** Run `apt install python3-routes` (often missed in install-deps.sh) + +### Test Failures +1. **"ulimit -n too small":** + - **Solution:** `ulimit -n 4096` before running tests + +2. **"hostname --fqdn" fails:** + - **Solution:** Fix system hostname configuration + +3. **Temp files accumulate in /tmp:** + - **Solution:** `rm -fr /tmp/ceph-asok.*` between test runs + +## Documentation + +- Build documentation: `admin/build-doc` (requires packages from `doc_deps.deb.txt`) +- Documentation source: `doc/` directory (RST format) +- Follow Google Developer Documentation Style Guide for doc changes +- Doc changes must accompany user-facing functionality changes + +## Submitting Changes + +Ceph has two distinct workflows for submitting changes: + +### Workflow 1: Regular PRs (targeting main branch) + +**PR Requirements:** +1. **Target branch**: `main` (NOT stable branches) +2. **Commits must be signed**: Use `git commit -s` to add `Signed-off-by:` line +3. **Follow commit message format** (see Commit Messages section above) +4. **Update documentation** for user-facing changes +5. **Code licensing**: Must be LGPL 2.1/3.0 compatible (NO GPL in most areas) + +**PR Title Format:** +- Use `: ` format +- Examples: `osd: fix memory leak in BlueStore`, `mgr/dashboard: add user management UI` + +**PR Description:** +- Summarize the PR as a whole +- Link to tracker issues if applicable +- Can include notices to maintainers, to-do lists, etc. + +**Flagging for Backport:** +If changes should be backported to stable branches after merging: +1. Open a tracker issue at https://tracker.ceph.com explaining: + - What bug is fixed + - Why the bug needs to be fixed in `` +2. Fill out the Backport field: `Backport: mimic, nautilus` + +**Before Submitting:** +```bash +# Build and verify: +./install-deps.sh +./do_cmake.sh +cd build && ninja + +# Run tests (recommended): +ctest -R +``` + +### Workflow 2: Backport PRs (targeting stable branches) + +**IMPORTANT:** All fixes should land in `main` first, then be cherry-picked to stable branches. + +**PR Requirements:** +1. **Target branch**: Stable branch (e.g., `nautilus`, `octopus`, `pacific`, `quincy`, `reef`, `squid`, `tentacle`) +2. **PR Title Format**: **MUST** be prefixed with target branch name + - Format: `: : ` + - Examples: + - `nautilus: osd: fix memory leak in BlueStore` + - `squid: mgr/dashboard: fix user permissions bug` + - `tentacle: mon: prevent election storm` +3. **Milestone**: Set PR milestone to the target stable branch name (e.g., milestone = "nautilus") +4. **Cherry-pick requirements**: + - Use `git cherry-pick -x` to preserve original commit reference + - Do NOT modify original commit message except to add "Conflicts" section + - All commits must be cherry-picked from `main` branch + +**Cherry-Picking Rules:** +- Cherry-picks MUST use `git cherry-pick -x` +- Check `main` git history for follow-up fixes: `git log --grep ` +- If cherry-pick cannot be done, explain why in commit message +- Commit message generated by `git cherry-pick -x` must NOT be modified except: + - Add "Conflicts" section below "cherry picked from commit..." line + - Describe manual changes in "Conflicts" section + - List all files with manual changes (not just git-flagged conflicts) + +**Conflicts Section Example:** +``` +(cherry picked from commit 01d73020da12f40ccd95ea1e49cfcf663f1a3a75) + +Conflicts: + src/osd/batlo.cc +- add_batlo_check has an extra arg in newer code +``` + +**Backport Tracker Workflow:** +1. Create backport tracker issues for tracking (if targeting multiple stable branches) +2. Use `src/script/backport-create-issue` script from `main` branch +3. Use `src/script/ceph-backport.sh` script to automate cherry-picking and PR creation +4. Branch naming convention: `wip--` + +**Labelling:** +- Set Milestone to target stable branch +- Apply same component label as original `main` PR + +**DO NOT merge backport PRs yourself** - this is done by release maintainers. + +## Quick Reference + +**Environment Variables:** +- `BUILD_DIR`: Override build directory (default: `build`) +- `CEPH_GIT_DIR`: Path to ceph git checkout (default: `..`) +- `ARGS`: Pass additional CMake arguments to do_cmake.sh + +**Important Files:** +- `CONTRIBUTING.rst`: Contribution guidelines +- `SubmittingPatches.rst`: Patch submission process for main branch +- `SubmittingPatches-backports.rst`: Detailed backport workflow and requirements +- `CodingStyle`: Coding standards +- `README.md`: General project information +- `.clang-format`: C++ code formatting rules + +--- + +**Trust these instructions first.** Only search for additional information if these instructions are incomplete or incorrect. The Ceph build system is complex but well-documented. When in doubt, consult README.md, SubmittingPatches.rst, or ask for guidance. diff --git a/.github/labeler.yml b/.github/labeler.yml index 932b2a23018c..1dcdf585963a 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -55,6 +55,7 @@ mgr: - src/pybind/mgr/ceph_module.pyi - src/pybind/mgr/mgr_module.py - src/pybind/mgr/mgr_util.py + - src/pybind/mgr/cherrypy_mgr.py - src/pybind/mgr/object_format.py - src/pybind/mgr/requirements.txt - src/pybind/mgr/tox.ini diff --git a/.github/milestone.yml b/.github/milestone.yml index bf151aee6846..c29958c2993b 100644 --- a/.github/milestone.yml +++ b/.github/milestone.yml @@ -7,3 +7,4 @@ base-branch: - "(reef)" - "(squid)" - "(tentacle)" + - "(umbrella)" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 17674d347bd3..ccb9d5eaea8d 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,68 +1,34 @@ - - - - -## Contribution Guidelines -- To sign and title your commits, please refer to [Submitting Patches to Ceph](https://github.com/ceph/ceph/blob/main/SubmittingPatches.rst). + +Closes cobaltcore-dev/cloud-storage# -- If you are submitting a fix for a stable branch (e.g. "quincy"), please refer to [Submitting Patches to Ceph - Backports](https://github.com/ceph/ceph/blob/master/SubmittingPatches-backports.rst) for the proper workflow. +## Backport file -- When filling out the below checklist, you may click boxes directly in the GitHub web UI. When entering or editing the entire PR message in the GitHub web UI editor, you may also select a checklist item by adding an `x` between the brackets: `[x]`. Spaces and capitalization matter when checking off items this way. +- [ ] `release-management/backports/.md` added (or updated) by this PR +- [ ] `id` in frontmatter matches the filename stem +- [ ] `provenance.upstream_prs` set (or `provenance.type: other` with an `other:` block) -## Checklist -- Tracker (select at least one) - - [ ] References tracker ticket - - [ ] Very recent bug; references commit where it was introduced - - [ ] New feature (ticket optional) - - [ ] Doc update (no ticket needed) - - [ ] Code cleanup (no ticket needed) -- Component impact - - [ ] Affects [Dashboard](https://tracker.ceph.com/projects/dashboard/issues/new), opened tracker ticket - - [ ] Affects [Orchestrator](https://tracker.ceph.com/projects/orchestrator/issues/new), opened tracker ticket - - [ ] No impact that needs to be tracked -- Documentation (select at least one) - - [ ] Updates relevant documentation - - [ ] No doc update is appropriate -- Tests (select at least one) - - [ ] Includes [unit test(s)](https://docs.ceph.com/en/latest/dev/developer_guide/tests-unit-tests/) - - [ ] Includes [integration test(s)](https://docs.ceph.com/en/latest/dev/developer_guide/testing_integration_tests/) - - [ ] Includes bug reproducer - - [ ] No tests +## Stage-B risk (filled per `release-management/backports/RISK-RUBRIC.md`) -
-Show available Jenkins commands +- [ ] `blast` — cosmetic / availability / data-loss +- [ ] `conflict` — clean / trivial / substantive +- [ ] `coverage` — strong / partial / weak +- [ ] Risk-notes paragraph in the prose section (required for `high` band) -- `jenkins test classic perf` [Jenkins Job](https://jenkins.ceph.com/view/all/job/ceph-perf-classic/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-perf-pull-requests/config/definitions/ceph-perf-pull-requests.yml) -- `jenkins test crimson perf` [Jenkins Job](https://jenkins.ceph.com/view/all/job/ceph-perf-crimson/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-perf-pull-requests/config/definitions/ceph-perf-pull-requests.yml) -- `jenkins test signed` [Jenkins Job](https://jenkins.ceph.com/job/ceph-pr-commits/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-pr-commits/config/definitions/ceph-pr-commits.yml) -- `jenkins test make check` [Jenkins Job](https://jenkins.ceph.com/job/ceph-pull-requests/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-pull-requests/config/definitions/ceph-pull-requests.yml) -- `jenkins test make check arm64` [Jenkins Job](https://jenkins.ceph.com/job/ceph-pull-requests-arm64/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-pull-requests-arm64/config/definitions/ceph-pull-requests-arm64.yml) -- `jenkins test submodules` [Jenkins Job](https://jenkins.ceph.com/view/all/job/ceph-pr-submodules/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-pr-submodules/config/definitions/ceph-pr-commits.yml) -- `jenkins test dashboard` [Jenkins Job](https://jenkins.ceph.com/view/all/job/ceph-dashboard-pull-requests/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-dashboard-pull-requests/config/definitions/ceph-dashboard-pull-requests.yml) -- `jenkins test dashboard cephadm` [Jenkins Job](https://jenkins.ceph.com/view/all/job/ceph-dashboard-cephadm-e2e/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-dashboard-cephadm-e2e/config/definitions/ceph-dashboard-cephadm-e2e.yml) -- `jenkins test api` [Jenkins Job](https://jenkins.ceph.com/view/all/job/ceph-api/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-pr-api/config/definitions/ceph-pr-api.yml) -- `jenkins test docs` [ReadTheDocs](https://readthedocs.org/projects/ceph/) | [Github Workflow Definition](https://github.com/ceph/ceph/blob/main/.readthedocs.yml) -- `jenkins test ceph-volume all` [Jenkins Jobs](https://jenkins.ceph.com/view/ceph-volume%20PR/) | [Jenkins Jobs Definition](https://github.com/ceph/ceph-build/blob/main/ceph-volume-cephadm-prs/config/definitions/ceph-volume-pr.yml) -- `jenkins test windows` [Jenkins Job](https://jenkins.ceph.com/job/ceph-windows-pull-requests/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-windows-pull-requests/config/definitions/ceph-windows-pull-requests.yml) -- `jenkins test rook e2e` [Jenkins Job](https://jenkins.ceph.com/view/all/job/ceph-orchestrator-rook-e2e/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-rook-e2e/config/definitions/ceph-orchestrator-rook-e2e.yml) +## Merge -You must only issue one Jenkins command per-comment. Jenkins does not understand -comments with more than one command. -
+Land this via `just merge-backport PR=` — do not click the green merge button. +The just recipe constructs the merge commit's `Backport-Id` trailer. diff --git a/.github/workflows/author-ci-perms.yml b/.github/workflows/author-ci-perms.yml new file mode 100644 index 000000000000..0a6f92fd4e61 --- /dev/null +++ b/.github/workflows/author-ci-perms.yml @@ -0,0 +1,77 @@ +name: Check PR Author Permissions + +on: + pull_request_target: + types: [opened, synchronize, reopened] + +jobs: + check-permissions: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - name: Check permissions, label, and comment + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const pr = context.payload.pull_request; + const author = pr.user.login; + const issueNumber = pr.number; + const owner = context.repo.owner; + const repo = context.repo.repo; + + let permission = 'none'; + try { + const response = await github.rest.repos.getCollaboratorPermissionLevel({ + owner, + repo, + username: author, + }); + permission = response.data.permission; + } catch (error) { + if (pr.user.type === 'Bot' && error.status === 404) { + console.log(`Bot account ${author} not found as a direct collaborator, defaulting to 'none' permission.`); + } else { + console.log(`Failed to fetch permissions for ${author}: ${error.message}`); + } + } + if (permission === 'none') { + const currentLabels = pr.labels.map(label => label.name); + + // 1. Revoke approval on new pushes/updates by removing 'ci-approved' + if (currentLabels.includes('ci-approved')) { + try { + await github.rest.issues.removeLabel({ + owner, + repo, + issue_number: issueNumber, + name: 'ci-approved', + }); + } catch (error) { + console.log('Failed to remove ci-approved label:', error); + } + } + + // 2. Attach 'needs-ci-approval' label if not already present + if (!currentLabels.includes('needs-ci-approval')) { + await github.rest.issues.addLabels({ + owner, + repo, + issue_number: issueNumber, + labels: ['needs-ci-approval'], + }); + } + + // 3. Post notification comment on initial PR creation + if (context.payload.action === 'opened') { + const commentBody = `Thank you for your contribution. Since you are not yet a member of the [Ceph organization](https://github.com/ceph) with write permissions on ceph/ceph.git, our CI will not automatically run. Any member of the Ceph organization may label this PR \`ci-approved\` to allow Jenkins CI jobs to run.`; + + await github.rest.issues.createComment({ + owner, + repo, + issue_number: issueNumber, + body: commentBody, + }); + } + } diff --git a/.github/workflows/build-ceph-custom.yml b/.github/workflows/build-ceph-custom.yml new file mode 100644 index 000000000000..ca223fa873be --- /dev/null +++ b/.github/workflows/build-ceph-custom.yml @@ -0,0 +1,302 @@ +name: Build Ceph CobaltCore (Squid) + +on: + workflow_dispatch: + inputs: + cherry_pick_commits: + description: "Commit hashes to cherry-pick, separated by spaces" + required: false + type: string + merge_branches: + description: "Branches to merge, separated by spaces" + required: false + type: string + base_branch: + description: "CobaltCore branch to build" + required: true + default: "squid-cobaltcore" + type: string + push_image: + description: "Push the resulting image to GitHub Packages" + required: true + default: true + type: boolean + +concurrency: + group: ceph-cobaltcore-build-${{ inputs.base_branch }} + cancel-in-progress: false + +jobs: + build-ceph: + name: Build Ceph RPMs and image + runs-on: self-hosted + timeout-minutes: 720 + + permissions: + contents: read + packages: write + + defaults: + run: + shell: bash + + steps: + - name: Checkout CobaltCore Ceph + uses: actions/checkout@v4 + with: + repository: cobaltcore-dev/ceph + ref: ${{ inputs.base_branch }} + submodules: recursive + fetch-depth: 0 + + - name: Clean workspace + run: | + set -euo pipefail + + echo "Cleaning the source tree and submodules..." + git clean -fdx + git submodule foreach --recursive git clean -fdx + git submodule update --init --recursive + + - name: Configure upstream remote + run: | + set -euo pipefail + + git remote remove upstream 2>/dev/null || true + git remote add upstream https://github.com/ceph/ceph.git + git config remote.upstream.tagOpt --no-tags + + # Do not fetch all upstream history here. A full fetch can inspect + # historical submodule revisions that no longer exist remotely. + + - name: Apply requested branches and commits + if: ${{ inputs.merge_branches != '' || inputs.cherry_pick_commits != '' }} + env: + MERGE_BRANCHES: ${{ inputs.merge_branches }} + CHERRY_PICK_COMMITS: ${{ inputs.cherry_pick_commits }} + run: | + set -euo pipefail + + git config user.email "ci-bot@cobaltcore.dev" + git config user.name "CobaltCore CI" + + if [[ -n "${MERGE_BRANCHES}" ]]; then + read -r -a branches <<< "${MERGE_BRANCHES}" + + for branch in "${branches[@]}"; do + git check-ref-format --branch "${branch}" >/dev/null + echo "Merging branch: ${branch}" + + if git ls-remote --exit-code --heads origin "refs/heads/${branch}" >/dev/null 2>&1; then + git fetch \ + --no-tags \ + --recurse-submodules=no \ + origin \ + "+refs/heads/${branch}:refs/remotes/origin/${branch}" + git merge --no-edit "refs/remotes/origin/${branch}" + continue + fi + + if git ls-remote --exit-code --heads upstream "refs/heads/${branch}" >/dev/null 2>&1; then + git fetch \ + --no-tags \ + --recurse-submodules=no \ + upstream \ + "+refs/heads/${branch}:refs/remotes/upstream/${branch}" + git merge --no-edit "refs/remotes/upstream/${branch}" + continue + fi + + echo "Error: branch '${branch}' was not found in origin or upstream." + exit 1 + done + fi + + if [[ -n "${CHERRY_PICK_COMMITS}" ]]; then + read -r -a commits <<< "${CHERRY_PICK_COMMITS}" + + for commit in "${commits[@]}"; do + if [[ ! "${commit}" =~ ^[0-9a-fA-F]{7,40}$ ]]; then + echo "Error: '${commit}' is not a valid abbreviated or full Git commit hash." + exit 1 + fi + + echo "Cherry-picking commit: ${commit}" + + if ! git cat-file -e "${commit}^{commit}" 2>/dev/null; then + git fetch \ + --no-tags \ + --recurse-submodules=no \ + upstream \ + "${commit}" + fi + + git cherry-pick "${commit}" + done + fi + + - name: Calculate safe build parallelism + run: | + set -euo pipefail + + cpu_jobs=$(nproc) + host_available_kb=$(awk '/^MemAvailable:/ {print $2}' /proc/meminfo) + effective_available_bytes=$((host_available_kb * 1024)) + + if [[ -r /sys/fs/cgroup/memory.max ]]; then + cgroup_limit=$(cat /sys/fs/cgroup/memory.max) + cgroup_usage=$(cat /sys/fs/cgroup/memory.current) + + if [[ "${cgroup_limit}" =~ ^[0-9]+$ ]] \ + && (( ${#cgroup_limit} < 18 )) \ + && (( cgroup_limit > cgroup_usage )); then + cgroup_available=$((cgroup_limit - cgroup_usage)) + if (( cgroup_available < effective_available_bytes )); then + effective_available_bytes=${cgroup_available} + fi + fi + elif [[ -r /sys/fs/cgroup/memory/memory.limit_in_bytes ]]; then + cgroup_limit=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) + cgroup_usage=$(cat /sys/fs/cgroup/memory/memory.usage_in_bytes) + + if [[ "${cgroup_limit}" =~ ^[0-9]+$ ]] \ + && (( ${#cgroup_limit} < 18 )) \ + && (( cgroup_limit > cgroup_usage )); then + cgroup_available=$((cgroup_limit - cgroup_usage)) + if (( cgroup_available < effective_available_bytes )); then + effective_available_bytes=${cgroup_available} + fi + fi + fi + + # Keep 2 GiB for the runner and container runtime, then budget 3 GiB + # for every concurrent Ceph compilation job. + headroom_bytes=$((2 * 1024 * 1024 * 1024)) + bytes_per_job=$((3 * 1024 * 1024 * 1024)) + + if (( effective_available_bytes > headroom_bytes )); then + memory_jobs=$(((effective_available_bytes - headroom_bytes) / bytes_per_job)) + else + memory_jobs=1 + fi + + (( memory_jobs < 1 )) && memory_jobs=1 + + jobs=${cpu_jobs} + (( memory_jobs < jobs )) && jobs=${memory_jobs} + (( jobs < 1 )) && jobs=1 + + echo "CPU limit: ${cpu_jobs} jobs" + echo "Memory limit: ${memory_jobs} jobs" + echo "Selected build parallelism: ${jobs} jobs" + echo "BUILD_JOBS=${jobs}" >> "${GITHUB_ENV}" + + - name: Compile RPMs + run: | + set -euo pipefail + + ./src/script/build-with-container.py \ + --distro centos9 \ + --execute rpm \ + --image-variant packages \ + --extra=-e \ + --extra="NPROC=${BUILD_JOBS}" \ + --extra=-e \ + --extra="NINJAJOBS=${BUILD_JOBS}" + + - name: Collect runtime RPMs + run: | + set -euo pipefail + + rm -rf staging_rpms + mkdir -p staging_rpms + + find rpmbuild/RPMS -type f -name "*.rpm" \ + ! -name "*debuginfo*" \ + ! -name "*debugsource*" \ + ! -name "*devel*" \ + ! -name "*test*" \ + ! -name "*static*" \ + -exec cp --target-directory=staging_rpms {} + + + shopt -s nullglob + rpms=(staging_rpms/*.rpm) + if (( ${#rpms[@]} == 0 )); then + echo "Error: no runtime RPMs were produced." + exit 1 + fi + + echo "RPMs selected for the runtime image:" + ls -lh staging_rpms/ + + - name: Generate runtime Containerfile + run: | + set -euo pipefail + + cat > Containerfile.cobaltcore <<'EOF' + FROM quay.io/centos/centos:stream9 + + RUN dnf install -y dnf-plugins-core \ + https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm && \ + dnf config-manager --set-enabled crb && \ + dnf makecache + + COPY staging_rpms/*.rpm /tmp/rpms/ + + RUN dnf localinstall -y \ + --setopt=install_weak_deps=False \ + /tmp/rpms/*.rpm && \ + dnf clean all && \ + rm -rf /tmp/rpms + + RUN mkdir -p /var/run/ceph /var/lib/ceph /var/log/ceph && \ + chmod 0770 /var/run/ceph /var/lib/ceph /var/log/ceph + + ENTRYPOINT ["/usr/bin/ceph"] + EOF + + - name: Set image coordinates + env: + BASE_BRANCH: ${{ inputs.base_branch }} + run: | + set -euo pipefail + + repository=${GITHUB_REPOSITORY,,} + branch_tag=${BASE_BRANCH//\//-} + branch_tag=${branch_tag,,} + + echo "IMAGE_REPOSITORY=ghcr.io/${repository}" >> "${GITHUB_ENV}" + echo "IMAGE_TAG=${branch_tag}" >> "${GITHUB_ENV}" + + - name: Build runtime image + run: | + set -euo pipefail + + echo "Building ${IMAGE_REPOSITORY}:${IMAGE_TAG}" + podman build \ + --file Containerfile.cobaltcore \ + --tag "${IMAGE_REPOSITORY}:${IMAGE_TAG}" \ + . + + podman tag \ + "${IMAGE_REPOSITORY}:${IMAGE_TAG}" \ + "${IMAGE_REPOSITORY}:latest" + + - name: Push to GitHub Packages + if: ${{ inputs.push_image }} + env: + GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + + echo "${GHCR_TOKEN}" | podman login \ + --username "${GITHUB_ACTOR}" \ + --password-stdin \ + ghcr.io + + podman push "${IMAGE_REPOSITORY}:${IMAGE_TAG}" + podman push "${IMAGE_REPOSITORY}:latest" + + - name: Log out from GitHub Packages + if: ${{ always() && inputs.push_image }} + run: podman logout ghcr.io || true diff --git a/.github/workflows/check-license.yml b/.github/workflows/check-license.yml index 89dcfa292c3c..3b9a0cfefdbe 100644 --- a/.github/workflows/check-license.yml +++ b/.github/workflows/check-license.yml @@ -1,14 +1,28 @@ --- name: "Check for Incompatible Licenses" -on: [pull_request] +on: + pull_request_target: + branches: + - main + - umbrella + - tentacle + - squid + +permissions: + contents: read + pull-requests: read jobs: pull_request: name: "Check for Incompatible Licenses" runs-on: ubuntu-latest steps: - - name: Check Pull Request - uses: JJ/github-pr-contains-action@526dfe784d8604ea1c39b6c26609074de95b1ffd # releases/v14.1 - with: - github-token: ${{github.token}} - diffDoesNotContain: "GNU General Public License" + - name: Check PR Diff for License + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + DIFF=$(gh pr diff ${{ github.event.pull_request.number }} -R ${{ github.repository }}) + if echo "$DIFF" | grep -qi "GNU General Public License"; then + echo "Error: Incompatible license 'GNU General Public License' found in PR diff." + exit 1 + fi diff --git a/.github/workflows/create-backport-trackers.yml b/.github/workflows/create-backport-trackers.yml index 6ad026abbe6a..af94a9026fb6 100644 --- a/.github/workflows/create-backport-trackers.yml +++ b/.github/workflows/create-backport-trackers.yml @@ -38,7 +38,7 @@ jobs: # Backport checks need to be run ONLY on the main branch on ceph/ceph (not forks) if: github.ref == 'refs/heads/main' && github.repository == 'ceph/ceph' steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: sparse-checkout: | src/script/backport-create-issue diff --git a/.github/workflows/diff-ceph-config.yml b/.github/workflows/diff-ceph-config.yml index ce1c51ec408a..a0295939c409 100644 --- a/.github/workflows/diff-ceph-config.yml +++ b/.github/workflows/diff-ceph-config.yml @@ -1,4 +1,6 @@ -name: Check ceph config changes +--- + +name: Check Ceph config changes on: pull_request_target: types: @@ -6,56 +8,69 @@ on: - synchronize - edited - reopened - -# The following permissions are needed to write a comment to repo permissions: - issues: write - contents: read - pull-requests: write - + issues: write + contents: read + pull-requests: write jobs: pull_request: + env: + PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} + PR_NUMBER: ${{ github.event.pull_request.number }} + PR_COMMITS: ${{ github.event.pull_request.commits }} + BASE_REPO_URL: ${{ github.event.pull_request.base.repo.clone_url }} + BASE_REF: ${{ github.event.pull_request.base.ref }} + HEAD_REPO_URL: ${{ github.event.pull_request.head.repo.clone_url }} + if: github.repository == 'ceph/ceph' runs-on: ubuntu-latest steps: - - name: checkout ceph.git - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - name: Checkout main branch for pull_request_target + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: - ref: ${{ github.event.pull_request.head.sha }} + ref: 'refs/heads/main' path: ceph sparse-checkout: | src/script src/common/options .github/workflows - - name: 'Get common ancestor between PR and ceph upstream main branch' + - name: Get common ancestor between PR and Ceph upstream main branch id: get_common_ancestor - env: - branch_pr: origin/${{ github.event.pull_request.head.ref }} - refspec_pr: +${{ github.event.pull_request.head.sha }}:remotes/origin/${{ github.event.pull_request.head.ref }} working-directory: ceph + env: + BRANCH_PR: origin/${{ github.event.pull_request.head.ref }} run: | - # Fetch enough history to find a common ancestor commit (aka merge-base): - git fetch origin ${{ env.refspec_pr }} --depth=$(( ${{ github.event.pull_request.commits }} + 1 )) \ - --no-tags --prune --no-recurse-submodules - - # This should get the oldest commit in the local fetched history (the commit in ceph upstream from which PR branched from): - COMMON_ANCESTOR=$( git rev-list --first-parent --max-parents=0 --max-count=1 ${{ env.branch_pr }} ) - COMMON_ANCESTOR_SHA=$( git log --format=%H "${COMMON_ANCESTOR}" ) + set -euo pipefail + FETCH_DEPTH=$(( PR_COMMITS + 1 )) + REFSPEC="+${PR_HEAD_SHA}:remotes/origin/pr/${PR_NUMBER}/head" + + git fetch origin "$REFSPEC" \ + --depth="$FETCH_DEPTH" \ + --no-tags \ + --prune \ + --no-recurse-submodules + + COMMON_ANCESTOR_SHA=$(git rev-list \ + --first-parent \ + --max-parents=0 \ + --max-count=1 \ + "origin/pr/${PR_NUMBER}/head") - echo "COMMON_ANCESTOR_SHA=${COMMON_ANCESTOR_SHA}" >> $GITHUB_ENV + echo "COMMON_ANCESTOR_SHA=$COMMON_ANCESTOR_SHA" >> "$GITHUB_ENV" - name: Setup Python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 #v5.6.0 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: python-version: '3.13' - name: Install python packages + working-directory: ceph run: | pip3 install -r ./src/script/config-diff/requirements.txt - working-directory: ceph - - name: execute config diff tool + - name: Execute config diff tool id: diff_tool + working-directory: ceph env: REF_REPO: ${{ github.event.pull_request.base.repo.clone_url }} REF_BRANCH: ${{ github.event.pull_request.base.ref }} @@ -63,16 +78,25 @@ jobs: REMOTE_REPO: ${{ github.event.pull_request.head.repo.clone_url }} REMOTE_BRANCH: ${{ github.event.pull_request.head.ref }} REMOTE_COMMIT_SHA: ${{ github.event.pull_request.head.sha }} - run: | + run: | + set -euo pipefail + { echo 'DIFF_JSON<> "$GITHUB_OUTPUT" - working-directory: ceph - name: Post output as a comment - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea #v7.0.1 + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} DIFF_JSON_OUTPUT: ${{ steps.diff_tool.outputs.DIFF_JSON }} @@ -80,4 +104,4 @@ jobs: script: | const configDiff = process.env.DIFF_JSON_OUTPUT; const postComment = require('./ceph/.github/workflows/scripts/config-diff-post-comment.js'); - postComment({ github, context, core, configDiff }); \ No newline at end of file + postComment({ github, context, core, configDiff }); diff --git a/.github/workflows/pr-checklist.yml b/.github/workflows/pr-checklist.yml index dc3dbfb29245..325015622499 100644 --- a/.github/workflows/pr-checklist.yml +++ b/.github/workflows/pr-checklist.yml @@ -1,15 +1,22 @@ --- name: "Pull Request Checklist" on: - pull_request: + pull_request_target: + branches: + - main types: - edited - opened - reopened + +# https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#defining-access-for-the-github_token-scopes +permissions: + pull-requests: read + jobs: pr_checklist: runs-on: ubuntu-latest - name: Verify + name: Verify Checklist steps: - name: Sleep for 30 seconds run: sleep 30s diff --git a/.github/workflows/qa-symlink.yml b/.github/workflows/qa-symlink.yml index 39413514c901..cafc3c85eb97 100644 --- a/.github/workflows/qa-symlink.yml +++ b/.github/workflows/qa-symlink.yml @@ -2,30 +2,38 @@ name: "Check for missing .qa links" on: pull_request_target: + branches: + - main + - umbrella + - tentacle + - squid types: - opened - synchronize - - edited - reopened - +permissions: + contents: read jobs: - pull_request: + check-qa-links: name: "Check for missing .qa links" runs-on: ubuntu-latest if: github.repository == 'ceph/ceph' steps: - - name: Checkout main branch for pull_request_target - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Checkout verify-qa script from main branch + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: 'refs/heads/main' path: main + sparse-checkout: | + src/script/verify-qa + sparse-checkout-cone-mode: false - - name: checkout PR HEAD - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Checkout PR HEAD + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} path: pull_request - - name: verify .qa links - run: ../main/src/script/verify-qa - working-directory: pull_request/ + - name: Run verification script + run: | + ./main/src/script/verify-qa ./pull_request diff --git a/.github/workflows/redmine-upkeep.yml b/.github/workflows/redmine-upkeep.yml index db9bdf1802c8..1e81afbbd589 100644 --- a/.github/workflows/redmine-upkeep.yml +++ b/.github/workflows/redmine-upkeep.yml @@ -23,6 +23,9 @@ on: types: [closed] branches: - main + - squid + - tentacle + - umbrella # TODO enable/setup after upkeep has caught up # push: # tags: @@ -38,7 +41,7 @@ jobs: steps: - name: Checkout main branch for pull_request_target if: github.event_name == 'pull_request_target' - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: 'refs/heads/main' path: 'ceph' @@ -46,7 +49,7 @@ jobs: - name: Checkout default branch for other events if: github.event_name != 'pull_request_target' - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: 'ceph' fetch-depth: 0 diff --git a/.github/workflows/releng-audit.yaml b/.github/workflows/releng-audit.yaml new file mode 100644 index 000000000000..97c83980a290 --- /dev/null +++ b/.github/workflows/releng-audit.yaml @@ -0,0 +1,542 @@ +name: Backport Audit + +on: + pull_request_target: + types: [opened, synchronize, unlabeled, labeled, reopened] + branches: + - umbrella + - tentacle + - squid + issue_comment: + types: [created] + +# Group concurrency by PR/Issue number to serialize executions and prevent race conditions +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.issue.number }} + cancel-in-progress: false + +jobs: + audit: + name: Execution and Routing + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + issues: write + statuses: write + steps: + - id: router + name: Evaluate Workflow Routing + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + ORG_TOKEN: ${{ secrets.ORG_READ_PAT }} + with: + script: | + const eventName = context.eventName; + const payload = context.payload; + const actor = context.actor; + const isBot = actor === 'github-actions[bot]' || actor === 'github-actions'; + const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; + + // Safely removes a label and logs execution, ignoring 404s if label is not attached + async function removeLabelSafely(labelName) { + try { + core.info(`[Router] Attempting to remove label '${labelName}'...`); + await github.rest.issues.removeLabel({ + owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, name: labelName + }); + core.info(`[Router] Successfully removed label '${labelName}'.`); + } catch (e) { + if (e.status === 404) { + core.info(`[Router] Label '${labelName}' was not present on PR (404 ignored).`); + } else { + core.warning(`[Router] Failed to remove label '${labelName}': ${e.message}`); + } + } + } + + // Verifies if the user has maintainer/admin collaborator permissions or is an active + // member of the ceph-release-manager team. Required for /audit override and test-branch. + async function checkAuthorization(username) { + core.info(`[Router] Checking collaborator permission level for @${username}...`); + let authorized = false; + try { + const { data: permData } = await github.rest.repos.getCollaboratorPermissionLevel({ + owner: context.repo.owner, repo: context.repo.repo, username: username + }); + core.info(`[Router] Collaborator permission level for @${username}: ${permData.permission}`); + authorized = (permData.permission === 'admin' || permData.permission === 'maintain'); + } catch (e) { + core.info(`[Router] Failed to fetch repo permissions: ${e.message}`); + } + + if (!authorized && context.repo.owner === 'ceph' && process.env.ORG_TOKEN) { + core.info(`[Router] @${username} does not have maintain/admin repo rights. Checking ceph-release-manager team membership...`); + try { + const orgOctokit = github.getOctokit(process.env.ORG_TOKEN); + const { data: teamData } = await orgOctokit.rest.teams.getMembershipForUserInOrg({ + org: 'ceph', team_slug: 'ceph-release-manager', username: username + }); + core.info(`[Router] Org team membership state for @${username}: ${teamData.state}`); + authorized = (teamData.state === 'active'); + } catch (e) { + core.info(`[Router] Failed to fetch org team membership: ${e.message}`); + } + } + core.info(`[Router] Authorization result for @${username}: ${authorized ? 'AUTHORIZED' : 'NOT AUTHORIZED'}`); + return authorized; + } + + // Retrieves the HEAD SHA of the pull request. Falls back to an API lookup + // when triggered by issue_comment events where the PR object is omitted from payload. + async function getPrSha() { + let sha = context.payload.pull_request?.head?.sha; + if (!sha) { + core.info(`[Router] PR SHA not found in payload. Fetching from API for issue #${context.issue.number}...`); + try { + const { data: pr } = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number + }); + sha = pr.head.sha; + core.info(`[Router] Successfully retrieved SHA from API: ${sha}`); + } catch (e) { + core.error(`[Router] Failed to fetch PR details from API: ${e.message}`); + } + } else { + core.info(`[Router] Retrieved PR SHA from payload: ${sha}`); + } + if (sha) core.setOutput('pr_sha', sha); + return sha; + } + + // Pushes a pending commit status to the PR HEAD SHA to provide visual feedback + // and block branch protection while the audit executes. For standard audit runs, + // strips pass/fail state labels before starting. + async function triggerAuditRun(description, statusContext = 'Backport Audit') { + core.info(`[Router] Initiating audit run trigger for context '${statusContext}': ${description}`); + const isStandard = (statusContext === 'Backport Audit'); + if (isStandard) { + core.info('[Router] Clearing any previous labels before starting standard audit run...'); + await removeLabelSafely('releng-audit-fail'); + await removeLabelSafely('releng-audit-override'); + await removeLabelSafely('releng-audit-pass'); + await removeLabelSafely('releng-audit-queue'); + } + const sha = await getPrSha(); + if (!sha) { + core.error('[Router] Cannot initiate audit: PR SHA could not be retrieved.'); + core.setOutput('run_audit', 'false'); + return; + } + core.setOutput('status_context', statusContext); + + if (isStandard) { + try { + core.info(`[Router] Setting commit status to 'pending' on SHA ${sha}...`); + await github.rest.repos.createCommitStatus({ + owner: context.repo.owner, + repo: context.repo.repo, + sha: sha, + state: 'pending', + context: statusContext, + description: description, + target_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}` + }); + core.info(`[Router] Set pending commit status (${statusContext}) on SHA: ${sha}`); + } catch (e) { + core.error(`[Router] Failed to set commit status: ${e.message}`); + } + } else { + core.info(`[Router] Non-standard audit run ('${statusContext}') — skipping pending commit status creation.`); + } + core.setOutput('run_audit', 'true'); + } + + // Pushes an immediate success commit status when an authorized override occurs, + // unblocking required branch protection rules without executing the audit script. + async function setOverrideStatus(actorName) { + core.info(`[Router] Setting override success commit status for @${actorName}...`); + try { + const sha = await getPrSha(); + if (sha) { + await github.rest.repos.createCommitStatus({ + owner: context.repo.owner, + repo: context.repo.repo, + sha: sha, + state: 'success', + context: 'Backport Audit', + description: `Audit requirement overridden by @${actorName}`, + target_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}` + }); + core.info(`[Router] Set success (override) commit status on SHA: ${sha}`); + } else { + core.error('[Router] Cannot set override commit status: SHA is undefined or could not be retrieved.'); + } + } catch (e) { + core.error(`[Router] Failed to set override commit status: ${e.message}`); + } + } + + // Performs the complete override state transition atomically: applies the override label, + // strips pass/fail labels, updates commit status to success, and posts a confirmation comment. + async function executeOverride(actorName, addLabel = true, postComment = true) { + core.info(`[Router] Executing override lifecycle for @${actorName} (addLabel=${addLabel}, postComment=${postComment})...`); + if (addLabel) { + try { + core.info('[Router] Applying releng-audit-override label...'); + await github.rest.issues.addLabels({ + owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, labels: ['releng-audit-override'] + }); + core.info('[Router] Successfully added releng-audit-override label.'); + } catch (e) { + core.error(`[Router] Failed to add override label: ${e.message}`); + } + } + core.info('[Router] Stripping pass/fail labels as part of override execution...'); + await removeLabelSafely('releng-audit-fail'); + await removeLabelSafely('releng-audit-pass'); + await setOverrideStatus(actorName); + if (postComment) { + try { + core.info('[Router] Posting override confirmation comment...'); + await github.rest.issues.createComment({ + owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, + body: `✅ **Audit Override Applied** by @${actorName}.\n\n[View workflow run](${runUrl})` + }); + core.info('[Router] Successfully posted override confirmation comment.'); + } catch (e) { + core.error(`[Router] Failed to post override comment: ${e.message}`); + } + } + } + + core.info(`[Router] Evaluating event: ${eventName}, action: ${payload.action || 'N/A'}`); + + // ========================================== + // 1. HANDLE ISSUE COMMENTS (State Machine Drivers) + // ========================================== + // Issue comments (/audit commands) act strictly as state machine drivers. + // For standard commands (/audit retest, /audit override), we only apply labels + // here. This routes execution cleanly through the 'labeled' event handler, + // ensuring a single source of truth for audit triggers and override state changes. + if (eventName === 'issue_comment') { + if (!payload.issue.pull_request) { + core.info('[Router] Comment is not on a pull request. Skipping.'); + core.setOutput('run_audit', 'false'); + return; + } + + const commentBody = payload.comment.body.trim(); + + if (commentBody.startsWith('/audit retest')) { + // Directly trigger the audit run instead of bouncing through an ephemeral label + core.info('[Router] /audit retest detected. Triggering immediate audit execution...'); + try { + await github.rest.issues.createComment({ + owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, + body: `🔄 **Audit Retest Triggered** by @${actor}.\n\n[View workflow run](${runUrl})` + }); + } catch (e) { + core.error(`[Router] Failed to post retest comment: ${e.message}`); + } + await triggerAuditRun('Running backport audit...'); + } else if (commentBody.startsWith('/audit override')) { + // Execute the full override lifecycle atomically within this run + core.info(`[Router] /audit override detected. Validating @${actor}...`); + if (await checkAuthorization(actor)) { + core.info(`[Router] @${actor} is authorized. Executing override...`); + await executeOverride(actor, true, true); + } else { + core.error(`User @${actor} is not authorized to override audits.`); + } + core.setOutput('run_audit', 'false'); + } else if (commentBody.startsWith('/audit test-branch')) { + // Test branch mode: Execute PTL tool from an alternative branch for testing/debugging. + // To prevent side effects on PR mergeability, this mode does NOT touch state labels + // and will report a success commit status even if issues are found (findings are posted as PR comments). + core.info(`[Router] /audit test-branch detected. Validating @${actor}...`); + if (await checkAuthorization(actor)) { + const parts = commentBody.split(/\s+/); + const testBranch = parts[2] || 'testing/releng-audit'; + + try { + core.info(`[Router] Validating test branch '${testBranch}' exists...`); + await github.rest.repos.getBranch({ owner: context.repo.owner, repo: context.repo.repo, branch: testBranch }); + core.info(`[Router] Test branch '${testBranch}' verified.`); + } catch (e) { + core.error(`Test branch '${testBranch}' does not exist: ${e.message}`); + await github.rest.issues.createComment({ + owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, + body: `❌ **Audit Test Mode Failed**\n\nBranch \`${testBranch}\` was not found in \`${context.repo.owner}/${context.repo.repo}\`.\n\n[View workflow run](${runUrl})` + }); + core.setOutput('run_audit', 'false'); + return; + } + + try { + core.info('[Router] Posting test mode activation comment...'); + await github.rest.issues.createComment({ + owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, + body: `🧪 **Audit Test Mode Activated** by @${actor}.\n\nExecuting audit using tooling checked out from branch \`${testBranch}\`. *This run will not affect required PR commit statuses or state labels.*\n\n[View workflow run](${runUrl})` + }); + core.info('[Router] Successfully posted test mode activation comment.'); + } catch (e) { + core.error(`[Router] Failed to post test mode comment: ${e.message}`); + } + + core.setOutput('checkout_ref', testBranch); + await triggerAuditRun(`Running audit using branch ${testBranch}...`, `Audit Test Mode (${testBranch})`); + } else { + core.error(`User @${actor} is not authorized to invoke test branches.`); + core.setOutput('run_audit', 'false'); + } + } else { + core.info('[Router] Comment is not a recognized /audit command. Skipping.'); + core.setOutput('run_audit', 'false'); + } + + return; + } + + // ========================================== + // 2. HANDLE PR EVENTS & LABELS + // ========================================== + const hasFailLabel = payload.pull_request?.labels.some(l => l.name === 'releng-audit-fail'); + const hasPassLabel = payload.pull_request?.labels.some(l => l.name === 'releng-audit-pass'); + const hasOverrideLabel = payload.pull_request?.labels.some(l => l.name === 'releng-audit-override'); + const hasQueueLabel = payload.pull_request?.labels.some(l => l.name === 'releng-audit-queue'); + + core.info(`[Router] Current state labels -> Fail: ${hasFailLabel}, Pass: ${hasPassLabel}, Override: ${hasOverrideLabel}, Queue: ${hasQueueLabel}`); + core.setOutput('has_override', hasOverrideLabel ? 'true' : 'false'); + + // --- LABELED EVENTS --- + if (eventName === 'pull_request_target' && payload.action === 'labeled') { + const labelName = payload.label.name; + core.info(`[Router] Labeled event triggered for label '${labelName}' by @${actor}.`); + + // The releng-audit-queue label acts as the primary trigger for manual retests + if (labelName === 'releng-audit-queue') { + core.info('[Router] Queue label detected. Stripping label and triggering audit...'); + await removeLabelSafely('releng-audit-queue'); + await triggerAuditRun('Running backport audit...'); + return; + } + + // Handle authorized overrides applied via label or /audit override comment + if (labelName === 'releng-audit-override') { + core.info(`[Router] Evaluating override label application by @${actor}...`); + if (!isBot && !(await checkAuthorization(actor))) { + core.error(`[Router] User @${actor} is not authorized to apply releng-audit-override. Removing label...`); + await removeLabelSafely(labelName); + core.error(`User @${actor} is not authorized to override audits.`); + } else { + core.info(`[Router] Override authorized for @${actor}. Executing override state transition...`); + // Execute override state transition without re-adding label (addLabel = false). + // Only post a confirmation comment if applied by a human user in the UI (!isBot). + await executeOverride(actor, false, !isBot); + } + core.setOutput('run_audit', 'false'); + return; + } + + // Prevent unauthorized users from manually spoofing machine-owned state labels + if (!isBot && (labelName === 'releng-audit-pass' || labelName === 'releng-audit-fail')) { + core.warning(`[Router] User @${actor} cannot manually apply machine-owned label '${labelName}'. Removing...`); + await removeLabelSafely(labelName); + if (!hasOverrideLabel) { + core.info('[Router] No override active. Triggering fresh audit run...'); + await triggerAuditRun('Running backport audit...'); + } else { + core.info('[Router] Override is active. Skipping fresh audit run.'); + } + return; + } + + core.info(`[Router] Labeled event for '${labelName}' requires no action. Skipping.`); + core.setOutput('run_audit', 'false'); + return; + } + + // --- SYNCHRONIZE (New Commits) --- + // When new commits are pushed, existing overrides are revoked and audits re-evaluate. + // If the PR is already failed, execution halts to avoid comment spam until re-requested. + if (eventName === 'pull_request_target' && payload.action === 'synchronize') { + core.info('[Router] Processing synchronize event (new commits pushed)...'); + if (hasOverrideLabel) { + core.info('[Router] PR had active override label. Revoking override due to new commits...'); + await removeLabelSafely('releng-audit-override'); + core.setOutput('has_override', 'false'); + try { + core.info('[Router] Posting override removal notification comment...'); + await github.rest.issues.createComment({ + owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, + body: `⚠️ **Audit Override Removed**\n\nNew commits were pushed to this PR, so the previous override has been removed.\n\n[View workflow run](${runUrl})` + }); + core.info('[Router] Override removal notification posted.'); + } catch (e) { + core.error(`[Router] Failed to post override removal comment: ${e.message}`); + } + } + + if (hasFailLabel) { + core.warning("[Router] PR is currently in a failed audit state. Halting automated execution on synchronize."); + core.info("PR is currently in a failed audit state. Remove the releng-audit-fail label or comment /audit retest to re-run."); + const sha = await getPrSha(); + if (sha) { + core.info(`[Router] Setting commit status to 'failure' on new SHA ${sha}...`); + await github.rest.repos.createCommitStatus({ + owner: context.repo.owner, + repo: context.repo.repo, + sha: sha, + state: 'failure', + context: 'Backport Audit', + description: 'PR is in a failed audit state. Remove releng-audit-fail label or comment /audit retest to re-run.', + target_url: runUrl + }); + } + core.setOutput('run_audit', 'false'); + return; + } + + await triggerAuditRun('Running backport audit...'); + return; + } + + // --- UNLABELED --- + // If a user manually strips a status label, trigger a fresh audit evaluation + if (eventName === 'pull_request_target' && payload.action === 'unlabeled') { + const removed = payload.label.name; + core.info(`[Router] Processing unlabeled event: label '${removed}' was removed by @${actor}.`); + if (['releng-audit-fail', 'releng-audit-pass', 'releng-audit-override'].includes(removed) && !isBot) { + if (hasOverrideLabel && removed === 'releng-audit-fail') { + core.info('[Router] PR has active override label; ignoring manual removal of releng-audit-fail.'); + core.setOutput('run_audit', 'false'); + return; + } + core.info(`[Router] Status label '${removed}' removed by human. Triggering fresh audit evaluation...`); + await triggerAuditRun('Running backport audit...'); + return; + } else { + core.info(`[Router] Unlabeled event for '${removed}' requires no action.`); + } + } + + // --- OPENED / REOPENED --- + if (eventName === 'pull_request_target' && (payload.action === 'opened' || payload.action === 'reopened')) { + core.info(`[Router] Processing PR ${payload.action} event...`); + if (payload.action === 'reopened' && hasOverrideLabel) { + core.info('[Router] PR reopened with previous override label. Removing stale override...'); + await removeLabelSafely('releng-audit-override'); + core.setOutput('has_override', 'false'); + } + await triggerAuditRun('Running backport audit...'); + return; + } + + core.info('[Router] Event did not match any active execution triggers. Skipping audit.'); + core.setOutput('run_audit', 'false'); + + - name: Checkout Trusted Base Repository + if: steps.router.outputs.run_audit == 'true' + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + ref: ${{ steps.router.outputs.checkout_ref || '' }} + + - name: Fetch main for parity check + if: steps.router.outputs.run_audit == 'true' + # checkout only fetches the PR's base branch (e.g. squid/tentacle/umbrella). + # The parity check needs the main ref to walk the commit history graph and find the upstream + # merge commit for each cherry-pick, so fetch it explicitly as origin/main. + run: git fetch --no-tags origin +refs/heads/main:refs/remotes/origin/main + + - name: Setup Python + if: steps.router.outputs.run_audit == 'true' + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + with: + python-version: '3.13' + + - name: Install Dependencies + if: steps.router.outputs.run_audit == 'true' + run: pip install GitPython python-redmine requests + + - id: ptl_audit + name: Run PTL Audit + if: steps.router.outputs.run_audit == 'true' + env: + PTL_TOOL_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PTL_TOOL_REDMINE_API_KEY: ${{ secrets.REDMINE_API_KEY_BACKPORT_BOT }} + PTL_TOOL_BASE_PROJECT: ${{ github.repository_owner }} + PTL_TOOL_BASE_REPO: ${{ github.event.repository.name }} + PTL_TOOL_PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }} + run: | + python src/script/ptl-tool.py --debug --ci-mode --audit + + - name: Report Audit Status & Update State Labels + if: always() && steps.router.outputs.run_audit == 'true' && steps.router.outputs.pr_sha != '' + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const statusContext = '${{ steps.router.outputs.status_context }}' || 'Backport Audit'; + if (statusContext !== 'Backport Audit') { + core.info(`[Reporter] Non-standard audit run ('${statusContext}') — skipping state labels and commit status reporting.`); + return; + } + + const outcome = '${{ steps.ptl_audit.outcome }}'; + const eventName = context.eventName; + core.info(`[Reporter] Evaluating final audit outcome: '${outcome}' for standard audit run (event: ${eventName})...`); + + let state = 'failure'; + let description = 'Backport audit failed. See review comments or workflow logs.'; + + if (outcome === 'success') { + state = 'success'; + description = 'Backport audit completed successfully.'; + core.info('[Reporter] Audit completed successfully. Applying releng-audit-pass label...'); + try { + await github.rest.issues.addLabels({ + owner: context.repo.owner, repo: context.repo.repo, + issue_number: context.issue.number || context.payload.pull_request.number, + labels: ['releng-audit-pass'] + }); + core.info('[Reporter] Successfully applied releng-audit-pass label.'); + } catch (e) { + core.error(`[Reporter] Failed to add pass label: ${e.message}`); + } + } else if (outcome === 'cancelled') { + state = 'error'; + description = 'Backport audit execution was cancelled.'; + core.warning('[Reporter] Audit execution was cancelled.'); + } else { + // outcome === 'failure' + core.info('[Reporter] Audit detected failures. Applying releng-audit-fail label...'); + try { + await github.rest.issues.addLabels({ + owner: context.repo.owner, repo: context.repo.repo, + issue_number: context.issue.number || context.payload.pull_request.number, + labels: ['releng-audit-fail'] + }); + core.info('[Reporter] Successfully applied releng-audit-fail label.'); + } catch (e) { + core.error(`[Reporter] Failed to add fail label: ${e.message}`); + } + } + + try { + core.info(`[Reporter] Creating final commit status '${state}' for context '${statusContext}' on SHA '${{ steps.router.outputs.pr_sha }}'...`); + await github.rest.repos.createCommitStatus({ + owner: context.repo.owner, + repo: context.repo.repo, + sha: '${{ steps.router.outputs.pr_sha }}', + state: state, + context: statusContext, + description: description, + target_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}` + }); + core.info(`[Reporter] Set ${state} commit status (${statusContext}) on SHA: ${{ steps.router.outputs.pr_sha }}`); + } catch (e) { + core.error(`[Reporter] Failed to set final commit status: ${e.message}`); + } diff --git a/.githubmap b/.githubmap index 81522db7ea78..52c4462d171b 100644 --- a/.githubmap +++ b/.githubmap @@ -8,6 +8,8 @@ # # a2batic Kanika Murarka +aainscow Alex Ainscow +aaryanporwal Aaryan Porwal aaSharma14 Aashish Sharma abhidesai6 Abhishek Desai abhishek-kane Abhishek Kane @@ -22,24 +24,36 @@ alimaredia Ali Maredia amathuria Aishwarya Mathuria amitkumar50 Amit Kumar andrewschoen Andrew Schoen +anoopcs9 Anoop C S +anthonyeleven Anthony D'Atri anuradhagadge Anuradha Gadge -aaryanporwal Aaryan Porwal +AnuragRaut08 Anurag Raut +arbtfnf anuragbandhu asettle Alexandra Settle +ashjosh1git Ashwin M Joshi athanatos Samuel Just avanthakkar Avan Thakkar -b-ranto Boris Ranto badone Brad Hubbard +baergj Joshua Baergen baruza Barbora Ančincová bassamtabbara Bassam Tabbara batrick Patrick Donnelly +baum Alexander Indenbaum +BBoozmen Oguzhan Ozmen +benhanokh Gabriel Benhanokh bigjust Justin Caratzas +bill-scales Bill Scales bk201 Kiefer Chang BlaineEXE Blaine Gardner +bluikko Ville Ojamo branch-predictor Piotr Dałek +b-ranto Boris Ranto bryanmontalvan Bryan Montalvan callithea Laura Paduano capri1989 Kai Wagner +caroav Aviv Caro cbodley Casey Bodley +cfsnyder Cory Snyder chardan Jesse Williamson chhabaramesh Ramesh Chander chrisphoffman Christopher Hoffman @@ -47,20 +61,24 @@ cloudbehl Ankush Behl CourtneyCCaldwell Courtney Caldwell Daniel-Pivonka Daniel Pivonka ddiss David Disseldorp -devikab25 Devika Babrekar +devikab25 Devika Babrekar Devp00l Stephan Müller dillaman Jason Dillaman djgalloway David Galloway dmick Dan Mick dnyanee1997 Dnyaneshwari talwekar +dparmar18 Dhairya Parmar dragonylffly Li Wang dsavineau Dimitri Savineau +dubeyko Viacheslav Dubeyko dvanders Dan van der Ster dzafman David Zafman +edwinzrodriguez Edwin Rodriguez emmericp Paul Emmerich epuertat Ernesto Puerta ErwanAliasr1 Erwan Velu Exotelis Sebastian Krah +ffilz Frank S. Filz fullerdj Douglas Fuller GabrielBrascher Gabriel Brascher galsalomon66 Gal Salomon @@ -73,20 +91,27 @@ idryomov Ilya Dryomov ifed01 Igor Fedotov ivancich J. Eric Ivancich jan--f Jan Fajerski +Jayaprakash-ibm Jaya Prakash Madaka jcsp John Spray jdurgin Josh Durgin jecluis João Eduardo Luís jmolmo Juan Miguel Olmo +jmundack Joseph Mundackal joscollin Jos Collin josephsawaya Joseph Sawaya jschmid1 Joshua Schmid jtlayton Jeff Layton kalaspuffar Daniel Persson +kamoltat Kamoltat Sirivadhna +karthik-us1 Karthik U S +kchheda3 Krunal Chheda knrt10 Kautilya Tripathi kotreshhr Kotresh Hiremath Ravishankar kshtsk Kyr Shatskyy ktdreyer Ken Dreyer +Kushal-deb Kushal Deb LenzGr Lenz Grimmer +leonid-s-usov Leonid Usov leseb Sébastien Han liewegas Sage Weil liupan1111 Pan Liu @@ -97,27 +122,36 @@ markhpc Mark Nelson Matan-B Matan Breizman mattbenjamin Matt Benjamin mchangir Milind Changire +mctaggatart Sage McTaggart melissa-kun-li Melissa Li mgfritch Michael Fritch +mheler Matthew Heler mikechristie Mike Christie +mkogan1 Mark Kogan +mmgaggle Kyle Bader mogeb Mohamad Gebai MrFreezeex Arthur Outhenin-Chalandre myoungwon Myoungwon Oh -nmunet Naman Munet Naveenaidu Naveen Naidu +neesingh-rh Neeraj Pratap Singh neha-ojha Neha Ojha NitzanMordhai Nitzan Mordechai nizamial09 Nizamudeen A nmshelke Nikhilkumar Shelke -nSedrickm Ngwa Sedrick Meh +nmunet Naman Munet noahdesu Noah Watkins +nSedrickm Ngwa Sedrick Meh oritwas Orit Wasserman -p-na Patrick Nawracay -p-se Patrick Seidensal +parth-gr Parth Arora pcuzner Paul Cuzner Pegonzal Pedro Gonzalez Gomez pereman2 Pere Diaz Bou +perezjosibm Jose J Palacios-Perez +petrutlucian94 Lucian Petrut +phlogistonjohn John Mulligan +p-na Patrick Nawracay prgoel-code Prachi prgoel@redhat.com +p-se Patrick Seidensal pujaoshahu Puja Shahu rchagam Anjaneya Chagam renhwztetecs huanwen ren @@ -125,25 +159,33 @@ ricardoasmarques Ricardo Marques rishabh-d-dave Rishabh Dave rjfd Ricardo Dias rkachach Redouane Kachach +robbat2 Robin H. Johnson ronen-fr Ronen Friedman runsisi luo runbing rzarzynski Radoslaw Zarzynski s0nea Tatjana Dehler +sagargopale2233 Sagar Gopale +salieri11 Igor Golikov Sarthak0702 Sarthak Gupta saschagrunert Sascha Grunert sebastian-philipp Sebastian Wagner shraddhaag Shraddha Agrawal -Kushal-deb Kushal Deb ShwetaBhosale1 Shweta Bhosale +Shwetha-Acharya Shwetha Acharya ShyamsundarR Shyamsundar R sidharthanup Sidharth Anupkrishnan +smanjara Shilpa Jagannath smithfarm Nathan Cutler +spuiuk Sachin Prabhu sunilangadi2 Sunil Angadi sunnyku Sunny Kumar +synarete Shachar Sharon szuraski898 Steven Zuraski taodd dongdong tao tchaikov Kefu Chai theanalyst Abhishek Lekshmanan +Thingee Mike Perez +ThomasLamprecht Thomas Lamprecht toabctl Thomas Bechtold travisn Travis Nielsen trociny Mykola Golub @@ -163,12 +205,13 @@ vumrao Vikhyat Umrao Waadkh7 Waad Alkhoury wido Wido den Hollander wjwithagen Willem Jan Withagen +xhernandez Xavi Hernandez xiaoxichen Xiaoxi Chen xiexingguo xie xingguo xxhdx1985126 Xuehan Xu yaarith Yaarit Hatuka -Yan-waller yanjun yangdongsheng Dongsheng Yang +Yan-waller yanjun yehudasa Yehuda Sadeh yunfeiguan Yunfei Guan yuriw Yuri Weinstein @@ -176,30 +219,3 @@ yuvalif Yuval Lifshitz yuyuyu101 Haomai Wang zdover23 Zac Dover zmc Zack Cerza -Thingee Mike Perez -cfsnyder Cory Snyder -benhanokh Gabriel Benhanokh -kamoltat Kamoltat Sirivadhna -anthonyeleven Anthony D Atri -petrutlucian94 Lucian Petrut -dparmar18 Dhairya Parmar -nmshelke Nikhilkumar Shelke -neesingh-rh Neeraj Pratap Singh -parth-gr Parth Arora -phlogistonjohn John Mulligan -baergj Joshua Baergen -zmc Zack Cerza -robbat2 Robin H. Johnson -leonid-s-usov Leonid Usov -ffilz Frank S. Filz -Jayaprakash-ibm Jaya Prakash Madaka -spuiuk Sachin Prabhu -anoopcs9 Anoop C S -dubeyko Viacheslav Dubeyko -bill-scales Bill Scales -kchheda3 Krunal Chheda -Shwetha-Acharya Shwetha Acharya -xhernandez Xavi Hernandez -ThomasLamprecht Thomas Lamprecht -jmundack Joseph Mundackal -edwinzrodriguez Edwin Rodriguez diff --git a/.gitmodules b/.gitmodules index 58bd31d06bfd..b0473d24fff7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -85,3 +85,6 @@ [submodule "src/lss"] path = src/lss url = https://chromium.googlesource.com/linux-syscall-support +[submodule "src/librdkafka"] + path = src/librdkafka + url = https://github.com/confluentinc/librdkafka.git diff --git a/.mailmap b/.mailmap index 16b030937137..43a984b8e6f5 100644 --- a/.mailmap +++ b/.mailmap @@ -68,12 +68,14 @@ Anton Oks Anton Turetckii banuchka Anuradha Gadge Anurag Bandhu +Anurag Raut Aravind Ramesh Aravind Aristoteles Neto Aron Gunn Arthur Outhenin-Chalandre MrFreezeex Ashish Chandra Ashita Kasam <694240887@qq.com> +Ashwin M Joshi Avan Thakkar Avan Thakkar Avan Avan Avan Thakkar avanthakkar @@ -389,6 +391,7 @@ Kamoltat Sirivadhna Kamoltat Kanika Murarka Kapil Sharma Karol Mroz +Karthik U S Kautilya Tripathi Kefu Chai Kefu Chai @@ -621,6 +624,7 @@ Ruifeng Yang Ruifeng Yang <149233652@qq.com> Rust Shen Rémi Buisson +Sagar Gopale Sage Weil Sage Weil Sage Weil @@ -776,7 +780,7 @@ Vasu Kulkarni Vasu Kulkarni Vasu Kulkarni Victor Araujo -Ville Ojamo <14869000+bluikko@users.noreply.github.com> bluikko <14869000+bluikko@users.noreply.github.com> +Ville Ojamo <14869000+bluikko@users.noreply.github.com> Volker Assmann Volker Assmann Waad Alkhoury Waad AlKhoury @@ -839,8 +843,7 @@ Xin Yuan Xin Yuan Xingyi Wu Xinxin Shu -Xinying Song -Xinying Song +Xinying Song Xinyu Wang wangxinyu Xinze Chi Xinze Chi diff --git a/.organizationmap b/.organizationmap index 0e301a56d617..79a0804bde2b 100644 --- a/.organizationmap +++ b/.organizationmap @@ -160,6 +160,7 @@ Cloudwatt Sahid Orentino Ferdjaoui Mark Nelson Clyso GmbH Mykola Golub Clyso GmbH Dan van der Ster +Clyso GmbH Zac Dover CohortFS, LLC Matt Benjamin Commerce Guys Nikola Kotur Corvisa LLC Walter Huf @@ -352,11 +353,13 @@ IBM Afreen Misbah IBM Aliaksei Makarau IBM Andrew Solomon IBM Anuradha Gadge +IBM Anurag Raut IBM Devika Babrekar IBM Dnyaneshwari talwekar IBM Guillaume Abrioux IBM Jonas Pfefferle IBM Kautilya Tripathi +IBM Karthik U S IBM Laura Flores IBM Martin Ohmacht IBM Michel Normand @@ -367,6 +370,7 @@ IBM Or Ozeri IBM Paul Cuzner IBM Prachi Goel IBM Puja Shahu +IBM Sagar Gopale IBM Samuel Matzek IBM Shraddha Agrawal IBM Kushal Deb @@ -376,6 +380,7 @@ IBM Steven Zuraski IBM Sunil Angadi IBM Teoman Onay IBM Ulrich Weigand +IBM Ashwin M Joshi ICT Zhang Huan ICT Zhenyu Leng IDECO Коренберг Марк diff --git a/CMakeLists.txt b/CMakeLists.txt index b7c7bbdf4f7a..8cddac58c519 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,14 @@ cmake_minimum_required(VERSION 3.22.1) project(ceph - VERSION 20.0.0 + VERSION 21.0.0 LANGUAGES CXX C ASM) -foreach(policy CMP0127 CMP0135 CMP0175) +foreach(policy CMP0127 CMP0135 + CMP0144 # Ensure taking `BOOST_ROOT` keeps working. Otherwise, + # config-based `find_package` will take `Boost_ROOT`. + CMP0167 # Use Boost's own CMake config files instead of FindBoost module. + CMP0175) if(POLICY ${policy}) cmake_policy(SET ${policy} NEW) endif() @@ -71,6 +75,20 @@ if(MINGW) link_directories(${MINGW_LINK_DIRECTORIES}) endif() +option(WITH_MOLD "Use the Mold linker" OFF) +if(WITH_MOLD) + find_program(_mold_path mold REQUIRED) + message(STATUS "Mold linker: ${_mold_path}") + set(CMAKE_LINKER ${_mold_path} CACHE FILEPATH "Linker" FORCE) + set(MOLD_FUSE_LD_FLAG "-fuse-ld=mold" CACHE INTERNAL "") + foreach(_flags CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS) + if(NOT "${${_flags}}" MATCHES "fuse-ld=") + string(APPEND ${_flags} " ${MOLD_FUSE_LD_FLAG}") + endif() + endforeach() + set(USING_MOLD_LINKER TRUE CACHE INTERNAL "") +endif() + option(WITH_CCACHE "Build with ccache.") if(WITH_CCACHE) if(CMAKE_C_COMPILER_LAUNCHER OR CMAKE_CXX_COMPILER_LAUNCHER) @@ -99,13 +117,13 @@ if(WITH_SCCACHE) ERROR_VARIABLE sccache_dist_status_error GET "${sccache_dist_status}" SchedulerStatus 1 num_cpus ) - string(FIND "${sccache_dist_status}" "disabled" find_result) - if(find_result EQUAL -1) + if(sccache_dist_status_error) + message(WARNING "Using sccache, but it is not configured for distributed " + "compilation: ${sccache_dist_status_error}") + else() message(STATUS "Using sccache with distributed compilation. Effective cores: ${sccache_cores}") set(NINJA_MAX_COMPILE_JOBS ${sccache_cores}) set(NINJA_MAX_LINK_JOBS ${sccache_cores}) - else() - message(WARNING "Using sccache, but it is not configured for distributed complilation") endif() else() message(WARNING "Using sccache, but cannot determine maximum job value since cmake version is <3.19") @@ -205,7 +223,6 @@ if(LINUX) elseif(FREEBSD) set(HAVE_UDEV OFF) set(HAVE_LIBAIO OFF) - set(HAVE_LIBDML OFF) set(HAVE_BLKID OFF) set(HAVE_KEYUTILS OFF) else() @@ -241,12 +258,18 @@ endif() option(WITH_BLUESTORE "Bluestore OSD backend" ON) if(WITH_BLUESTORE) + if(FREEBSD) + # POSIX AIO is integrated into FreeBSD kernel, and exposed by libc. + set(HAVE_POSIXAIO ON) + endif() +endif() + +option(WITH_CRIMSON "Build Crimson components" OFF) + +if(WITH_BLUESTORE OR WITH_CRIMSON) if(LINUX) find_package(aio) set(HAVE_LIBAIO ${AIO_FOUND}) - elseif(FREEBSD) - # POSIX AIO is integrated into FreeBSD kernel, and exposed by libc. - set(HAVE_POSIXAIO ON) endif() endif() @@ -264,12 +287,12 @@ endif() include(CMakeDependentOption) -CMAKE_DEPENDENT_OPTION(WITH_LIBURING "Enable io_uring bluestore backend" ON - "WITH_BLUESTORE;HAVE_LIBAIO" OFF) +CMAKE_DEPENDENT_OPTION(WITH_LIBURING "Enable io_uring for bluestore backend or crimson" ON + "HAVE_LIBAIO" OFF) set(HAVE_LIBURING ${WITH_LIBURING}) CMAKE_DEPENDENT_OPTION(WITH_SYSTEM_LIBURING "Require and build with system liburing" OFF - "HAVE_LIBAIO;WITH_BLUESTORE" OFF) + "HAVE_LIBAIO" OFF) if(WITH_LIBURING) if(WITH_SYSTEM_LIBURING) @@ -278,18 +301,6 @@ if(WITH_LIBURING) include(Builduring) build_uring() endif() - # enable uring in boost::asio - - if(CMAKE_SYSTEM_VERSION VERSION_GREATER_EQUAL "5.10") - add_compile_definitions("BOOST_ASIO_HAS_IO_URING") - endif() -endif() - -CMAKE_DEPENDENT_OPTION(WITH_BLUESTORE_PMEM "Enable PMDK libraries" OFF - "WITH_BLUESTORE" OFF) -if(WITH_BLUESTORE_PMEM) - find_package(dml) - set(HAVE_LIBDML ${DML_FOUND}) endif() CMAKE_DEPENDENT_OPTION(WITH_RBD_MIRROR "Enable build for rbd-mirror daemon executable" OFF @@ -306,7 +317,7 @@ CMAKE_DEPENDENT_OPTION(WITH_RBD_SSD_CACHE "Enable librbd persistent write back c "WITH_RBD" OFF) CMAKE_DEPENDENT_OPTION(WITH_SYSTEM_PMDK "Require and build with system PMDK" OFF - "WITH_RBD_RWL OR WITH_BLUESTORE_PMEM" OFF) + "WITH_RBD_RWL" OFF) CMAKE_DEPENDENT_OPTION(WITH_RBD_UBBD "Enable ubbd support for rbd device utility" OFF "WITH_RBD" OFF) @@ -316,26 +327,27 @@ if(WITH_RBD_UBBD) build_ubbd() endif() -if(WITH_BLUESTORE_PMEM) - set(HAVE_BLUESTORE_PMEM ON) -endif() - CMAKE_DEPENDENT_OPTION(WITH_SPDK "Enable SPDK" OFF - "CMAKE_SYSTEM_PROCESSOR MATCHES i386|i686|amd64|x86_64|AMD64|aarch64" OFF) + "CMAKE_SYSTEM_PROCESSOR MATCHES i386|i686|amd64|x86_64|AMD64|aarch64|riscv64" OFF) +option(WITH_SYSTEM_SPDK "Require a system SPDK instead of building bundled src/spdk" OFF) if(WITH_SPDK) if(NOT WITH_BLUESTORE) message(SEND_ERROR "Please enable WITH_BLUESTORE for using SPDK") endif() - include(BuildSPDK) - build_spdk() + if(WITH_SYSTEM_SPDK) + find_package(spdk REQUIRED) + else() + include(BuildSPDK) + build_spdk() + endif() set(HAVE_SPDK TRUE) endif(WITH_SPDK) if(WITH_BLUESTORE) - if(NOT AIO_FOUND AND NOT HAVE_POSIXAIO AND NOT WITH_SPDK AND NOT WITH_BLUESTORE_PMEM) + if(NOT AIO_FOUND AND NOT HAVE_POSIXAIO AND NOT WITH_SPDK) message(SEND_ERROR "WITH_BLUESTORE is ON, " "but none of the bluestore backends is enabled. " - "Please install libaio, or enable WITH_SPDK or WITH_BLUESTORE_PMEM (experimental)") + "Please install libaio, or enable WITH_SPDK") endif() endif() @@ -450,6 +462,10 @@ if(ALLOCATOR) elseif(NOT ALLOCATOR STREQUAL "libc") message(FATAL_ERROR "Unsupported allocator selected: ${ALLOCATOR}") endif() +elseif(WITH_ASAN) + # Force libc: tcmalloc/jemalloc still export operator new/delete even when the + # sanitizer shadows malloc, so sanitizer-allocated memory is freed via tcmalloc and SIGSEGVs. + set(ALLOCATOR "libc") else(ALLOCATOR) find_package(gperftools 2.6.2) set(HAVE_LIBTCMALLOC ${gperftools_FOUND}) @@ -535,16 +551,20 @@ if(WITH_CATCH2) # Restore the original CPM settings in case someone else wants to use the module: set(CPM_USE_LOCAL_PACKAGES_ONLY, ${ORIG_CPM_USE_LOCAL_PACKAGES_ONLY}) - message("-- Enabled Catch2 support") -endif() - -if(WIN32) - set(WITH_BREAKPAD_DEFAULT OFF) -else() - set(WITH_BREAKPAD_DEFAULT ON) + # CPM skips the fetch silently if downloads are disabled, + # e.g. with FETCHCONTENT_FULLY_DISCONNECTED=ON on deb builds + if(NOT TARGET Catch2::Catch2WithMain) + message(WARNING "Catch2 unavailable, disabling Catch2 tests") + set(WITH_CATCH2 OFF) + else() + message("-- Enabled Catch2 support") + endif() endif() -option(WITH_BREAKPAD "Build with Google Breakpad crash reporter" ${WITH_BREAKPAD_DEFAULT}) +# enable breakpad unless win32 or power +# ppc64le port tracked in https://issues.chromium.org/issues/41479970 +CMAKE_DEPENDENT_OPTION(WITH_BREAKPAD "Build with Google Breakpad crash reporter" ON + "NOT (WIN32 OR CMAKE_SYSTEM_PROCESSOR MATCHES ppc64le)" OFF) if(WITH_BREAKPAD) set(HAVE_BREAKPAD ON) message("-- Enabled Google Breakpad crash reporter") @@ -555,12 +575,15 @@ option(WITH_RADOSGW "RADOS Gateway is enabled" ON) option(WITH_RADOSGW_BEAST_OPENSSL "RADOS Gateway's Beast frontend uses OpenSSL" ON) option(WITH_RADOSGW_AMQP_ENDPOINT "RADOS Gateway's pubsub support for AMQP push endpoint" ON) option(WITH_RADOSGW_KAFKA_ENDPOINT "RADOS Gateway's pubsub support for Kafka push endpoint" ON) +option(WITH_SYSTEM_RDKAFKA "build against system librdkafka instead of the bundled submodule" OFF) option(WITH_RADOSGW_LUA_PACKAGES "RADOS Gateway's support for dynamically adding lua packagess" ON) +option(WITH_RADOSGW_FDB "FoundationDB support for RADOS Gateway (experimental)" OFF) option(WITH_RADOSGW_DBSTORE "DBStore backend for RADOS Gateway" ON) option(WITH_RADOSGW_MOTR "CORTX-Motr backend for RADOS Gateway" OFF) option(WITH_RADOSGW_DAOS "DAOS backend for RADOS Gateway" OFF) option(WITH_RADOSGW_D4N "D4N wrapper for RADOS Gateway" ON) -cmake_dependent_option(WITH_RADOSGW_POSIX "POSIX backend for RADOS Gateway" ON WITH_RADOSGW_DBSTORE OFF) # posix depends on dbstore +option(WITH_RADOSGW_POSIX "POSIX backend for RADOS Gateway" ON) +cmake_dependent_option(WITH_RADOSGW_STANDALONE "Standalone RADOS Gateway" ON WITH_RADOSGW_POSIX OFF) option(WITH_RADOSGW_RADOS "RADOS backend for Rados Gateway" ON) option(WITH_RADOSGW_SELECT_PARQUET "Support for s3 select on parquet objects" ON) option(WITH_RADOSGW_ARROW_FLIGHT "Build arrow flight when not using system-provided arrow" OFF) @@ -569,6 +592,9 @@ option(WITH_RADOSGW_BACKTRACE_LOGGING "Enable backtraces in rgw logs" OFF) option(WITH_SYSTEM_ARROW "Use system-provided arrow" OFF) option(WITH_SYSTEM_UTF8PROC "Use system-provided utf8proc" OFF) +# POSIX depends on DBStore: +cmake_dependent_option(WITH_RADOSGW_POSIX "POSIX backend for RADOS Gateway" ON WITH_RADOSGW_DBSTORE OFF) + if(WITH_RADOSGW) find_package(EXPAT REQUIRED) find_package(OATH REQUIRED) @@ -622,6 +648,23 @@ if(WITH_RADOSGW) message(STATUS "crypto soname: ${LIBCRYPTO_SONAME}") endif (WITH_RADOSGW) +if(WITH_RADOSGW_FDB) + include(${CMAKE_MODULE_PATH}/CPM.cmake) + + CPMAddPackage("gh:eyalz800/zpp_bits@4.5.1") + message("-- enabled zpp_bits") + +# JFW: sadly, I'm having trouble getting FoundationDB to build, but this is VERY close +# to "just working". But, how would we install the RPMs, etc.? This will need looking at +# before this can be non-experimental: +# CPMAddPackage("gh:apple/foundationdb@7.3.63") + message("FoundationDB support is EXPERIMENTAL and requires manual setup:") + message(" wget https://github.com/apple/foundationdb/releases/download/7.3.63/foundationdb-clients-7.3.63-1.el7.x86_64.rpm") + message(" wget https://github.com/apple/foundationdb/releases/download/7.3.63/foundationdb-server-7.3.63-1.el7.x86_64.rpm") + message("-- enabled FoundationDB (whether its there or not)") + +endif() + #option for CephFS option(WITH_CEPHFS "CephFS is enabled" ON) @@ -706,6 +749,13 @@ endif(LINUX) option(WITH_ASAN "build with ASAN" OFF) if(WITH_ASAN) list(APPEND sanitizers "address") + # Shared ASan/LSan runtime options: the in-tree suppression files plus the + # flags our tests need. Consumed by add_ceph_test() and baked into bin/ceph + # so both ignore the same still-reachable third-party leaks. + set(CEPH_ASAN_OPTIONS "suppressions=${CMAKE_SOURCE_DIR}/qa/asan.supp,detect_odr_violation=0" + CACHE INTERNAL "ASAN_OPTIONS for ceph tests and the ceph CLI") + set(CEPH_LSAN_OPTIONS "suppressions=${CMAKE_SOURCE_DIR}/qa/lsan.supp,print_suppressions=0" + CACHE INTERNAL "LSAN_OPTIONS for ceph tests and the ceph CLI") endif() option(WITH_ASAN_LEAK "explicitly enable ASAN leak detection" OFF) @@ -731,20 +781,24 @@ if(sanitizers) string(APPEND CMAKE_SHARED_LINKER_FLAGS " ${sanitiers_compile_flags}") endif() +# Jerasure & GF-Complete +option(WITH_SYSTEM_JERASURE "require and build with system jerasure and gf-complete" OFF) +if(WITH_SYSTEM_JERASURE) + find_package(Jerasure REQUIRED) +endif() + # Rocksdb option(WITH_SYSTEM_ROCKSDB "require and build with system rocksdb" OFF) if (WITH_SYSTEM_ROCKSDB) find_package(RocksDB 5.14 REQUIRED) endif() -option(WITH_CRIMSON "Build seastar components") - # Boost option(WITH_SYSTEM_BOOST "require and build with system Boost" OFF) # Boost::thread depends on Boost::atomic, so list it explicitly. set(BOOST_COMPONENTS - atomic chrono thread system regex random program_options date_time + atomic chrono headers thread regex random program_options date_time iostreams context coroutine url) set(BOOST_HEADER_COMPONENTS container) @@ -765,6 +819,10 @@ if(WITH_LIBCEPHFS OR WITH_FUSE) list(APPEND BOOST_COMPONENTS locale) endif() +if(WITH_CEPHFS) + list(APPEND BOOST_COMPONENTS filesystem) +endif() + set(Boost_USE_MULTITHREADED ON) CMAKE_DEPENDENT_OPTION(WITH_BOOST_VALGRIND "Boost support for valgrind" OFF @@ -795,8 +853,30 @@ else() include(BuildBoost) build_boost(1.87 COMPONENTS ${BOOST_COMPONENTS} ${BOOST_HEADER_COMPONENTS}) + if(WITH_ASAN) + # Boost.Context is built ucontext-only here (context-impl=ucontext); define + # the matching backend tree-wide so every Boost.Context/Coroutine2 consumer + # agrees on it, instead of relying on per-target propagation that is easy to miss. + add_compile_definitions(BOOST_USE_ASAN BOOST_USE_UCONTEXT) + endif() endif() include_directories(BEFORE SYSTEM ${Boost_INCLUDE_DIRS}) +if(WIN32 AND WITH_CATCH2) + foreach(catch2_target Catch2 Catch2WithMain) + if(TARGET ${catch2_target}) + target_include_directories(${catch2_target} SYSTEM PRIVATE + ${PROJECT_BINARY_DIR}/include + ${Boost_INCLUDE_DIRS}) + endif() + endforeach() +endif() +add_library(Boost::asio INTERFACE IMPORTED) +if(WITH_LIBURING AND CMAKE_SYSTEM_VERSION VERSION_GREATER_EQUAL "5.10") + # enable uring in boost::asio + set_target_properties(Boost::asio PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "BOOST_ASIO_HAS_IO_URING" + INTERFACE_LINK_LIBRARIES "Boost::headers;uring::uring") +endif() # dashboard angular2 frontend option(WITH_MGR_DASHBOARD_FRONTEND "Build the mgr/dashboard frontend using `npm`" ON) @@ -864,4 +944,3 @@ add_tags(ctags EXCLUDE_OPTS ${CTAG_EXCLUDES} EXCLUDES "*.js" "*.css" ".tox" "python-common/build") add_custom_target(tags DEPENDS ctags) - diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index fb832c0fb773..faad1536acb0 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -1,3 +1,7 @@ +Project governance is defined in + +`Governance`_ + For the general process of submitting patches to Ceph, read the below `Submitting Patches`_ @@ -16,3 +20,4 @@ primarily because it can cause problems when rebasing and backporting. .. _Submitting Patches: SubmittingPatches.rst .. _Documenting Ceph: doc/start/documenting-ceph.rst +.. _Governance: doc/governance.rst diff --git a/Dockerfile.build b/Dockerfile.build index 0586cdd37a4b..d3ef7eab700a 100644 --- a/Dockerfile.build +++ b/Dockerfile.build @@ -21,7 +21,7 @@ ARG DISTRO ARG CEPH_CTR_SRC=/usr/local/src/ceph ARG CLEAN_DNF=yes ARG CEPH_BASE_BRANCH=main -ARG SCCACHE_VERSION=v0.8.2 +ARG SCCACHE_VERSION=v0.15.0 ARG SCCACHE_REPO=https://github.com/mozilla/sccache ARG WITH_CRIMSON=true ARG FOR_MAKE_CHECK=1 @@ -36,6 +36,12 @@ RUN DISTRO=$DISTRO \ FOR_MAKE_CHECK=${FOR_MAKE_CHECK} \ bash -x ${CEPH_CTR_SRC}/buildcontainer-setup.sh RUN \ - SCCACHE_URL="${SCCACHE_REPO}/releases/download/${SCCACHE_VERSION}/sccache-${SCCACHE_VERSION}-$(uname -m)-unknown-linux-musl.tar.gz"; \ + if rpm --quiet --query sccache 2>/dev/null || { command -v dnf >/dev/null 2>&1 && dnf install -y sccache 2>/dev/null; }; then \ + echo "sccache provided by distro packages"; \ + elif [ $(uname -m) != ppc64le ]; then \ + SCCACHE_ARCH="$(uname -m)"; \ + if [ "$SCCACHE_ARCH" = riscv64 ]; then SCCACHE_ARCH=riscv64gc; fi; \ + SCCACHE_URL="${SCCACHE_REPO}/releases/download/${SCCACHE_VERSION}/sccache-${SCCACHE_VERSION}-${SCCACHE_ARCH}-unknown-linux-musl.tar.gz"; \ echo "${SCCACHE_URL}"; \ - curl -sS -L $SCCACHE_URL | tar --no-anchored --strip-components=1 -C /usr/local/bin/ -xzf - sccache + curl -sS -L $SCCACHE_URL | tar --no-anchored --strip-components=1 -C /usr/local/bin/ -xzf - sccache; \ + fi diff --git a/PendingReleaseNotes b/PendingReleaseNotes index f056f8e8c61c..9658c2f9964e 100644 --- a/PendingReleaseNotes +++ b/PendingReleaseNotes @@ -1,17 +1,296 @@ +* CephFS: The ``client_force_lazyio`` configuration option is now correctly marked + as not supporting runtime updates. Previously, the configuration schema indicated + this option could be changed at runtime, but changes had no effect on opened file + handlers in ceph-fuse or libcephfs clients because there is no logic to propagate + changes to open file handles. + +* RADOS: PG autoscaler allows overlapping roots. Each root receives a PG target based + on its OSDs, with OSDs shared across multiple roots contributing proportionally + less to each root's allocation. + +* CephFS: CephFS snapshots metadata is now mutable. It is now possible to add, + update and remove existing key-value pairs that are part of a snapshot + metadata via libcephfs API ceph_do_snap_md_op(). + +* CephFS: MDS dmclock support for subvolume QoS. With this feature, MDS assigns QoS + to throttle client metadata requests (e.g., create, mkdir, lookup, and so on) to + subvolumes, where each subvolume QoS is shared among multiple client sessions at + that time. + +* librados/neorados: The C++ APIs for executing Ceph Class (CLS) methods + have undergone a breaking change to enforce compile-time type safety, replacing + legacy string-based parameters with strongly-typed ClsMethod structs. C++ + developers must update their method calls to use these new structs, which ensure + read/write semantics are correctly applied. + +* RGW: S3 ListObjects and ListObjectVersions now support the + ``x-amz-optional-object-attributes: RestoreStatus`` request header to include + restore status in listing responses. Restore status is stored in the bucket + index, so only objects written or restored after this upgrade will populate + the field. Existing objects are unaffected. +* RGW: New S3 Control APIs to apply PublicAccessBlock configuration to User Accounts. +* ceph-volume: Raw BlueStore OSD preparation now pre-formats NVMe devices and + skips the slower BlueStore discard phase,reducing mkfs time on + very large namespaces. +* RGW: Omap backing for the RGW Datalog is deprecated and support will be removed in a future version. + - The `rgw default data log backing` option is removed and it is no longer + possible to create clusters with an omap based datalog. + - `radosgw-admin datalog type` will only accept `--log_type=fifo`. +* RGW: iam:RemoveClientIdFromOIDCProvider is now a recognized action for + policy, corrected from a typo of iam:RemoveCientIdFromOIDCProvider + +* MGR: The default values of ``mon_target_pg_per_osd`` and ``mon_max_pg_per_osd`` + have been increased from 100 and 250 to 200 and 500, respectively. These values + enhance the PG autoscaler's ability to calculate reasonable ``pg_num`` values + for pools under its control. These in turn increase parallelism and performance, + and improve the ``balancer`` module's ability to acheive uniform OSD utilization. + + [This concomitant PR](https://github.com/ceph/ceph/pull/67694) ensures that + upgrades are not delayed or disrupted by PG splitting as a result of this change. + + Clusters with effective ``bluestore_osd_memory_target`` values smaller than + the default 4GiB may wish to explicitly set the previous default values in + the central config store before upgrading. This will reduce the potential + for increased memory starvation. Clusters with SSDs split into more than two + OSDs may also wish to pin their current values in advance, or redeploy those + SSDs with at most two OSDs per. + +* RGW: Bucket Logging suppports creating log buckets in EC pools. + Implicit logging object commits are now performed asynchronously. +* RGW: radosgw-admin bucket list now supports pagination for versioned buckets by using + both --marker and --object-version options together (e.g., ``--marker=obj1 --object-version=abc123``). + This enables proper pagination through versioned bucket listings without duplicates or + infinite loops. For non-versioned buckets, use only --marker as before (backward compatible). * RGW: OpenSSL engine support is deprecated in favor of provider support. - Removed the `openssl_engine_opts` configuration option. OpenSSL engine configuration in string format is no longer supported. - Added the `openssl_conf` configuration option for loading specified providers as default providers. Configuration file syntax follows the OpenSSL standard (see https://github.com/openssl/openssl/blob/master/doc/man5/config.pod). If the default provider is required when also using custom providers, it must be explicitly loaded in the configuration file or code (see https://github.com/openssl/openssl/blob/master/README-PROVIDERS.md). +* RGW: Fixed bucket notification events so the 'x_amz_request_id' in NotificationEvent now matches the 'x_amz_request_id' returned by the corresponding S3 operation. +* RGW: The rgw_gc_max_deferred and rgw_gc_max_deferred_entries_size options have been removed, as they did not do anything. + - Updated the default for rgw_gc_max_queue_size to account for the extra space from removing rgw_gc_max_deferred_entries_size. +* RGW: The default value of ``rgw_thread_pool_size`` has been reduced from 512 to 128. + Benchmarks showed that the lower thread count improves throughput and reduces latency + on NVMe and HDD based environments. Users with specific workload requirements can + tune this value; see also ``rgw_max_concurrent_requests``. + + +* DASHBOARD: A new Overview landing page provides an at-a-glance cluster summary + with health status, capacity, performance metrics, and quick-access links. All the + previous legacy landing pages are removed. +* DASHBOARD: RGW Service form updated to take input regarding QAT compression. + QAT compression is an optional field which can be set to 'Hardware' or + 'Software' by selecting options from provided dropdwon. If 'None' is selected, + compression is removed altogether. +* DASHBOARD: NVMe-oF management workflows have been revamped with DH-HMAC-CHAP + in-band authentication support for both unidirectional (host-to-controller) and + bidirectional (mutual) authentication, namespace host masking, and an integrated + subsystem creation wizard that combines NQN setup, host addition, and + authentication configuration in a single guided flow. Subsystem HA is now enabled + by default. Gateway group creation and deletion are now supported directly from + the dashboard, including per-gateway node management. NVMe-oF performance and + overview Grafana dashboards are embedded directly in the Block > NVMe/TCP tab. +* DASHBOARD: RGW Storage Classes now support Glacier and Local storage class + types with full create, list, edit, and delete operations. +* DASHBOARD: RGW S3 Bucket Notifications are now fully manageable from the dashboard. + Notification destinations (topics) support full CRUD operations (create, list, edit, delete) + for configuring webhook endpoints, Kafka brokers, and AMQP queues. Bucket notification + configurations can be created, listed, edited, and deleted to define which S3 events + trigger notifications and which destination to use. +* DASHBOARD: RGW User Accounts can now be linked to individual RGW users, + root account user functionality has been added, and the bucket form + differentiates account users from standalone RGW users. +* DASHBOARD: RGW tiering now supports read-through configuration and bucket + tiering options in lifecycle policies. +* DASHBOARD: RGW multisite setup improvements: the RGW module is now + auto-enabled on primary and secondary clusters during multisite automation, + FQDN endpoints are supported (not only IPs), and users can re-use existing + realm/zonegroup/zone configurations when setting up replication. +* DASHBOARD: RGW archive zone configuration is now available from the dashboard. +* DASHBOARD: SMB shares now support QoS rate limiting, including per-share + bandwidth limits and cluster-wide rate limiting configuration. +* DASHBOARD: NFS export management has been enhanced with subvolume group and + subvolume selection in the edit export form, CephFS snapshot visibility + toggling per export, and IPv6 address support. NFS cluster and export listing + is now available. +* DASHBOARD: CephFS volume creation now supports selecting existing pools for + metadata and data instead of always creating new ones. +* DASHBOARD: Certificate management is now integrated into the dashboard. + Service detail views include a Certificate tab showing certificate status, and + the service create/edit modal supports certmgr-based certificate provisioning. + Certificate health alerts are surfaced in the dashboard and Prometheus. +* DASHBOARD: The onboarding (cluster creation) wizard has been redesigned with + an updated layout and improved visual flow. +* DASHBOARD: The dashboard UI has been modernized with the Carbon Design + System — including forms, modals, notifications, icons, performance charts, + and multi-cluster views. +* DASHBOARD: Logging infrastructure has been migrated from Promtail to Grafana + Alloy. +* DASHBOARD: Prometheus configuration now supports a remote write section for + forwarding metrics to external systems. +* DASHBOARD: `ceph dashboard sso enable oauth2` checks for oauth2-proxy service for SSO enablement.  If the `oauth2-proxy` service goes down, cephadm will automatically disable Dashboard OAuth2 SSO. +* Monitoring: New Grafana dashboards have been added for Application Overview, + CephFS, CephFS Subvolume, NVMe-oF (performance and overview), SMB Overview, + and RGW Bucket Notification. The Grafana dashboards naming convention has been + standardized. Grafana has been upgraded to version 12.3.1. +* Monitoring: Added ``NVMeoFHostKeepAliveTimeout`` Prometheus alert that fires + when an NVMe-oF host keepalive times out. +* Monitoring: Certificate management health checks now generate Prometheus + alerts and dashboard warnings for certificate expiration and errors. + - CephCertificateError: Fires when a Ceph certificate has expired (critical severity). + - CephCertificateWarning: Fires when a Ceph certificate is about to expire (warning severity). -* DASHBOARD: Removed the older landing page which was deprecated in Quincy. - Admins can no longer enable the older, deprecated landing page layout by - adjusting FEATURE_TOGGLE_DASHBOARD. * CephFS: The `peer_add` command is deprecated in favor of the `peer_bootstrap` command. +* RGW: For `radosgw-admin account rm`, the `--purge-data` option previously applied only + to buckets and objects, but now deletes account users, roles, groups, and oidc-providers + too instead of failing with ENOTEMPTY. +* RADOS: When objects are read during deep scrubs, the data is read in strides, + and the scrubbing process is delayed between each read in order to avoid monopolizing + the I/O capacity of the OSD. + The default stride size (``osd_deep_scrub_stride``) was 512 KBytes, and is now 4 MBytes. +* RADOS: When an OSD is overloaded with queued snap-trim operations, no + regular (non-urgent) scrubs will be scheduled on that OSD. This is + determined by comparing the total snap-trim queue lengths for all PGs + for which the OSD is a primary against ``osd_scrub_queued_snaptrims_limit``, + which defaults to 500. + This restriction does not apply to operator-initiated scrubs, nor to repair scrubs. + It can be disabled by setting ``osd_scrub_queued_snaptrims_limit`` to 0. +* RGW: Add SSE-KMS secrets cache + +* RADOS: Stretch mode can now be entered even if the two dividing buckets differ + in weight by a small fraction (default 0.1). This is tunable via + `mon_stretch_max_bucket_weight_delta`. + +* CephFS: The offline CephFS tools (cephfs-data-scan, cephfs-journal-tool, + and cephfs-table-tool) now include progress tracking with ETA (Estimated Time of + Arrival) for long-running operations. Progress updates are displayed automatically + at regular intervals, showing completion percentage, processed items, and time + estimates. This feature is enabled by default for relevant commands including + scan_extents, scan_inodes, and other state-changing operations. + Related Tracker: https://tracker.ceph.com/issues/63191 +* RBD: Fixed incorrect behavior of the "start-time" argument for mirror + snapshot and trash purge schedules, where it previously offset the schedule + anchor instead of defining it. The argument now requires an ISO 8601 + date-time. The `schedule ls` output displays the start time in UTC, including + the date and time in the format "%Y-%m-%d %H:%M:00". The `schedule status` + output now displays the next schedule time in UTC. +* CephFS Mirroring: Now utilizes a multi-threaded architecture to improve synchronization + performance. The workload is split into two distinct thread pools: a crawler thread pool, which + manages snapshot crawl and a data synchronization thread pool, which handles concurrent file + transfers. Users can fine-tune these operations using configuration parameters: + cephfs_mirror_max_concurrent_directory_syncs (controlling the number of concurrent snapshots being crawled) + and cephfs_mirror_max_datasync_threads (controlling the total threads available for data sync). + For more information, see https://tracker.ceph.com/issues/73452 +* CephFS Mirroring: Improved incremental synchronization behavior in CephFS mirroring. Previously, + block-level delta synchronization was used for all files regardless of size. With this change, + blockdiff is applied only to files larger than a configurable threshold, while smaller files are + synchronized using full copy, as blockdiff is not efficient for small files. The threshold is + controlled by the new configuration option cephfs_mirror_blockdiff_min_file_size (default: 16_M). + For more information, see https://tracker.ceph.com/issues/73452 +* CephFS Mirroring: Improved mirror daemon status reporting. The command + ``ceph fs snapshot mirror daemon status`` now shows the remote cluster's + monitor addresses and cluster ID for each configured peer, making it easier + to verify peer connectivity and troubleshoot mirroring issues. +* CephFS Mirroring: The ``fs mirror peer status`` admin socket command reports + additional per-directory sync metrics (sync mode, throughput, crawl and + data-sync queue timing, bytes/files progress, and ETA). Output is grouped + under ``metrics//peer/``. For more information, + see https://tracker.ceph.com/issues/73453 +* CephFS Mirroring: Per-directory snapshot sync progress is exposed as labeled perf + counters in the ``cephfs_mirror_directory`` group (``counter dump`` on the mirror + daemon admin socket, exportable via ``ceph-exporter``). Counters mirror + ``fs mirror peer status`` fields (directory state, current sync, last sync, and + snap summary) and are labeled by peer UUID and mirrored directory path. See + https://tracker.ceph.com/issues/73457 +* CephFS Mirroring: The mirroring module provides ``ceph fs snapshot mirror status``, + a Ceph CLI command similar to the ``fs mirror peer status`` admin socket interface + for viewing per-directory snapshot sync metrics. The output layout matches + ``fs mirror peer status`` for core sync fields and additionally includes + ``metrics_updated_at`` (time of the last omap write). Optional filters by + mirrored directory path and peer UUID are supported. For more information, + see https://tracker.ceph.com/issues/76686 +* CephFS Mirroring: Introduced snapshot checkpoints feature that allows users to mark + specific snapshots as important milestones and track their replication status to remote + sites. Checkpoints automatically detect if a snapshot has already been synced and provide + visibility into disaster recovery readiness. The feature includes four new CLI commands: + ``ceph fs snapshot mirror checkpoint add`` to mark a snapshot, + ``ceph fs snapshot mirror checkpoint now`` to checkpoint the latest snapshot, + ``ceph fs snapshot mirror checkpoint ls`` to list all checkpoints with their status + (created/complete/failed), and ``ceph fs snapshot mirror checkpoint remove`` to remove + a checkpoint. Checkpoint metadata is persistent across daemon restarts. This feature is + useful for compliance auditing, application consistency verification, and SLA tracking. + For more information, see https://tracker.ceph.com/issues/73454 +* RBD: Mirror snapshot creation and trash purge schedules are now automatically + staggered when no explicit "start-time" is specified. This reduces scheduling + spikes and distributes work more evenly over time. +* RBD: Introduced a new ``RBD_LOCK_MODE_EXCLUSIVE_TRANSIENT`` policy for + ``rbd_lock_acquire()``. This is a low-level interface intended to allow + a peer to grab exclusive lock manually for short periods of time with other + peers pausing their activity and waiting for the lock to be released rather + than instantly aborting I/O and returning an error. It's possible to switch + from ``RBD_LOCK_MODE_EXCLUSIVE`` to ``RBD_LOCK_MODE_EXCLUSIVE_TRANSIENT`` + policy and vice versa even if the lock is already held. +* RGW: In multisite deployments, zone endpoints configured in the zonegroup + (e.g. ``https://zone-a.example.com``) can now be resolved to all IP addresses + returned by DNS, with inter-zone traffic distributed across them using + round-robin and per-IP health tracking. This enables DNS-based service discovery + for inter-zone traffic without an external load balancer. This feature is disabled + by default: to opt in, set ``rgw_rest_conn_connect_to_resolved_ips = true``. The + per-IP retry-after-failure timeout is controlled by ``rgw_rest_conn_ip_fail_timeout_secs`` + (default: 2 seconds). Deployments that work around libcurl's single-address behavior + by repeating the same endpoint multiple times in zone configuration should review that + setup before enabling, as round-robin distribution makes such duplication unnecessary. + +* OSD: A health warning is reported when BlueFS usage exceeds the + configured ratio of the main OSD data device size. This warning is + informational and can be muted with: + ``ceph health mute BLUESTORE_BLUEFS_OVERSIZED`` +* MGR: The Manager now automatically increases ``mgr_stats_period`` when its + message queue is congested, reducing daemon reporting frequency to prevent + overload. The period recovers automatically once the queue clears. This + behavior is controlled by the new ``mgr_stats_period_autotune`` (default: + ``true``) and ``mgr_stats_period_autotune_queue_threshold`` (default: ``100``) + config options. +* MGR: The Manager cache system has been redesigned from a TTL-based (time-to-live) + approach to an event-driven invalidation strategy. The cache now automatically + invalidates entries when underlying cluster maps are updated. The cache is enabled + by default. The previous `mgr_ttl_cache_expire_seconds` configuration option has + been removed and replaced with `mgr_map_cache_enabled` (default: true). +* The ``last_degraded`` timestamp is added to the ``pg_stat_t`` structure to + track the initial point of redundancy loss when a PG enters an undersized or + degraded state. This timestamp is latched until the PG returns to a clean + state and a subsequent redundancy loss occurs. Used in conjunction with + ``last_clean``, the ``last_degraded`` timestamp enables the calculation of + data vulnerability and durability scores. +* RBD: It's possible to specify source cluster's ``mon_host`` and ``key`` for + ``native`` format migration via the migration spec now. This eliminates the + dependency on ``.conf`` file in a known location which is + rather rigid and also challenging to disseminate in some environments. The + key can be embedded in the migration spec or just referenced from there while + stored in the MON config-key store. +* RBD: `Group::list_images` python API will now correctly raise an ObjectNotFound + error when invoked on a non-existent group. The C APIs `rbd_group_image_list`, + `rbd_snap_list`, `rbd_group_snap_list` and C++ API `group_image_list` will now + return ENOENT instead of masking the error and returning 0. +* BlueStore: The experimental PMEM device backend has been removed, together + with the ``pmem`` value of the ``bdev_type`` option and the DML/DSA offload + path. The hardware it targeted, Intel Optane DC persistent memory, was + discontinued in 2022. The RBD persistent write-back cache, which also uses + PMDK, is unaffected. + + Existing OSDs backed by persistent memory in fsdax mode (a block device such + as ``/dev/pmem0``) keep working on the default ``aio`` backend over the same + data. Remove any explicit ``bdev_type = pmem`` from their configuration. OSDs + on a devdax namespace (a character device such as ``/dev/dax0.0``) will no + longer start, because no remaining backend can open one; reconfigure the + namespace to fsdax with ``ndctl`` or re-provision them before upgrading. >=20.0.0 +* Client: New config value osd_min_split_replica_read_size, which allows control + of the minimum size a read can be when a client breaks up the read into multiple + smaller reads across PG shards. * RADOS: The lead Monitor and stretch mode status are now displayed by `ceph status`. Related Tracker: https://tracker.ceph.com/issues/70406 * RGW: The User Account feature introduced in Squid provides first-class support for @@ -216,12 +495,32 @@ * Dashboard: RGW Topics and Bucket Notification Management * Dashboard: RGW granular bucket replication * Dashboard: SMB monitoring and management +* Dashboard: `ceph dashboard sso enable oauth2` checks for oauth2-proxy service for SSO enablement.  If the `oauth2-proxy` service goes down, cephadm will automatically disable Dashboard OAuth2 SSO. * Monitoring: New monitoring Dashboards for Application, NVMe, CephFS, and SMB Overview * RGW: Introduce the `rgw_usage_log_key_transition` configuration option to handle the co-existence of old and new usage log keys. This option is enabled by default to ensure compatibility during upgrades, but can be disabled once old usage logs are no longer present to avoid performance overhead. +* NVMe-oF: A new Ceph Manager module, `nvmeof`, is now available. When enabled, it provisions the + dedicated `.nvmeof` RADOS Block Device (RBD) pool required for NVMe-oF integration, + simplifying initial setup and ensuring the pool is created consistently across deployments. + +* MGR: A new command, `ceph osd ok-to-upgrade`, has been added that allows + users and orchestration tools to determine a safe set of OSDs within a CRUSH + bucket to upgrade simultaneously without impacting data availability. To help + converge to a safe set, a new config option + ``mgr_osd_upgrade_check_convergence_factor`` is introduced. This option can be + modified (if necessary) to help converge to an optimal set. Higher values + maximize the set of OSDs to upgrade at the cost of longer command response + times. Conversely, a lower value improves the command response time but + results in a non-optimal or smaller set of OSDs which impacts the overall time + to upgrade all OSDs in the cluster. For more details see tracker: + https://tracker.ceph.com/issues/73031. + +* NFS: cluster/export delete commands now throw a deprecation warning when + used and will be removed in V release. + >=19.2.1 * CephFS: The `fs subvolume create` command now allows tagging subvolumes through option @@ -789,3 +1088,13 @@ can be configured using the `rgw` option `rgw_bucket_persistent_notif_num_shards https://docs.ceph.com/en/latest/radosgw/notifications/ Relevant tracker: https://tracker.ceph.com/issues/71677 + +* RGW: Multipart upload part heads are now tracked under a new + ``rgw.multipart`` category in bucket stats, separate from completed + objects (``rgw.main``). This makes ``radosgw-admin bucket stats`` + and the ``X-RGW-Object-Count`` header on HEAD Bucket more accurate: + in-progress or abandoned multipart parts no longer inflate the + object count. Existing in-progress uploads retain the old category + until they complete or abort. + + Relevant tracker: https://tracker.ceph.com/issues/77509 diff --git a/README.FreeBSD b/README.FreeBSD index a3193f7d23e3..8eb98e7c78ae 100644 --- a/README.FreeBSD +++ b/README.FreeBSD @@ -149,8 +149,6 @@ Task to do: - Improve the FreeBSD /etc/rc.d initscripts in the Ceph stack. Both for testing, but mainly for running Ceph on production machines. - Work on ceph-disk and ceph-deploy to make it more FreeBSD and ZFS - compatible. - Build test-cluster and start running some of the teuthology integration tests on these. diff --git a/SubmittingPatches-backports.rst b/SubmittingPatches-backports.rst index bb55088cb5fa..45d24d1ff064 100644 --- a/SubmittingPatches-backports.rst +++ b/SubmittingPatches-backports.rst @@ -2,7 +2,7 @@ Submitting Patches to Ceph - Backports ====================================== Most likely you're reading this because you intend to submit a GitHub pull -request ("PR") targeting one of the stable branches ("nautilus", etc.) at +request ("PR") targeting one of the stable branches ("tentacle", etc.) at https://github.com/ceph/ceph. Before you open that PR, please read this entire document or, at the very least, @@ -16,6 +16,8 @@ the following two sections: `General principles`_ and `Cherry-picking rules`_. General principles ------------------ +.. note:: There are many automations that exist for backports. If you read nothing else in this document, please read `ceph-backport`_ section for automating backport creation. + To help the people who will review your backport, please state either in the backport PR, or in the backport tracker issue, or in the ``main`` branch tracker issue: @@ -36,11 +38,14 @@ ages, the importance of following these general principles rises. Cherry-picking rules -------------------- +**Note: These rules are strictly enforced by the `releng-audit` GitHub Actions CI. Failure to adhere to them will block your PR.** + The following rules, which have been codified from "best practices" developed over years of backporting, apply to the actual backport implementation: * all fixes should land in ``main`` first * commits to stable branches should be cherry-picked from ``main`` +* if a commit is entirely specific to the backport and *not* cherry-picked from ``main``, its commit message summary must begin with the target branch name (e.g., ``squid: fix compilation issue``). * before starting to cherry-pick a set of commits from ``main``, grep the ``main`` git history for the SHA1 of each ``main`` commit (using ``git log --grep``) to check for follow-up fixes. Include any follow-up fixes found in the set of commits to be cherry-picked. * when backporting a ``main`` PR to a stable branch, double-check that the backport PR contains cherry-picks of all of the ``main`` PR's commits. If any commit needs to be omitted, declare and explain this in the PR. * cherry-picks must be done using ``git cherry-pick -x`` @@ -111,9 +116,16 @@ the tracker issue. For example, if the PR number is 99999:: Pull request ID: 99999 -Once the ``main`` PR has been merged, after checking that the change really needs -to be backported and the Backport field has been populated, change the ``main`` -branch tracker issue's ``Status`` field to "Pending Backport". +In general, you should stop here with manually managing the state of the +tracker tickets. If the ``Pull request ID`` field of the ``main`` tracker is +up-to-date, the ``redmine-upkeep`` Github CI will automatically detect a merge +and move your tracker to the ``Pending backport`` state as long as the +``Backport`` field has release branches in it. Otherwise the ticket will be +moved to ``Resolved``. + +However, if that CI fails to run for whatever reason, you may manually correct +the ticket by setting the ``main`` branch tracker issue's ``Status`` field to +"Pending Backport":: Status: Pending Backport @@ -121,40 +133,28 @@ If you do not have sufficient permissions to modify any field of the tracker issue, just add a comment describing what changes you would like to make. Someone with permissions will make the necessary modifications on your behalf. -Authors of pull requests are responsible for creating associated backport pull -requests. As long as you have sufficient permissions at -https://tracker.ceph.com, you can `create Backport tracker issues` and `stage -backports`_ yourself. Read these linked sections to learn how to create -backport tracker issues and how to stage backports: - .. _`create backport tracker issues`: .. _`backport tracker issue`: Creating Backport tracker issues -------------------------------- -To track backporting efforts, "backport tracker issues" can be created from -a parent "``main`` branch tracker issue". The ``main`` branch tracker issue is described in the -previous section, `Tracker workflow`_. This section focuses the backport tracker -issue. - -Once the entire `Tracker workflow`_ has been completed for the ``main`` branch tracker issue, -issues can be created in the backport tracker issue for tracking the backporting work. - -Under ordinary circumstances, the developer who merges the ``main`` PR will flag -the ``main`` branch tracker issue for backport by changing the Status to "Pending -Backport". +To track backporting efforts, "backport tracker issues" can be created from a +parent ``main`` branch tracker issue. The ``main`` branch tracker issue is +described in the previous section, `Tracker workflow`_. This section focuses +the backport tracker issue. -You might be tempted to forge ahead and create the backport issues yourself. -Please don't do that - it is difficult (bordering on impossible) to get all the -fields correct when creating backport issues manually, and why even try when -there is a script that gets it right every time? Setting up the script requires -a small up-front time investment. Once that is done, creating backport issues -becomes trivial. +When a ``main`` branch tracker issue is in the ``Pending Backport`` state, +another Github CI running ``backport-create-issue`` will trigger and create the +backport tickets to be associated with the ``main`` tracker. This workflow will +auto-populate the required metadata for the tracker tickets to track the +backports. The backport-create-issue script ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. warning:: It is discouraged to run this script yourself. However, sometimes CI checks fail to run, so please review for those circumstances. + The script used to create backport issues is located at ``src/script/backport-create-issue`` in the ``main`` branch. Though there might be an older version of this script in a stable branch, do not use it. Only use the @@ -178,21 +178,21 @@ dependency, `python-redmine`_, can be obtained from PyPi:: Then, try to run the script:: - backport-create-issue --help + python3 -c "$(git show main:src/script/backport-create-issue)" --help This should produce a usage message. Finally, run the script to actually create the Backport issues. For example, if the tracker issue number is 55555:: - backport-create-issue --user --password 55555 + python3 -c "$(git show main:src/script/backport-create-issue)" --user --password 55555 The script needs to know your https://tracker.ceph.com credentials in order to authenticate to Redmine. In lieu of providing your literal username and password on the command line, you could also obtain a REST API key ("My account" -> "API access key"), put it in ``~/.redmine_key`` and run the script like so:: - backport-create-issue 55555 + python3 -c "$(git show main:src/script/backport-create-issue)" 55555 .. _`stage backports`: @@ -213,6 +213,8 @@ In the past, much time was lost, and much frustration caused, by the necessity of staging backports manually. Now, fortunately, there is a script available which automates the process and takes away most of the guesswork. +.. _`ceph-backport`: + The ceph-backport.sh script ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -294,13 +296,23 @@ For a quick reference on CLI, that contains above information, you can run:: ceph-backport.sh --usage +Milestones and Labels +""""""""""""""""""""" + +The ``ceph-backport.sh`` script automates the process of setting the Milestone +tag to the stable release the backport PR is targeting. + +PR labels (such as component labels) are added automatically by automations; +the backport author does not need to do anything manually. + + Conflict resolution ^^^^^^^^^^^^^^^^^^^ -If git reports conflicts, the script will abort to allow you to resolve the -conflicts manually. +**Automated Conflict Simulation:** The `releng-audit` CI will perform a dry-run of the cherry-pick and compare the resulting tree to your PR. If you make *any* manual changes (even to fix a bug introduced by the backport), you **must** document it in the ``Conflicts:`` block. If a legitimate manual resolution is flagged as an unapproved deviation, any user with "maintain" or "admin" rights on the repository, or a member of the ``@ceph/ceph-release-manager`` team, must comment ``/audit override`` or manually apply the ``releng-audit-override`` label on the PR to bypass the simulation check. -Once the conflicts are resolved, complete the cherry-pick :: +If git reports conflicts, the script will abort to allow you to resolve the +conflicts manually. Once the conflicts are resolved, complete the cherry-pick :: git cherry-pick --continue @@ -313,6 +325,7 @@ of the commit message before committing the cherry-pick. You can also include commentary on what the conflicts were and how you resolved them. For example:: + Conflicts: src/foo/bar.cc - mimic does not have blatz; use batlo instead @@ -347,17 +360,40 @@ original commit message. If you use `ceph-backport.sh` for your backport creation (which is recommended), read up at the end of `The ceph-backport.sh script`_ on how to continue from here. -Labelling of backport PRs -------------------------- +Automated Audit Workflow +------------------------ + +Once your backport PR is open, it will be automatically audited by the `releng-audit` GitHub Actions CI. This workflow enforces backport rules and ensures consistency between GitHub and Redmine. + +The audit performs the following checks: + +* **Merge Conflict:** Verifies that the PR can merge cleanly into the target base branch without git conflicts. +* **Commit Parity:** Ensures all commits from the original ``main`` PR(s) are present in the backport. It flags missing commits, unmerged cherry-picks, or invalid commit message formats. +* **Conflict Simulation:** Dry-runs the cherry-pick sequence to dynamically verify conflict resolutions. It will fail if there are undocumented or unapproved deviations from a clean cherry-pick. +* **Redmine Linkage:** Checks that the backport PR is properly linked to its Redmine backport tracker, and that the original ``main`` PR is correctly linked to the parent tracker ticket. + +**Addressing Failures (PR Author Workflow):** + +If the audit fails, the CI bot will post a review detailing the issues and apply the ``releng-audit-fail`` label. -Once the backport PR is open, the first order of business is to set the -Milestone tag to the stable release the backport PR is targeting. For example, -if the PR is targeting "nautilus", set the Milestone tag to "nautilus". +* **Fix the issues:** Address the failures as guided by the bot's review (e.g., fix Redmine tracker links, rebase your branch, fix commit messages, or adjust the code to match upstream patches). +* **Retest:** When you are ready for a new audit, **remove the ``releng-audit-fail`` label** or comment ``/audit retest`` on the PR. +* **Note:** You cannot manually apply the ``releng-audit-pass`` or ``releng-audit-fail`` labels; they are strictly managed by the CI bot and your manual changes to them will be rejected. -Next, check which component label was applied to the ``main`` PR corresponding to -this backport, and double-check that that label is applied to the backport PR as -well. For example, if the ``main`` PR carries the component label "core", the -backport PR should also get that label. +**Bypassing the Audit (Component Lead / Release Manager Workflow):** + +In some cases, the audit may flag a legitimate manual conflict resolution or an intentional deviation in the code. + +* If a deviation is intentional, documented in the commit message, and approved, authorized users (repository admins/maintainers or members of the ``@ceph/ceph-release-manager`` team) can bypass the check. +* To apply the bypass, comment ``/audit override`` on the PR or manually apply the ``releng-audit-override`` label. + +**Audit Labels Explained:** + +* ``releng-audit-pass``: Applied automatically by the bot when all checks pass. +* ``releng-audit-fail``: Applied automatically by the bot when checks fail. Removing this label triggers a new audit. +* ``releng-audit-override``: Applied manually by authorized leads/managers to override an audit failure. + +The bot will leave a failing CI check if a backport PR does not have either ``releng-audit-pass`` or ``releng-audit-override``. .. _`backport PR reviewing`: .. _`backport PR testing`: @@ -369,6 +405,8 @@ Reviewing, testing, and merging of backport PRs Once your backport PR is open, it will be reviewed and tested. When the PR has been reviewed and tested, it will be merged. +* **Prerequisite:** The PR must have the ``releng-audit-pass`` or ``releng-audit-override`` label applied before it is eligible for merging. + If you would like to facilitate this process, you can solicit reviews and run integration tests on the PR. In this case, add comments to the PR describing the tests you ran and their results. diff --git a/SubmittingPatches.rst b/SubmittingPatches.rst index 5869bba81422..ad8211b3f53a 100644 --- a/SubmittingPatches.rst +++ b/SubmittingPatches.rst @@ -214,9 +214,9 @@ the following difference: the PR title describes the entire set of changes, while the `Commit title`_ describes only the changes in a particular commit. If GitHub suggests a PR title based on a very long commit message it will split -the result with an elipsis (...) and fold the remainder into the PR description. +the result with an ellipsis (...) and fold the remainder into the PR description. In such a case, please edit the title to be more concise and the description to -remove the elipsis. +remove the ellipsis. Keep in mind that the PR titles feed directly into the script that generates release notes and it is tedious to clean up non-conformant PR titles at release diff --git a/admin/doc-read-the-docs.txt b/admin/doc-read-the-docs.txt index 282d02168059..bcc77ccffb0a 100644 --- a/admin/doc-read-the-docs.txt +++ b/admin/doc-read-the-docs.txt @@ -1,3 +1 @@ plantweb -readthedocs-sphinx-search@git+https://github.com/readthedocs/readthedocs-sphinx-search@main -pip < 25.3 diff --git a/admin/doc-requirements.txt b/admin/doc-requirements.txt index c350bb63db6e..1cb7af2624f5 100644 --- a/admin/doc-requirements.txt +++ b/admin/doc-requirements.txt @@ -15,7 +15,6 @@ sphinx_rtd_theme Sphinx-Substitution-Extensions sphinxcontrib-mermaid sphinxcontrib-openapi -sphinxcontrib-seqdiag # m2r2 replaces mistune https://github.com/CrossNox/m2r2?tab=readme-ov-file#m2r-the-original m2r2 natsort diff --git a/ceph-object-corpus b/ceph-object-corpus index 9670a0ef3c10..44b11dd5aa8a 160000 --- a/ceph-object-corpus +++ b/ceph-object-corpus @@ -1 +1 @@ -Subproject commit 9670a0ef3c10bb2afa1ed4f75cbdfdc954a170cb +Subproject commit 44b11dd5aa8a2f965ea395f13cf4cbb4a61e9afe diff --git a/ceph.spec.in b/ceph.spec.in index 43736f27c804..8fae0974d64a 100644 --- a/ceph.spec.in +++ b/ceph.spec.in @@ -34,8 +34,8 @@ %else %bcond_with rbd_rwl_cache %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} -%if 0%{?rhel} < 9 || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} +%if 0%{?openEuler} || 0%{?openruyi} %bcond_with system_pmdk %else %ifarch s390x aarch64 @@ -44,7 +44,11 @@ %bcond_without system_pmdk %endif %endif +%if 0%{?openruyi} +%bcond_with selinux +%else %bcond_without selinux +%endif %bcond_without amqp_endpoint %bcond_without kafka_endpoint %bcond_without lttng @@ -91,29 +95,27 @@ %bcond_with lua_packages %endif %endif -%bcond_with crimson +%bcond_without crimson %if 0%{?suse_version} || 0%{?openEuler} %bcond_with jaeger %else %bcond_without jaeger %endif -%if 0%{?fedora} || 0%{?suse_version} >= 1500 || 0%{?rhel} >= 9 +%if 0%{?fedora} || 0%{?suse_version} >= 1500 || 0%{?rhel} || 0%{?openruyi} # distros that ship cmd2 and/or colorama %bcond_without cephfs_shell %else # distros that do _not_ ship cmd2/colorama %bcond_with cephfs_shell %endif -%if 0%{?fedora} || 0%{?rhel} >= 9 +%if 0%{?fedora} || 0%{?rhel} %bcond_without system_arrow %else -# for centos 8, utf8proc-devel comes from the subversion-devel module which isn't available in EPEL8 -# this is tracked in https://bugzilla.redhat.com/2152265 %bcond_with system_arrow %endif # qat only supported for intel devices %ifarch x86_64 -%if 0%{?fedora} || 0%{?rhel} >= 9 +%if 0%{?fedora} || 0%{?rhel} %bcond_without system_qat %else # not fedora/rhel @@ -123,7 +125,8 @@ # not x86_64 %bcond_with system_qat %endif -%if 0%{?fedora} || 0%{?suse_version} || 0%{?rhel} >= 8 || 0%{?openEuler} +%bcond_with system_rdkafka +%if 0%{?fedora} || 0%{?suse_version} || 0%{?rhel} || 0%{?openEuler} %global weak_deps 1 %endif %if %{with selinux} @@ -135,7 +138,11 @@ %{!?_selinux_policy_version: %global _selinux_policy_version 0.0.0} %endif %endif +%if 0%{?openruyi} +%bcond_with cephadm_bundling +%else %bcond_without cephadm_bundling +%endif %bcond_without cephadm_pip_deps %bcond_without dwz %if %{with dwz} @@ -144,13 +151,18 @@ %global _find_debuginfo_dwz_opts %{nil} %endif %bcond_with sccache +%if 0%{?rhel} && 0%{?rhel} >= 10 +%bcond_without pypkg +%else +%bcond_with pypkg +%endif %{!?_udevrulesdir: %global _udevrulesdir /lib/udev/rules.d} %{!?tmpfiles_create: %global tmpfiles_create systemd-tmpfiles --create} -%{!?python3_pkgversion: %global python3_pkgversion 3} %{!?python3_version_nodots: %global python3_version_nodots 3} %{!?python3_version: %global python3_version 3} -%if 0%{?rhel} < 10 +%global c_ares_min_version 1.28.0 +%if 0%{?rhel} && 0%{?rhel} < 10 %{!?gts_version: %global gts_version 13} %endif @@ -167,6 +179,18 @@ [ $jobs -lt 1 ] && jobs=1 \ echo $jobs ) +# $1==1: fresh install; $1==0: removal. Skip try-restart on upgrade ($1>1). +%define ceph_mgr_module_scripts() \ +%post %1\ +if [ $1 -eq 1 ] ; then\ + /usr/bin/systemctl try-restart ceph-mgr.target >/dev/null 2>&1 || :\ +fi\ +\ +%postun %1\ +if [ $1 -eq 1 ] ; then\ + /usr/bin/systemctl try-restart ceph-mgr.target >/dev/null 2>&1 || :\ +fi + %if 0%{?_smp_ncpus_max} == 0 %if 0%{?__isa_bits} == 32 # 32-bit builds can use 3G memory max, which is not enough even for -j2 @@ -207,7 +231,7 @@ Epoch: 2 %global _epoch_prefix %{?epoch:%{epoch}:} Summary: User space components of the Ceph file system -License: LGPL-2.1 and LGPL-3.0 and CC-BY-SA-3.0 and GPL-2.0 and BSL-1.0 and BSD-3-Clause and MIT +License: LGPL-2.1-or-later AND LGPL-3.0-only AND CC-BY-SA-3.0 AND GPL-2.0-only AND BSL-1.0 AND BSD-2-Clause AND BSD-3-Clause AND MIT %if 0%{?suse_version} Group: System/Filesystems %endif @@ -238,7 +262,7 @@ BuildRequires: gperf BuildRequires: cmake > 3.5 BuildRequires: pkgconfig(fuse3) BuildRequires: git -BuildRequires: grpc-devel +BuildRequires: pkgconfig(grpc++) # Before 13.3, an lto bug resulted in a segfault in SafeTimer and perhaps # elsewhere. Require the fixed version so we can reenable lto. See # ceph bug https://tracker.ceph.com/issues/63867 @@ -257,59 +281,69 @@ BuildRequires: libatomic %endif %if 0%{with tcmalloc} # libprofiler did not build on ppc64le until 2.7.90 -%if 0%{?fedora} || 0%{?rhel} >= 8 || 0%{?openEuler} -BuildRequires: gperftools-devel >= 2.7.90 -%endif -%if 0%{?rhel} && 0%{?rhel} < 8 -BuildRequires: gperftools-devel >= 2.6.1 +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} +BuildRequires: pkgconfig(libtcmalloc) >= 2.7.90 %endif %if 0%{?suse_version} BuildRequires: gperftools-devel >= 2.4 %endif %endif BuildRequires: libaio-devel -BuildRequires: libblkid-devel >= 2.17 -BuildRequires: cryptsetup-devel -BuildRequires: libnbd-devel -BuildRequires: libcurl-devel -BuildRequires: libcap-devel -BuildRequires: libcap-ng-devel -BuildRequires: fmt-devel >= 6.2.1 +BuildRequires: pkgconfig(blkid) >= 2.17 +BuildRequires: pkgconfig(libcryptsetup) +BuildRequires: pkgconfig(libnbd) +BuildRequires: pkgconfig(libcurl) +BuildRequires: pkgconfig(libcap) +BuildRequires: pkgconfig(libcap-ng) +BuildRequires: pkgconfig(fmt) >= 6.2.1 BuildRequires: pkgconfig(libudev) -BuildRequires: libnl3-devel -BuildRequires: liboath-devel +BuildRequires: pkgconfig(nss) +BuildRequires: pkgconfig(libkeyutils) +BuildRequires: pkgconfig(openssl) +BuildRequires: pkgconfig(ldap) +BuildRequires: pkgconfig(libibverbs) +BuildRequires: pkgconfig(librdmacm) +BuildRequires: pkgconfig(liblz4) >= 1.7 +BuildRequires: pkgconfig(libnl-3.0) +BuildRequires: pkgconfig(liboath) BuildRequires: libtool -BuildRequires: libxml2-devel +BuildRequires: pkgconfig(libxml-2.0) BuildRequires: make -BuildRequires: ncurses-devel -BuildRequires: libicu-devel +BuildRequires: pkgconfig(ncurses) +BuildRequires: pkgconfig(icu-uc) BuildRequires: patch BuildRequires: perl BuildRequires: pkgconfig BuildRequires: procps -BuildRequires: python%{python3_pkgversion} -BuildRequires: python%{python3_pkgversion}-devel -BuildRequires: python%{python3_pkgversion}-setuptools -BuildRequires: python%{python3_pkgversion}-Cython -BuildRequires: snappy-devel -BuildRequires: sqlite-devel +BuildRequires: python3 +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3dist(cython) +BuildRequires: python3-pip +BuildRequires: python3-wheel +BuildRequires: pkgconfig(snappy) +BuildRequires: pkgconfig(sqlite3) BuildRequires: sudo BuildRequires: pkgconfig(udev) -BuildRequires: valgrind-devel +BuildRequires: pkgconfig(valgrind) BuildRequires: which BuildRequires: xfsprogs-devel BuildRequires: xmlstarlet BuildRequires: nasm -BuildRequires: lua-devel -BuildRequires: lmdb-devel +BuildRequires: pkgconfig(lua) +BuildRequires: pkgconfig(lmdb) %if 0%{with crimson} || 0%{with jaeger} -BuildRequires: yaml-cpp-devel >= 0.6 +BuildRequires: pkgconfig(yaml-cpp) >= 0.6 %endif %if 0%{with amqp_endpoint} -BuildRequires: librabbitmq-devel +BuildRequires: pkgconfig(librabbitmq) %endif %if 0%{with kafka_endpoint} -BuildRequires: librdkafka-devel +%if 0%{with system_rdkafka} +BuildRequires: librdkafka-devel >= 2.11 +%else +BuildRequires: cyrus-sasl-devel +%endif %endif %if 0%{with lua_packages} Requires: lua-devel @@ -318,63 +352,60 @@ Requires: %{luarocks_package_name} %if 0%{with make_check} BuildRequires: hostname BuildRequires: jq -BuildRequires: libuuid-devel -BuildRequires: python%{python3_pkgversion}-bcrypt -BuildRequires: python%{python3_pkgversion}-requests -BuildRequires: python%{python3_pkgversion}-dateutil -BuildRequires: python%{python3_pkgversion}-coverage -BuildRequires: python%{python3_pkgversion}-pyOpenSSL +BuildRequires: pkgconfig(uuid) +BuildRequires: python3dist(bcrypt) +BuildRequires: python3dist(requests) +BuildRequires: python3dist(python-dateutil) +BuildRequires: python3dist(coverage) +BuildRequires: python3dist(pyopenssl) BuildRequires: socat -BuildRequires: python%{python3_pkgversion}-asyncssh -BuildRequires: python%{python3_pkgversion}-natsort -%endif -%if 0%{?suse_version} -BuildRequires: libthrift-devel >= 0.13.0 -%else -BuildRequires: thrift-devel >= 0.13.0 -%endif -BuildRequires: re2-devel +BuildRequires: python3dist(asyncssh) +BuildRequires: python3dist(natsort) +%if 0%{?openruyi} +BuildRequires: python3dist(cryptography) +BuildRequires: python3dist(jsonpatch) +BuildRequires: python3dist(jinja2) +BuildRequires: python3dist(werkzeug) +BuildRequires: python3dist(mypy) +BuildRequires: python3dist(pecan) +BuildRequires: python3dist(requests-mock) +BuildRequires: python3dist(kubernetes) +BuildRequires: python3dist(asyncmock) +BuildRequires: python3dist(types-pyyaml) +%endif +%endif +BuildRequires: pkgconfig(thrift) >= 0.13.0 +BuildRequires: pkgconfig(re2) +BuildRequires: pkgconfig(numa) %if 0%{with jaeger} BuildRequires: bison BuildRequires: flex -%if 0%{?fedora} || 0%{?rhel} -BuildRequires: json-devel -%endif -%if 0%{?suse_version} -BuildRequires: nlohmann_json-devel -%endif -BuildRequires: libevent-devel +BuildRequires: pkgconfig(nlohmann_json) +BuildRequires: pkgconfig(libevent) %endif %if 0%{with system_pmdk} -%if 0%{?suse_version} -BuildRequires: libndctl-devel >= 63 -%else -BuildRequires: ndctl-devel >= 63 -BuildRequires: daxctl-devel >= 63 -%endif -BuildRequires: libpmem-devel -BuildRequires: libpmemobj-devel >= 1.8 +BuildRequires: pkgconfig(libpmemobj) >= 1.8 %endif %if 0%{with system_arrow} -BuildRequires: libarrow-devel -BuildRequires: parquet-libs-devel -BuildRequires: utf8proc-devel +BuildRequires: pkgconfig(arrow) +BuildRequires: pkgconfig(parquet) +BuildRequires: pkgconfig(libutf8proc) %endif %if 0%{with system_qat} -BuildRequires: qatlib-devel -BuildRequires: qatzip-devel +BuildRequires: pkgconfig(qatlib) +BuildRequires: pkgconfig(qatzip) %endif %if 0%{with crimson} -BuildRequires: c-ares-devel -BuildRequires: gnutls-devel -BuildRequires: hwloc-devel -BuildRequires: libpciaccess-devel -BuildRequires: lksctp-tools-devel +BuildRequires: pkgconfig(libcares) +BuildRequires: pkgconfig(gnutls) +BuildRequires: pkgconfig(hwloc) +BuildRequires: pkgconfig(pciaccess) +BuildRequires: pkgconfig(libsctp) BuildRequires: ragel BuildRequires: systemtap-sdt-devel BuildRequires: libubsan BuildRequires: libasan -BuildRequires: protobuf-devel +BuildRequires: pkgconfig(protobuf) BuildRequires: protobuf-compiler %if 0%{?gts_version} > 0 BuildRequires: gcc-toolset-%{gts_version}-gcc-plugin-annobin @@ -382,6 +413,9 @@ BuildRequires: gcc-toolset-%{gts_version}-libubsan-devel BuildRequires: gcc-toolset-%{gts_version}-libasan-devel %endif %endif +BuildRequires: python3dist(prettytable) +BuildRequires: python3dist(pyyaml) +BuildRequires: python3dist(sphinx) ################################################################################# # distro-conditional dependencies ################################################################################# @@ -393,20 +427,11 @@ PreReq: %fillup_prereq BuildRequires: fdupes BuildRequires: memory-constraints BuildRequires: net-tools -BuildRequires: libbz2-devel -BuildRequires: mozilla-nss-devel -BuildRequires: keyutils-devel -BuildRequires: libopenssl-devel +BuildRequires: pkgconfig(bzip2) BuildRequires: ninja -BuildRequires: openldap2-devel #BuildRequires: krb5 #BuildRequires: krb5-devel BuildRequires: cunit-devel -BuildRequires: python%{python3_pkgversion}-PrettyTable -BuildRequires: python%{python3_pkgversion}-PyYAML -BuildRequires: python%{python3_pkgversion}-Sphinx -BuildRequires: rdma-core-devel -BuildRequires: liblz4-devel >= 1.7 # for prometheus-alerts BuildRequires: golang-github-prometheus-prometheus BuildRequires: jsonnet @@ -414,40 +439,39 @@ BuildRequires: jsonnet %if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} Requires: systemd BuildRequires: boost-random -BuildRequires: nss-devel -BuildRequires: keyutils-libs-devel BuildRequires: libatomic -BuildRequires: libibverbs-devel -BuildRequires: librdmacm-devel BuildRequires: ninja-build -BuildRequires: openldap-devel -BuildRequires: numactl-devel #BuildRequires: krb5-devel -BuildRequires: openssl-devel BuildRequires: CUnit-devel -BuildRequires: python%{python3_pkgversion}-devel -BuildRequires: python%{python3_pkgversion}-prettytable -BuildRequires: python%{python3_pkgversion}-pyyaml -BuildRequires: python%{python3_pkgversion}-sphinx -BuildRequires: lz4-devel >= 1.7 +BuildRequires: python3-devel +%endif +%if 0%{?openruyi} +BuildRequires: ninja %endif # distro-conditional make check dependencies %if 0%{with make_check} BuildRequires: golang +BuildRequires: pkgconfig(xmlsec1) +BuildRequires: pkgconfig(xmlsec1-openssl) +BuildRequires: python3dist(cherrypy) +BuildRequires: python3dist(routes) %if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} -BuildRequires: golang-github-prometheus +BuildRequires: /usr/bin/promtool BuildRequires: libtool-ltdl-devel BuildRequires: xmlsec1 -BuildRequires: xmlsec1-devel %ifarch x86_64 BuildRequires: xmlsec1-nss %endif BuildRequires: xmlsec1-openssl -BuildRequires: xmlsec1-openssl-devel -BuildRequires: python%{python3_pkgversion}-cherrypy -BuildRequires: python%{python3_pkgversion}-routes -BuildRequires: python%{python3_pkgversion}-scipy -BuildRequires: python%{python3_pkgversion}-pyOpenSSL +BuildRequires: python3dist(scipy) +BuildRequires: python3dist(pyopenssl) +%endif +%if 0%{?openruyi} +BuildRequires: /usr/bin/promtool +BuildRequires: python3dist(scipy) +BuildRequires: python3dist(numpy) +BuildRequires: python3dist(tox) +BuildRequires: python3dist(pyfakefs) %endif BuildRequires: jsonnet %if 0%{?suse_version} @@ -455,30 +479,15 @@ BuildRequires: golang-github-prometheus-prometheus BuildRequires: libxmlsec1-1 BuildRequires: libxmlsec1-nss1 BuildRequires: libxmlsec1-openssl1 -BuildRequires: python%{python3_pkgversion}-CherryPy -BuildRequires: python%{python3_pkgversion}-Routes -BuildRequires: python%{python3_pkgversion}-numpy-devel -BuildRequires: xmlsec1-devel -BuildRequires: xmlsec1-openssl-devel +BuildRequires: python3-numpy-devel %endif %endif # lttng and babeltrace for rbd-replay-prep %if %{with lttng} -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} -BuildRequires: lttng-ust-devel -BuildRequires: libbabeltrace-devel -%endif -%if 0%{?suse_version} -BuildRequires: lttng-ust-devel -BuildRequires: babeltrace-devel -%endif -%endif -%if 0%{?suse_version} -BuildRequires: libexpat-devel -%endif -%if 0%{?rhel} || 0%{?fedora} || 0%{?openEuler} -BuildRequires: expat-devel +BuildRequires: pkgconfig(lttng-ust) +BuildRequires: pkgconfig(babeltrace) %endif +BuildRequires: pkgconfig(expat) #hardened-cc1 %if 0%{?fedora} || 0%{?rhel} BuildRequires: redhat-rpm-config @@ -487,15 +496,12 @@ BuildRequires: redhat-rpm-config BuildRequires: openEuler-rpm-config %endif %if 0%{with crimson} -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} -BuildRequires: cryptopp-devel -%endif -%if 0%{?suse_version} -BuildRequires: libcryptopp-devel -BuildRequires: libnuma-devel +# EPEL9's cryptopp-devel ships its pkgconfig file as cryptopp.pc (providing +# pkgconfig(cryptopp)), while el10 and SUSE's cryptopp/libcryptopp-devel +# provide pkgconfig(libcryptopp); accept either. +BuildRequires: (pkgconfig(libcryptopp) or pkgconfig(cryptopp)) %endif -%endif -%if 0%{?rhel} >= 9 +%if 0%{?rhel} BuildRequires: python-rpm-macros %endif @@ -527,13 +533,6 @@ Requires: logrotate Requires: psmisc Requires: util-linux Requires: which -%if 0%{?rhel} && 0%{?rhel} < 8 -# The following is necessary due to tracker 36508 and can be removed once the -# associated upstream bugs are resolved. -%if 0%{with tcmalloc} -Requires: gperftools-libs >= 2.6.1 -%endif -%endif %if 0%{?weak_deps} Recommends: chrony Recommends: nvme-cli @@ -550,19 +549,32 @@ Base is the package that includes all the files shared amongst ceph servers Summary: Utility to bootstrap Ceph clusters BuildArch: noarch Requires: lvm2 -Requires: python%{python3_pkgversion} +Requires: python3 Requires: openssh-server Requires: which %if 0%{?weak_deps} Recommends: podman >= 2.0.2 %endif +# Cephadm zipapp: CMake sets CEPHADM_BUNDLED_DEPENDENCIES to pip, rpm, or none +# (see build / cmake block below): +# - with cephadm_bundling, with cephadm_pip_deps: pip at build, no stanzas here +# - with cephadm_bundling, without cephadm_pip_deps: build-time RPM deps only +# - without cephadm_bundling: unbundled cephadm, runtime Requires for yaml/jinja2 +# CentOS Storage SIG #75389 needs the unbundled branch (--without cephadm_bundling) +# after dropping downstream patch 0036; pip-mode SIG builds are a separate SIG fix. %if 0%{with cephadm_bundling} %if 0%{without cephadm_pip_deps} -BuildRequires: python3-jinja2 >= 2.10 +# Zipapp built from system RPMs at build time; bundled zipapp is self-contained at runtime. +BuildRequires: python3dist(jinja2) >= 2.10 +BuildRequires: python3dist(pyyaml) %endif +%dnl end without cephadm_pip_deps (CEPHADM_BUNDLED_DEPENDENCIES=rpm) %else -Requires: python3-jinja2 >= 2.10 +# Unbundled cephadm: host must provide yaml and jinja2 at runtime. +Requires: python3dist(jinja2) >= 2.10 +Requires: python3dist(pyyaml) %endif +%dnl end with cephadm_bundling %description -n cephadm Utility to bootstrap a Ceph cluster and manage Ceph daemons deployed with systemd and podman. @@ -575,18 +587,13 @@ Group: System/Filesystems Requires: librbd1 = %{_epoch_prefix}%{version}-%{release} Requires: librados2 = %{_epoch_prefix}%{version}-%{release} Requires: libcephfs2 = %{_epoch_prefix}%{version}-%{release} -Requires: python%{python3_pkgversion}-rados = %{_epoch_prefix}%{version}-%{release} -Requires: python%{python3_pkgversion}-rbd = %{_epoch_prefix}%{version}-%{release} -Requires: python%{python3_pkgversion}-cephfs = %{_epoch_prefix}%{version}-%{release} -Requires: python%{python3_pkgversion}-rgw = %{_epoch_prefix}%{version}-%{release} -Requires: python%{python3_pkgversion}-ceph-argparse = %{_epoch_prefix}%{version}-%{release} -Requires: python%{python3_pkgversion}-ceph-common = %{_epoch_prefix}%{version}-%{release} -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} -Requires: python%{python3_pkgversion}-prettytable -%endif -%if 0%{?suse_version} -Requires: python%{python3_pkgversion}-PrettyTable -%endif +Requires: python3-rados = %{_epoch_prefix}%{version}-%{release} +Requires: python3-rbd = %{_epoch_prefix}%{version}-%{release} +Requires: python3-cephfs = %{_epoch_prefix}%{version}-%{release} +Requires: python3-rgw = %{_epoch_prefix}%{version}-%{release} +Requires: python3-ceph-argparse = %{_epoch_prefix}%{version}-%{release} +Requires: python3-ceph-common = %{_epoch_prefix}%{version}-%{release} +Requires: python3dist(prettytable) %if 0%{with libradosstriper} Requires: libradosstriper1 = %{_epoch_prefix}%{version}-%{release} %endif @@ -642,11 +649,30 @@ Requires: ceph-base = %{_epoch_prefix}%{version}-%{release} Requires: ceph-mgr-modules-core = %{_epoch_prefix}%{version}-%{release} Requires: libcephsqlite = %{_epoch_prefix}%{version}-%{release} %if 0%{?weak_deps} +Recommends: ceph-mgr-alerts = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-cephadm = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-cli-api = %{_epoch_prefix}%{version}-%{release} Recommends: ceph-mgr-dashboard = %{_epoch_prefix}%{version}-%{release} Recommends: ceph-mgr-diskprediction-local = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-influx = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-insights = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-iostat = %{_epoch_prefix}%{version}-%{release} Recommends: ceph-mgr-k8sevents = %{_epoch_prefix}%{version}-%{release} -Recommends: ceph-mgr-cephadm = %{_epoch_prefix}%{version}-%{release} -Recommends: python%{python3_pkgversion}-influxdb +Recommends: ceph-mgr-localpool = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-mds-autoscaler = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-mirroring = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-nfs = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-nvmeof = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-osd-perf-query = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-osd-support = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-prometheus = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-rgw = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-selftest = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-smb = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-snap-schedule = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-stats = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-telegraf = %{_epoch_prefix}%{version}-%{release} +Recommends: ceph-mgr-test-orchestrator = %{_epoch_prefix}%{version}-%{release} %endif %description mgr ceph-mgr enables python modules that provide services (such as the REST @@ -661,30 +687,24 @@ BuildArch: noarch Group: System/Filesystems %endif Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-smb = %{_epoch_prefix}%{version}-%{release} Requires: ceph-grafana-dashboards = %{_epoch_prefix}%{version}-%{release} Requires: ceph-prometheus-alerts = %{_epoch_prefix}%{version}-%{release} -%if 0%{?fedora} || 0%{?rhel} >= 9 -Requires: python%{python3_pkgversion}-grpcio -Requires: python%{python3_pkgversion}-grpcio-tools -Requires: python%{python3_pkgversion}-jmespath -Requires: python%{python3_pkgversion}-xmltodict -%endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} -Requires: python%{python3_pkgversion}-cherrypy -Requires: python%{python3_pkgversion}-routes +%if 0%{?fedora} || 0%{?rhel} || 0%{?openruyi} +Requires: python3dist(grpcio) +Requires: python3dist(grpcio-tools) +Requires: python3dist(jmespath) +Requires: python3dist(xmltodict) +%endif +Requires: python3dist(cherrypy) +Requires: python3dist(routes) %if 0%{?weak_deps} -Recommends: python%{python3_pkgversion}-saml -%if 0%{?fedora} || 0%{?rhel} <= 8 -Recommends: python%{python3_pkgversion}-grpcio -Recommends: python%{python3_pkgversion}-grpcio-tools +Recommends: python3dist(python3-saml) +%if 0%{?fedora} +Recommends: python3dist(grpcio) +Recommends: python3dist(grpcio-tools) %endif %endif -%endif -%if 0%{?suse_version} -Requires: python%{python3_pkgversion}-CherryPy -Requires: python%{python3_pkgversion}-Routes -Recommends: python%{python3_pkgversion}-python3-saml -%endif %description mgr-dashboard ceph-mgr-dashboard is a manager module, providing a web-based application to monitor and manage many aspects of a Ceph cluster and related components. @@ -698,11 +718,11 @@ BuildArch: noarch Group: System/Filesystems %endif Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} -Requires: python%{python3_pkgversion}-numpy -%if 0%{?fedora} || 0%{?suse_version} || 0%{?openEuler} -Requires: python%{python3_pkgversion}-scikit-learn +Requires: python3dist(numpy) +%if 0%{?fedora} || 0%{?suse_version} || 0%{?openEuler} || 0%{?openruyi} +Requires: python3dist(scikit-learn) %endif -Requires: python3-scipy +Requires: python3dist(scipy) %description mgr-diskprediction-local ceph-mgr-diskprediction-local is a ceph-mgr module that tries to predict disk failures using local algorithms and machine-learning databases. @@ -713,25 +733,10 @@ BuildArch: noarch %if 0%{?suse_version} Group: System/Filesystems %endif -Requires: python%{python3_pkgversion}-bcrypt -Requires: python%{python3_pkgversion}-packaging -Requires: python%{python3_pkgversion}-pyOpenSSL -Requires: python%{python3_pkgversion}-requests -Requires: python%{python3_pkgversion}-dateutil -Requires: python%{python3_pkgversion}-setuptools -%if 0%{?fedora} || 0%{?rhel} >= 8 || 0%{?openEuler} -Requires: python%{python3_pkgversion}-cherrypy -Requires: python%{python3_pkgversion}-pyyaml -%endif -%if 0%{?suse_version} -Requires: python%{python3_pkgversion}-CherryPy -Requires: python%{python3_pkgversion}-PyYAML -%endif -# RHEL8 has python 3.6 and that lacks dataclasses in the stdlib, so pull in the -# backport dataclasses module instead. -%if 0%{?rhel} <= 8 -Requires: python%{python3_pkgversion}-dataclasses -%endif +Requires: python3dist(prettytable) +Requires: python3dist(requests) +Requires: python3dist(python-dateutil) +Requires: python3dist(pyyaml) %if 0%{?weak_deps} Recommends: ceph-mgr-rook = %{_epoch_prefix}%{version}-%{release} %endif @@ -739,6 +744,38 @@ Recommends: ceph-mgr-rook = %{_epoch_prefix}%{version}-%{release} ceph-mgr-modules-core provides a set of modules which are always enabled by ceph-mgr. +%package mgr-modules-standard +BuildArch: noarch +Summary: Ceph Manager modules without heavy external dependencies +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr-modules-core = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-alerts = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-influx = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-insights = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-iostat = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-localpool = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-mds-autoscaler = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-mirroring = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-nfs = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-nvmeof = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-osd-perf-query = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-osd-support = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-prometheus = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-rgw = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-selftest = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-smb = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-snap-schedule = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-stats = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-telegraf = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-test-orchestrator = %{_epoch_prefix}%{version}-%{release} +%description mgr-modules-standard +ceph-mgr-modules-standard is a meta-package with no files of its own. +It pulls in the full set of ceph-mgr modules that were formerly shipped +together in ceph-mgr-modules-core, so that existing users or scripts +that want the complete standard module set can depend on a single package. + %package mgr-rook BuildArch: noarch Summary: Ceph Manager module for Rook-based orchestration @@ -746,8 +783,9 @@ Summary: Ceph Manager module for Rook-based orchestration Group: System/Filesystems %endif Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} -Requires: python%{python3_pkgversion}-kubernetes -Requires: python%{python3_pkgversion}-jsonpatch +Requires: ceph-mgr-nfs = %{_epoch_prefix}%{version}-%{release} +Requires: python3dist(kubernetes) +Requires: python3dist(jsonpatch) %description mgr-rook ceph-mgr-rook is a ceph-mgr module for orchestration functions using a Rook backend. @@ -759,7 +797,7 @@ Summary: Ceph Manager module to orchestrate ceph-events to kubernetes' ev Group: System/Filesystems %endif Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} -Requires: python%{python3_pkgversion}-kubernetes +Requires: python3dist(kubernetes) %description mgr-k8sevents ceph-mgr-k8sevents is a ceph-mgr module that sends every ceph-events to kubernetes' events API @@ -771,30 +809,276 @@ BuildArch: noarch Group: System/Filesystems %endif Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} -Requires: python%{python3_pkgversion}-asyncssh -Requires: python%{python3_pkgversion}-natsort +Requires: ceph-mgr-nfs = %{_epoch_prefix}%{version}-%{release} +Requires: ceph-mgr-smb = %{_epoch_prefix}%{version}-%{release} +Requires: python3dist(asyncssh) +Requires: python3dist(bcrypt) +Requires: python3dist(natsort) +Requires: python3dist(pyopenssl) Requires: cephadm = %{_epoch_prefix}%{version}-%{release} +Requires: python3dist(cherrypy) +Requires: python3dist(jinja2) %if 0%{?suse_version} Requires: openssh -Requires: python%{python3_pkgversion}-CherryPy -Requires: python%{python3_pkgversion}-Jinja2 %endif -%if 0%{?rhel} || 0%{?fedora} || 0%{?openEuler} +%if 0%{?rhel} || 0%{?fedora} || 0%{?openEuler} || 0%{?openruyi} Requires: openssh-clients -Requires: python%{python3_pkgversion}-cherrypy -Requires: python%{python3_pkgversion}-jinja2 %endif %description mgr-cephadm ceph-mgr-cephadm is a ceph-mgr module for orchestration functions using the integrated cephadm deployment tool management operations. +%package mgr-cli-api +BuildArch: noarch +Summary: Ceph Manager module providing a CLI REST API +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +%description mgr-cli-api +ceph-mgr-cli-api is a ceph-mgr module that provides a REST-like API +for the Ceph command-line interface. + +%package mgr-alerts +BuildArch: noarch +Summary: Ceph Manager module for sending alerts on health state changes +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +%description mgr-alerts +ceph-mgr-alerts is a ceph-mgr module that sends email notifications +on cluster health state changes. + +%package mgr-influx +BuildArch: noarch +Summary: Ceph Manager module for sending metrics to InfluxDB +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +%if 0%{?weak_deps} +Recommends: python3dist(influxdb) +%endif +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +%description mgr-influx +ceph-mgr-influx is a ceph-mgr module that sends performance metrics +to an InfluxDB time-series database. + +%package mgr-insights +BuildArch: noarch +Summary: Ceph Manager module for recording cluster health history +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +%description mgr-insights +ceph-mgr-insights is a ceph-mgr module that records cluster health +history to support cluster analysis. + +%package mgr-iostat +BuildArch: noarch +Summary: Ceph Manager module for displaying I/O statistics +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +%description mgr-iostat +ceph-mgr-iostat is a ceph-mgr module that displays a running summary +of I/O statistics across the cluster. + +%package mgr-localpool +BuildArch: noarch +Summary: Ceph Manager module for creating per-host CRUSH rules and pools +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +%description mgr-localpool +ceph-mgr-localpool is a ceph-mgr module that automatically creates +per-host CRUSH rules and pools. + +%package mgr-mds-autoscaler +BuildArch: noarch +Summary: Ceph Manager module for automatically scaling MDS daemons +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +%description mgr-mds-autoscaler +ceph-mgr-mds-autoscaler is a ceph-mgr module that automatically scales +the number of MDS daemons based on file system needs. + +%package mgr-mirroring +BuildArch: noarch +Summary: Ceph Manager module for managing CephFS mirroring +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +%description mgr-mirroring +ceph-mgr-mirroring is a ceph-mgr module that provides management +commands for CephFS mirroring. + +%package mgr-nfs +BuildArch: noarch +Summary: Ceph Manager module for managing NFS gateway deployments +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +%description mgr-nfs +ceph-mgr-nfs is a ceph-mgr module that manages NFS gateway deployments +on top of CephFS and RGW. + +%package mgr-nvmeof +BuildArch: noarch +Summary: Ceph Manager module for managing NVMe-oF gateway deployments +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +%description mgr-nvmeof +ceph-mgr-nvmeof is a ceph-mgr module that manages NVMe-oF gateway +deployments for Ceph RBD. + +%package mgr-osd-perf-query +BuildArch: noarch +Summary: Ceph Manager module for OSD performance counter queries +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Requires: python3dist(prettytable) +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +%description mgr-osd-perf-query +ceph-mgr-osd-perf-query is a ceph-mgr module that exposes OSD +performance counter query functionality. + +%package mgr-osd-support +BuildArch: noarch +Summary: Ceph Manager module for additional OSD management commands +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +%description mgr-osd-support +ceph-mgr-osd-support is a ceph-mgr module that provides additional +OSD management commands. + +%package mgr-prometheus +BuildArch: noarch +Summary: Ceph Manager module for exposing metrics to Prometheus +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +Requires: python3dist(cherrypy) +%description mgr-prometheus +ceph-mgr-prometheus is a ceph-mgr module that exposes cluster metrics +in Prometheus exposition format. + +%package mgr-rgw +BuildArch: noarch +Summary: Ceph Manager module for RADOS Gateway management +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +%description mgr-rgw +ceph-mgr-rgw is a ceph-mgr module that provides management and status +commands for the RADOS Gateway. + +%package mgr-selftest +BuildArch: noarch +Summary: Ceph Manager module for testing the manager framework +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +%description mgr-selftest +ceph-mgr-selftest is a ceph-mgr module used for testing the manager +framework. + +%package mgr-smb +BuildArch: noarch +Summary: Ceph Manager module for managing SMB gateway deployments +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +%description mgr-smb +ceph-mgr-smb is a ceph-mgr module that manages SMB gateway +deployments on Ceph. + +%package mgr-snap-schedule +BuildArch: noarch +Summary: Ceph Manager module for automated CephFS snapshot schedules +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +%description mgr-snap-schedule +ceph-mgr-snap-schedule is a ceph-mgr module that manages automated +CephFS snapshot schedules. + +%package mgr-stats +BuildArch: noarch +Summary: Ceph Manager module for exposing file system client I/O statistics +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +%description mgr-stats +ceph-mgr-stats is a ceph-mgr module that exposes file system client +I/O statistics. + +%package mgr-telegraf +BuildArch: noarch +Summary: Ceph Manager module for sending metrics to Telegraf +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +%description mgr-telegraf +ceph-mgr-telegraf is a ceph-mgr module that sends performance metrics +to a Telegraf agent. + +%package mgr-test-orchestrator +BuildArch: noarch +Summary: Ceph Manager module for testing the orchestrator framework +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-mgr-modules-core < %{_epoch_prefix}%{version}-%{release} +%description mgr-test-orchestrator +ceph-mgr-test-orchestrator is a ceph-mgr module used for testing the +orchestrator framework. + %package fuse Summary: Ceph fuse-based client %if 0%{?suse_version} Group: System/Filesystems %endif Requires: fuse3 -Requires: python%{python3_pkgversion} +Requires: python3 %description fuse FUSE based client for Ceph distributed network file system @@ -877,16 +1161,32 @@ Requires: mailcap %if 0%{?weak_deps} Recommends: gawk %endif +%if 0%{with kafka_endpoint} && !0%{with system_rdkafka} +Provides: bundled(librdkafka) = 2.12.1 +%endif %description radosgw RADOS is a distributed object store used by the Ceph distributed storage system. This package provides a REST gateway to the object store that aims to implement a superset of Amazon's S3 service as well as the OpenStack Object Storage ("Swift") API. +%package rgw-standalone +Summary: Rados REST gateway for filesystems +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Conflicts: ceph-common +Conflicts: radosgw +%description rgw-standalone +This package provides an Object REST gateway (S3 and Swift) on +top of a filesystem that aims to implement a superset of Amazon's S3 +service as well as the OpenStack Object Storage ("Swift") API. +It does not require or provide any of the rest of the Ceph services. + %package -n cephfs-top Summary: top(1) like utility for Ceph Filesystem BuildArch: noarch -Requires: python%{python3_pkgversion}-rados +Requires: python3-rados %description -n cephfs-top This package provides a top(1) like utility to display Ceph Filesystem metrics in realtime. @@ -912,7 +1212,10 @@ Summary: Ceph Object Storage Daemon Group: System/Filesystems %endif Requires: ceph-base = %{_epoch_prefix}%{version}-%{release} -Requires: (ceph-osd-classic = %{_epoch_prefix}%{version}-%{release} or ceph-osd-crimson = %{_epoch_prefix}%{version}-%{release}) +Requires: ceph-osd-classic = %{_epoch_prefix}%{version}-%{release} +%if 0%{with crimson} +Requires: ceph-osd-crimson = %{_epoch_prefix}%{version}-%{release} +%endif Requires: sudo Requires: libstoragemgmt %if 0%{?weak_deps} @@ -930,6 +1233,9 @@ Summary: Ceph Object Storage Daemon (classic) Group: System/Filesystems %endif Requires: ceph-osd = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-osd < %{_epoch_prefix}%{version}-%{release} +Requires(posttrans): %{_sbindir}/update-alternatives +Requires(preun): %{_sbindir}/update-alternatives %description osd-classic classic-osd is the object storage daemon for the Ceph distributed file system. It is responsible for storing objects on a local file system @@ -942,8 +1248,16 @@ Summary: Ceph Object Storage Daemon (crimson) Group: System/Filesystems %endif Requires: ceph-osd = %{_epoch_prefix}%{version}-%{release} +Obsoletes: ceph-osd < %{_epoch_prefix}%{version}-%{release} Requires: binutils +# libcares.so.2 doesn't carry the version, and only EL crosses 1.28 between a +# rolling builder and a frozen older minor, so pin the c-ares floor there. +%if 0%{?rhel} >= 10 +Requires: c-ares%{?_isa} >= %{c_ares_min_version} +%endif Requires: protobuf +Requires(posttrans): %{_sbindir}/update-alternatives +Requires(preun): %{_sbindir}/update-alternatives %description osd-crimson crimson-osd is the object storage daemon for the Ceph distributed file system. It is responsible for storing objects on a local file system @@ -963,8 +1277,8 @@ Requires: lvm2 Requires: parted Requires: util-linux Requires: xfsprogs -Requires: python%{python3_pkgversion}-setuptools -Requires: python%{python3_pkgversion}-ceph-common = %{_epoch_prefix}%{version}-%{release} +Requires: python3-setuptools +Requires: python3-ceph-common = %{_epoch_prefix}%{version}-%{release} %description volume This package contains a tool to deploy OSD with different devices like lvm or physical disks, and trying to follow a predictable, and robust @@ -1031,31 +1345,31 @@ Obsoletes: librgw2-devel < %{_epoch_prefix}%{version}-%{release} This package contains libraries and headers needed to develop programs that use RADOS gateway client library. -%package -n python%{python3_pkgversion}-rgw +%package -n python3-rgw Summary: Python 3 libraries for the RADOS gateway %if 0%{?suse_version} Group: Development/Libraries/Python %endif Requires: librgw2 = %{_epoch_prefix}%{version}-%{release} -Requires: python%{python3_pkgversion}-rados = %{_epoch_prefix}%{version}-%{release} -%{?python_provide:%python_provide python%{python3_pkgversion}-rgw} +Requires: python3-rados = %{_epoch_prefix}%{version}-%{release} +%{?python_provide:%python_provide python3-rgw} Provides: python-rgw = %{_epoch_prefix}%{version}-%{release} Obsoletes: python-rgw < %{_epoch_prefix}%{version}-%{release} -%description -n python%{python3_pkgversion}-rgw +%description -n python3-rgw This package contains Python 3 libraries for interacting with Ceph RADOS gateway. -%package -n python%{python3_pkgversion}-rados +%package -n python3-rados Summary: Python 3 libraries for the RADOS object store %if 0%{?suse_version} Group: Development/Libraries/Python %endif -Requires: python%{python3_pkgversion} +Requires: python3 Requires: librados2 = %{_epoch_prefix}%{version}-%{release} -%{?python_provide:%python_provide python%{python3_pkgversion}-rados} +%{?python_provide:%python_provide python3-rados} Provides: python-rados = %{_epoch_prefix}%{version}-%{release} Obsoletes: python-rados < %{_epoch_prefix}%{version}-%{release} -%description -n python%{python3_pkgversion}-rados +%description -n python3-rados This package contains Python 3 libraries for interacting with Ceph RADOS object store. @@ -1146,17 +1460,17 @@ Obsoletes: librbd1-devel < %{_epoch_prefix}%{version}-%{release} This package contains libraries and headers needed to develop programs that use RADOS block device. -%package -n python%{python3_pkgversion}-rbd +%package -n python3-rbd Summary: Python 3 libraries for the RADOS block device %if 0%{?suse_version} Group: Development/Libraries/Python %endif Requires: librbd1 = %{_epoch_prefix}%{version}-%{release} -Requires: python%{python3_pkgversion}-rados = %{_epoch_prefix}%{version}-%{release} -%{?python_provide:%python_provide python%{python3_pkgversion}-rbd} +Requires: python3-rados = %{_epoch_prefix}%{version}-%{release} +%{?python_provide:%python_provide python3-rbd} Provides: python-rbd = %{_epoch_prefix}%{version}-%{release} Obsoletes: python-rbd < %{_epoch_prefix}%{version}-%{release} -%description -n python%{python3_pkgversion}-rbd +%description -n python3-rbd This package contains Python 3 libraries for interacting with Ceph RADOS block device. @@ -1212,55 +1526,55 @@ Obsoletes: libcephfs2-devel < %{_epoch_prefix}%{version}-%{release} This package contains libraries and headers needed to develop programs that use Ceph distributed file system. -%package -n python%{python3_pkgversion}-cephfs +%package -n python3-cephfs Summary: Python 3 libraries for Ceph distributed file system %if 0%{?suse_version} Group: Development/Libraries/Python %endif Requires: libcephfs2 = %{_epoch_prefix}%{version}-%{release} -Requires: python%{python3_pkgversion}-rados = %{_epoch_prefix}%{version}-%{release} -Requires: python%{python3_pkgversion}-ceph-argparse = %{_epoch_prefix}%{version}-%{release} -%{?python_provide:%python_provide python%{python3_pkgversion}-cephfs} +Requires: python3-rados = %{_epoch_prefix}%{version}-%{release} +Requires: python3-ceph-argparse = %{_epoch_prefix}%{version}-%{release} +%{?python_provide:%python_provide python3-cephfs} Provides: python-cephfs = %{_epoch_prefix}%{version}-%{release} Obsoletes: python-cephfs < %{_epoch_prefix}%{version}-%{release} -%description -n python%{python3_pkgversion}-cephfs +%description -n python3-cephfs This package contains Python 3 libraries for interacting with Ceph distributed file system. -%package -n python%{python3_pkgversion}-ceph-argparse +%package -n python3-ceph-argparse Summary: Python 3 utility libraries for Ceph CLI %if 0%{?suse_version} Group: Development/Libraries/Python %endif -%{?python_provide:%python_provide python%{python3_pkgversion}-ceph-argparse} -%description -n python%{python3_pkgversion}-ceph-argparse +%{?python_provide:%python_provide python3-ceph-argparse} +%description -n python3-ceph-argparse This package contains types and routines for Python 3 used by the Ceph CLI as well as the RESTful interface. These have to do with querying the daemons for command-description information, validating user command input against those descriptions, and submitting the command to the appropriate daemon. -%package -n python%{python3_pkgversion}-ceph-common +%package -n python3-ceph-common Summary: Python 3 utility libraries for Ceph -%if 0%{?fedora} || 0%{?rhel} >= 8 || 0%{?openEuler} -Requires: python%{python3_pkgversion}-pyyaml +Requires: python3dist(pyyaml) +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if %{with pypkg} +Recommends: python3-ceph-smb-ctl %endif -%if 0%{?suse_version} -Requires: python%{python3_pkgversion}-PyYAML %endif %if 0%{?suse_version} Group: Development/Libraries/Python %endif -%{?python_provide:%python_provide python%{python3_pkgversion}-ceph-common} -%description -n python%{python3_pkgversion}-ceph-common +%{?python_provide:%python_provide python3-ceph-common} +%description -n python3-ceph-common This package contains data structures, classes and functions used by Ceph. It also contains utilities used for the cephadm orchestrator. %if 0%{with cephfs_shell} %package -n cephfs-shell Summary: Interactive shell for Ceph file system -Requires: python%{python3_pkgversion}-cmd2 -Requires: python%{python3_pkgversion}-colorama -Requires: python%{python3_pkgversion}-cephfs +Requires: python3dist(cmd2) +Requires: python3dist(colorama) +Requires: python3-cephfs %description -n cephfs-shell This package contains an interactive tool that allows accessing a Ceph file system without mounting it by providing a nice pseudo-shell which @@ -1389,6 +1703,22 @@ Group: System/Monitoring %description node-proxy This package provides a Ceph hardware monitoring agent. +%if %{with pypkg} +%package -n python3-ceph-smb-ctl +Summary: Ceph SMB Service Remote-Control Client +BuildArch: noarch +%if 0%{?suse_version} +Group: System/Filesystems +%endif +Requires: python3-ceph-common = %{_epoch_prefix}%{version}-%{release} +Requires: python3dist(grpcio) +Requires: python3dist(grpcio-reflection) +%description -n python3-ceph-smb-ctl +This package provides a tool to interact with Ceph's SMB Service Remote-Control +gRPC API as a client. +%endif +%dnl end package python3-ceph-smb-ctl + ################################################################################# # common ################################################################################# @@ -1506,6 +1836,9 @@ cmake .. \ %if 0%{with system_pmdk} -DWITH_SYSTEM_PMDK:BOOL=ON \ %endif +%if 0%{with system_rdkafka} + -DWITH_SYSTEM_RDKAFKA:BOOL=ON \ +%endif %if 0%{without jaeger} -DWITH_JAEGER:BOOL=OFF \ %endif @@ -1533,6 +1866,9 @@ cmake .. \ %if %{with sccache} -DWITH_SCCACHE=ON \ %endif +%if 0%{with pypkg} + -DWITH_PYPKG:BOOL=ON \ +%endif %if 0%{with cephadm_bundling} %if 0%{with cephadm_pip_deps} -DCEPHADM_BUNDLED_DEPENDENCIES=pip @@ -1558,6 +1894,9 @@ popd %if 0%{with make_check} %check +%if 0%{?openruyi} +export CEPH_PYTHON_SYSTEM_SITE=true +%endif # run in-tree unittests pushd %{_vpath_builddir} ctest %{_smp_mflags} @@ -1579,7 +1918,7 @@ mv %{buildroot}%{_bindir}/crimson-osd %{buildroot}%{_bindir}/ceph-osd-crimson mv %{buildroot}%{_bindir}/ceph-osd %{buildroot}%{_bindir}/ceph-osd-classic install -m 0644 -D src/etc-rbdmap %{buildroot}%{_sysconfdir}/ceph/rbdmap -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} install -m 0644 -D etc/sysconfig/ceph %{buildroot}%{_sysconfdir}/sysconfig/ceph %endif %if 0%{?suse_version} @@ -1613,7 +1952,10 @@ install -m 0644 -D udev/50-rbd.rules %{buildroot}%{_udevrulesdir}/50-rbd.rules # sudoers.d install -m 0440 -D sudoers.d/ceph-smartctl %{buildroot}%{_sysconfdir}/sudoers.d/ceph-smartctl -%if 0%{?rhel} >= 8 || 0%{?openEuler} +%if 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} +# Undefine -P flag as it is only supported with python version >= 3.11 +%undefine _py3_shebang_P + %{py3_shebang_fix} %{buildroot}%{_bindir}/* %{buildroot}%{_sbindir}/* %endif @@ -1652,7 +1994,7 @@ install -m 644 -D -t %{buildroot}%{_datadir}/snmp/mibs monitoring/snmp/CEPH-MIB. %fdupes %{buildroot}%{_prefix} %endif -%if 0%{?rhel} == 8 || 0%{?openEuler} +%if 0%{?openEuler} %py_byte_compile %{__python3} %{buildroot}%{python3_sitelib} %endif @@ -1696,7 +2038,7 @@ rm -rf %{_vpath_builddir} %{_libdir}/libmgr_op_tp.so* %endif %config(noreplace) %{_sysconfdir}/logrotate.d/ceph -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %config(noreplace) %{_sysconfdir}/sysconfig/ceph %endif %if 0%{?suse_version} @@ -1729,7 +2071,7 @@ if [ $1 -eq 1 ] ; then /usr/bin/systemctl preset ceph.target ceph-crash.service >/dev/null 2>&1 || : fi %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_post ceph.target ceph-crash.service %endif if [ $1 -eq 1 ] ; then @@ -1740,7 +2082,7 @@ fi %if 0%{?suse_version} %service_del_preun ceph.target ceph-crash.service %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_preun ceph.target ceph-crash.service %endif @@ -1760,6 +2102,7 @@ exit 0 %files -n cephadm %{_sbindir}/cephadm +%attr(0700,root,root) %{_libexecdir}/cephadm_invoker.py %{_mandir}/man8/cephadm.8* %attr(0700,cephadm,cephadm) %dir %{_sharedstatedir}/cephadm %attr(0700,cephadm,cephadm) %dir %{_sharedstatedir}/cephadm/.ssh @@ -1773,11 +2116,13 @@ exit 0 %{_bindir}/ceph-authtool %{_bindir}/ceph-conf %{_bindir}/ceph-dencoder +%{_bindir}/ceph-diff-sorted %{_bindir}/ceph-rbdnamer %{_bindir}/ceph-syn %{_bindir}/cephfs-data-scan %{_bindir}/cephfs-journal-tool %{_bindir}/cephfs-table-tool +%{_bindir}/cephfs-tool %{_bindir}/crushdiff %{_bindir}/rados %{_bindir}/radosgw-admin @@ -1839,7 +2184,7 @@ exit 0 %pre common CEPH_GROUP_ID=167 CEPH_USER_ID=167 -%if 0%{?rhel} || 0%{?fedora} || 0%{?openEuler} +%if 0%{?rhel} || 0%{?fedora} || 0%{?openEuler} || 0%{?openruyi} /usr/sbin/groupadd ceph -g $CEPH_GROUP_ID -o -r 2>/dev/null || : /usr/sbin/useradd ceph -u $CEPH_USER_ID -o -r -g ceph -s /sbin/nologin -c "Ceph daemons" -d %{_localstatedir}/lib/ceph 2>/dev/null || : %endif @@ -1878,7 +2223,7 @@ if [ $1 -eq 1 ] ; then /usr/bin/systemctl preset ceph-mds@\*.service ceph-mds.target >/dev/null 2>&1 || : fi %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_post ceph-mds@\*.service ceph-mds.target %endif if [ $1 -eq 1 ] ; then @@ -1889,7 +2234,7 @@ fi %if 0%{?suse_version} %service_del_preun ceph-mds@\*.service ceph-mds.target %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_preun ceph-mds@\*.service ceph-mds.target %endif @@ -1913,6 +2258,9 @@ fi %{_datadir}/ceph/mgr/mgr_module.* %{_datadir}/ceph/mgr/mgr_util.* %{_datadir}/ceph/mgr/object_format.* +%{_datadir}/ceph/mgr/ceph_secrets_client.* +%{_datadir}/ceph/mgr/ceph_secrets_types.* +%{_datadir}/ceph/mgr/cherrypy_mgr.* %{_unitdir}/ceph-mgr@.service %{_unitdir}/ceph-mgr.target %attr(750,ceph,ceph) %dir %{_localstatedir}/lib/ceph/mgr @@ -1923,7 +2271,7 @@ if [ $1 -eq 1 ] ; then /usr/bin/systemctl preset ceph-mgr@\*.service ceph-mgr.target >/dev/null 2>&1 || : fi %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_post ceph-mgr@\*.service ceph-mgr.target %endif if [ $1 -eq 1 ] ; then @@ -1934,7 +2282,7 @@ fi %if 0%{?suse_version} %service_del_preun ceph-mgr@\*.service ceph-mgr.target %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_preun ceph-mgr@\*.service ceph-mgr.target %endif @@ -1955,98 +2303,142 @@ fi %files mgr-dashboard %{_datadir}/ceph/mgr/dashboard -%post mgr-dashboard -if [ $1 -eq 1 ] ; then - /usr/bin/systemctl try-restart ceph-mgr.target >/dev/null 2>&1 || : -fi - -%postun mgr-dashboard -if [ $1 -eq 1 ] ; then - /usr/bin/systemctl try-restart ceph-mgr.target >/dev/null 2>&1 || : -fi +%ceph_mgr_module_scripts mgr-dashboard %files mgr-diskprediction-local %{_datadir}/ceph/mgr/diskprediction_local -%post mgr-diskprediction-local -if [ $1 -eq 1 ] ; then - /usr/bin/systemctl try-restart ceph-mgr.target >/dev/null 2>&1 || : -fi - -%postun mgr-diskprediction-local -if [ $1 -eq 1 ] ; then - /usr/bin/systemctl try-restart ceph-mgr.target >/dev/null 2>&1 || : -fi +%ceph_mgr_module_scripts mgr-diskprediction-local %files mgr-modules-core %dir %{_datadir}/ceph/mgr -%{_datadir}/ceph/mgr/alerts %{_datadir}/ceph/mgr/balancer %{_datadir}/ceph/mgr/crash %{_datadir}/ceph/mgr/devicehealth +%{_datadir}/ceph/mgr/orchestrator +%{_datadir}/ceph/mgr/pg_autoscaler +%{_datadir}/ceph/mgr/progress +%{_datadir}/ceph/mgr/rbd_support +%{_datadir}/ceph/mgr/status +%{_datadir}/ceph/mgr/telemetry +%{_datadir}/ceph/mgr/volumes + +%files mgr-modules-standard + +%files mgr-alerts +%{_datadir}/ceph/mgr/alerts + +%ceph_mgr_module_scripts mgr-alerts + +%files mgr-influx %{_datadir}/ceph/mgr/influx + +%ceph_mgr_module_scripts mgr-influx + +%files mgr-insights %{_datadir}/ceph/mgr/insights + +%ceph_mgr_module_scripts mgr-insights + +%files mgr-iostat %{_datadir}/ceph/mgr/iostat + +%ceph_mgr_module_scripts mgr-iostat + +%files mgr-localpool %{_datadir}/ceph/mgr/localpool + +%ceph_mgr_module_scripts mgr-localpool + +%files mgr-mds-autoscaler %{_datadir}/ceph/mgr/mds_autoscaler + +%ceph_mgr_module_scripts mgr-mds-autoscaler + +%files mgr-mirroring %{_datadir}/ceph/mgr/mirroring + +%ceph_mgr_module_scripts mgr-mirroring + +%files mgr-nfs %{_datadir}/ceph/mgr/nfs -%{_datadir}/ceph/mgr/orchestrator + +%ceph_mgr_module_scripts mgr-nfs + +%files mgr-nvmeof +%{_datadir}/ceph/mgr/nvmeof + +%ceph_mgr_module_scripts mgr-nvmeof + +%files mgr-osd-perf-query %{_datadir}/ceph/mgr/osd_perf_query + +%ceph_mgr_module_scripts mgr-osd-perf-query + +%files mgr-osd-support %{_datadir}/ceph/mgr/osd_support -%{_datadir}/ceph/mgr/pg_autoscaler -%{_datadir}/ceph/mgr/progress + +%ceph_mgr_module_scripts mgr-osd-support + +%files mgr-prometheus %{_datadir}/ceph/mgr/prometheus -%{_datadir}/ceph/mgr/rbd_support + +%ceph_mgr_module_scripts mgr-prometheus + +%files mgr-rgw %{_datadir}/ceph/mgr/rgw + +%ceph_mgr_module_scripts mgr-rgw + +%files mgr-selftest %{_datadir}/ceph/mgr/selftest + +%ceph_mgr_module_scripts mgr-selftest + +%files mgr-smb %{_datadir}/ceph/mgr/smb + +%ceph_mgr_module_scripts mgr-smb + +%files mgr-snap-schedule %{_datadir}/ceph/mgr/snap_schedule + +%ceph_mgr_module_scripts mgr-snap-schedule + +%files mgr-stats %{_datadir}/ceph/mgr/stats -%{_datadir}/ceph/mgr/status + +%ceph_mgr_module_scripts mgr-stats + +%files mgr-telegraf %{_datadir}/ceph/mgr/telegraf -%{_datadir}/ceph/mgr/telemetry + +%ceph_mgr_module_scripts mgr-telegraf + +%files mgr-test-orchestrator %{_datadir}/ceph/mgr/test_orchestrator -%{_datadir}/ceph/mgr/volumes + +%ceph_mgr_module_scripts mgr-test-orchestrator %files mgr-rook %{_datadir}/ceph/mgr/rook -%post mgr-rook -if [ $1 -eq 1 ] ; then - /usr/bin/systemctl try-restart ceph-mgr.target >/dev/null 2>&1 || : -fi - -%postun mgr-rook -if [ $1 -eq 1 ] ; then - /usr/bin/systemctl try-restart ceph-mgr.target >/dev/null 2>&1 || : -fi +%ceph_mgr_module_scripts mgr-rook %files mgr-k8sevents %{_datadir}/ceph/mgr/k8sevents -%post mgr-k8sevents -if [ $1 -eq 1 ] ; then - /usr/bin/systemctl try-restart ceph-mgr.target >/dev/null 2>&1 || : -fi - -%postun mgr-k8sevents -if [ $1 -eq 1 ] ; then - /usr/bin/systemctl try-restart ceph-mgr.target >/dev/null 2>&1 || : -fi +%ceph_mgr_module_scripts mgr-k8sevents %files mgr-cephadm %{_datadir}/ceph/mgr/cephadm -%post mgr-cephadm -if [ $1 -eq 1 ] ; then - /usr/bin/systemctl try-restart ceph-mgr.target >/dev/null 2>&1 || : -fi +%ceph_mgr_module_scripts mgr-cephadm -%postun mgr-cephadm -if [ $1 -eq 1 ] ; then - /usr/bin/systemctl try-restart ceph-mgr.target >/dev/null 2>&1 || : -fi +%files mgr-cli-api +%{_datadir}/ceph/mgr/cli_api + +%ceph_mgr_module_scripts mgr-cli-api %files mon %{_bindir}/ceph-mon @@ -2062,7 +2454,7 @@ if [ $1 -eq 1 ] ; then /usr/bin/systemctl preset ceph-mon@\*.service ceph-mon.target >/dev/null 2>&1 || : fi %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_post ceph-mon@\*.service ceph-mon.target %endif if [ $1 -eq 1 ] ; then @@ -2073,7 +2465,7 @@ fi %if 0%{?suse_version} %service_del_preun ceph-mon@\*.service ceph-mon.target %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_preun ceph-mon@\*.service ceph-mon.target %endif @@ -2114,7 +2506,7 @@ if [ $1 -eq 1 ] ; then /usr/bin/systemctl preset cephfs-mirror@\*.service cephfs-mirror.target >/dev/null 2>&1 || : fi %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_post cephfs-mirror@\*.service cephfs-mirror.target %endif if [ $1 -eq 1 ] ; then @@ -2125,7 +2517,7 @@ fi %if 0%{?suse_version} %service_del_preun cephfs-mirror@\*.service cephfs-mirror.target %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_preun cephfs-mirror@\*.service cephfs-mirror.target %endif @@ -2145,7 +2537,7 @@ fi %files -n ceph-exporter %{_bindir}/ceph-exporter -%{_unitdir}/ceph-exporter.service +%{_unitdir}/ceph-exporter@.service %files -n rbd-fuse %{_bindir}/rbd-fuse @@ -2163,7 +2555,7 @@ if [ $1 -eq 1 ] ; then /usr/bin/systemctl preset ceph-rbd-mirror@\*.service ceph-rbd-mirror.target >/dev/null 2>&1 || : fi %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_post ceph-rbd-mirror@\*.service ceph-rbd-mirror.target %endif if [ $1 -eq 1 ] ; then @@ -2174,7 +2566,7 @@ fi %if 0%{?suse_version} %service_del_preun ceph-rbd-mirror@\*.service ceph-rbd-mirror.target %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_preun ceph-rbd-mirror@\*.service ceph-rbd-mirror.target %endif @@ -2204,7 +2596,7 @@ if [ $1 -eq 1 ] ; then /usr/bin/systemctl preset ceph-immutable-object-cache@\*.service ceph-immutable-object-cache.target >/dev/null 2>&1 || : fi %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_post ceph-immutable-object-cache@\*.service ceph-immutable-object-cache.target %endif if [ $1 -eq 1 ] ; then @@ -2215,7 +2607,7 @@ fi %if 0%{?suse_version} %service_del_preun ceph-immutable-object-cache@\*.service ceph-immutable-object-cache.target %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_preun ceph-immutable-object-cache@\*.service ceph-immutable-object-cache.target %endif @@ -2240,14 +2632,15 @@ fi %{_libexecdir}/rbd-nbd/rbd-nbd_quiesce %files radosgw -%{_bindir}/ceph-diff-sorted %{_bindir}/radosgw %{_bindir}/radosgw-token %{_bindir}/radosgw-es %{_bindir}/radosgw-object-expirer %{_bindir}/rgw-policy-check +%{_bindir}/rgw-policy-test %{_mandir}/man8/radosgw.8* %{_mandir}/man8/rgw-policy-check.8* +%{_mandir}/man8/rgw-policy-test.8* %dir %{_localstatedir}/lib/ceph/radosgw %{_unitdir}/ceph-radosgw@.service %{_unitdir}/ceph-radosgw.target @@ -2258,7 +2651,7 @@ if [ $1 -eq 1 ] ; then /usr/bin/systemctl preset ceph-radosgw@\*.service ceph-radosgw.target >/dev/null 2>&1 || : fi %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_post ceph-radosgw@\*.service ceph-radosgw.target %endif if [ $1 -eq 1 ] ; then @@ -2269,7 +2662,7 @@ fi %if 0%{?suse_version} %service_del_preun ceph-radosgw@\*.service ceph-radosgw.target %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_preun ceph-radosgw@\*.service ceph-radosgw.target %endif @@ -2287,6 +2680,19 @@ if [ $1 -ge 1 ] ; then fi fi +%files rgw-standalone +%dir %{_docdir}/ceph +%doc %{_docdir}/ceph/sample.ceph.conf +%dir %{_libdir}/ceph +%{_libdir}/ceph/libceph-common.so.* +%{_bindir}/rgw-standalone +%{_bindir}/rgw-standalone-admin +%dir %{_localstatedir}/lib/ceph/radosgw + +%post rgw-standalone -p /sbin/ldconfig + +%postun rgw-standalone -p /sbin/ldconfig + %files osd %{_bindir}/ceph-clsinfo %{_bindir}/ceph-erasure-code-tool @@ -2303,7 +2709,7 @@ if [ $1 -eq 1 ] ; then /usr/bin/systemctl preset ceph-osd@\*.service ceph-osd.target >/dev/null 2>&1 || : fi %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_post ceph-osd@\*.service ceph-osd.target %endif if [ $1 -eq 1 ] ; then @@ -2315,7 +2721,7 @@ fi %if 0%{?suse_version} %service_del_preun ceph-osd@\*.service ceph-osd.target %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_preun ceph-osd@\*.service ceph-osd.target %endif @@ -2345,23 +2751,23 @@ fi %{_bindir}/ceph-osd-crimson %{_bindir}/crimson-objectstore-tool -%post osd-crimson +%posttrans osd-crimson %{_sbindir}/update-alternatives --install %{_bindir}/ceph-osd ceph-osd \ %{_bindir}/ceph-osd-crimson 50 %preun osd-crimson if [ $1 -eq 0 ]; then - ${_sbindir}/update-alternatives --remove ceph-osd %{_bindir}/ceph-osd-crimson + %{_sbindir}/update-alternatives --remove ceph-osd %{_bindir}/ceph-osd-crimson fi %endif -%post osd-classic +%posttrans osd-classic %{_sbindir}/update-alternatives --install %{_bindir}/ceph-osd ceph-osd \ %{_bindir}/ceph-osd-classic 100 %preun osd-classic if [ $1 -eq 0 ]; then - ${_sbindir}/update-alternatives --remove ceph-osd %{_bindir}/ceph-osd-classic + %{_sbindir}/update-alternatives --remove ceph-osd %{_bindir}/ceph-osd-classic fi %files volume @@ -2380,7 +2786,7 @@ if [ $1 -eq 1 ] ; then /usr/bin/systemctl preset ceph-volume@\*.service >/dev/null 2>&1 || : fi %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_post ceph-volume@\*.service %endif @@ -2388,7 +2794,7 @@ fi %if 0%{?suse_version} %service_del_preun ceph-volume@\*.service %endif -%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} +%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler} || 0%{?openruyi} %systemd_preun ceph-volume@\*.service %endif @@ -2450,10 +2856,12 @@ fi %{_includedir}/rados/librados_fwd.hpp %{_includedir}/rados/page.h %{_includedir}/rados/rados_types.hpp +%{_includedir}/rados/cls_flags.hpp +%{_includedir}/rados/cls_traits.hpp -%files -n python%{python3_pkgversion}-rados +%files -n python3-rados %{python3_sitearch}/rados.cpython*.so -%{python3_sitearch}/rados-*.egg-info +%{python3_sitearch}/rados-*.dist-info %files -n libcephsqlite %{_libdir}/libcephsqlite.so @@ -2523,13 +2931,13 @@ fi %{_libdir}/librgw_rados_tp.so %endif -%files -n python%{python3_pkgversion}-rgw +%files -n python3-rgw %{python3_sitearch}/rgw.cpython*.so -%{python3_sitearch}/rgw-*.egg-info +%{python3_sitearch}/rgw-*.dist-info -%files -n python%{python3_pkgversion}-rbd +%files -n python3-rbd %{python3_sitearch}/rbd.cpython*.so -%{python3_sitearch}/rbd-*.egg-info +%{python3_sitearch}/rbd-*.dist-info %files -n libcephfs2 %{_libdir}/libcephfs.so.* @@ -2559,23 +2967,24 @@ fi %{_includedir}/cephfs/dump.h %{_includedir}/cephfs/json.h %{_includedir}/cephfs/keys_and_values.h +%{_includedir}/cephfs/snap_types.h %{_libdir}/libcephfs.so %{_libdir}/libcephfs_proxy.so %{_libdir}/pkgconfig/cephfs.pc -%files -n python%{python3_pkgversion}-cephfs +%files -n python3-cephfs %{python3_sitearch}/cephfs.cpython*.so -%{python3_sitearch}/cephfs-*.egg-info +%{python3_sitearch}/cephfs-*.dist-info -%files -n python%{python3_pkgversion}-ceph-argparse +%files -n python3-ceph-argparse %{python3_sitelib}/ceph_argparse.py %{python3_sitelib}/__pycache__/ceph_argparse.cpython*.py* %{python3_sitelib}/ceph_daemon.py %{python3_sitelib}/__pycache__/ceph_daemon.cpython*.py* -%files -n python%{python3_pkgversion}-ceph-common +%files -n python3-ceph-common %{python3_sitelib}/ceph -%{python3_sitelib}/ceph-*.egg-info +%{python3_sitelib}/ceph-*.%{?with_pypkg:dist}%{!?with_pypkg:egg}-info %if 0%{with cephfs_shell} %files -n cephfs-shell @@ -2603,7 +3012,6 @@ fi %{_bindir}/ceph_perf_msgr_client %{_bindir}/ceph_perf_msgr_server %{_bindir}/ceph_psim -%{_bindir}/ceph_radosacl %{_bindir}/ceph_rgw_jsonparser %{_bindir}/ceph_rgw_multiparser %{_bindir}/ceph_scratchtool @@ -2773,4 +3181,9 @@ exit 0 %{python3_sitelib}/ceph_node_proxy/* %{python3_sitelib}/ceph_node_proxy-* +%if %{with pypkg} +%files -n python3-ceph-smb-ctl +%{_bindir}/ceph-smb-ctl +%endif + %changelog diff --git a/cmake/modules/AddCephTest.cmake b/cmake/modules/AddCephTest.cmake index 65aafaf18839..98ae096306b9 100644 --- a/cmake/modules/AddCephTest.cmake +++ b/cmake/modules/AddCephTest.cmake @@ -3,6 +3,7 @@ #adds makes target/script into a test, test to check target, sets necessary environment variables function(add_ceph_test test_name test_path) add_test(NAME ${test_name} COMMAND ${test_path} ${ARGN} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND_EXPAND_LISTS) if(TARGET ${test_name}) add_dependencies(tests ${test_name}) @@ -32,8 +33,8 @@ function(add_ceph_test test_name test_path) set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT - ASAN_OPTIONS=suppressions=${CMAKE_SOURCE_DIR}/qa/asan.supp,detect_odr_violation=0 - LSAN_OPTIONS=suppressions=${CMAKE_SOURCE_DIR}/qa/lsan.supp,print_suppressions=0) + ASAN_OPTIONS=${CEPH_ASAN_OPTIONS} + LSAN_OPTIONS=${CEPH_LSAN_OPTIONS}) endif() set_property(TEST ${test_name} PROPERTY TIMEOUT ${CEPH_TEST_TIMEOUT}) @@ -72,8 +73,11 @@ if(WITH_GTEST_PARALLEL) BUILD_COMMAND "" INSTALL_COMMAND "") add_dependencies(tests gtest-parallel_ext) + # CACHE INTERNAL: the set() runs only in the first directory to create the + # target, so a plain variable would be invisible to PARALLEL tests elsewhere. set(GTEST_PARALLEL_COMMAND - ${Python3_EXECUTABLE} ${gtest_parallel_source_dir}/gtest-parallel) + ${Python3_EXECUTABLE} ${gtest_parallel_source_dir}/gtest-parallel + CACHE INTERNAL "command to run a gtest binary through gtest-parallel") endif() endif() @@ -182,9 +186,12 @@ if(DEFINED catch2_opt_EXTRA_INCS) endif() if(${catch2_opt_NO_CATCH2_MAIN}) - LIST(APPEND tl_libs Catch2) + LIST(APPEND tl_libs Catch2::Catch2) else() - LIST(APPEND tl_libs Catch2WithMain) + # Accept the gtest XML flag used by the Windows test runner. + target_sources(unittest_${test_name} + PRIVATE ${CMAKE_SOURCE_DIR}/src/test/catch2_compat_main.cc) + LIST(APPEND tl_libs Catch2::Catch2) endif() target_link_libraries(unittest_${test_name} diff --git a/cmake/modules/BuildArrow.cmake b/cmake/modules/BuildArrow.cmake index f3bf1872931c..10689928af3d 100644 --- a/cmake/modules/BuildArrow.cmake +++ b/cmake/modules/BuildArrow.cmake @@ -12,8 +12,12 @@ function(build_arrow) list(APPEND arrow_CMAKE_ARGS -DARROW_BUILD_STATIC=ON) # arrow only supports its own bundled version of jemalloc, so can't - # share the version ceph is using - list(APPEND arrow_CMAKE_ARGS -DARROW_JEMALLOC=OFF) + # share the version ceph is using, + # arrow builds and uses mimalloc by default, let's reduce the build time + # and simplify the linkage. + list(APPEND arrow_CMAKE_ARGS + -DARROW_JEMALLOC=OFF + -DARROW_MIMALLOC=OFF) # transitive dependencies if (thrift_VERSION VERSION_GREATER_EQUAL 0.17) diff --git a/cmake/modules/BuildBoost.cmake b/cmake/modules/BuildBoost.cmake index a662591fbf9c..6a00c6be2c0f 100644 --- a/cmake/modules/BuildBoost.cmake +++ b/cmake/modules/BuildBoost.cmake @@ -144,15 +144,26 @@ function(do_build_boost root_dir version) if(WITH_BOOST_VALGRIND) list(APPEND b2 valgrind=on) endif() + set(b2_targets headers stage) + set(b2_install_targets install) if(WITH_ASAN) list(APPEND b2 context-impl=ucontext) + # build the library with the BOOST_USE_ASAN consumers get from Boost::context, + # so fiber_activation_record has one layout (else heap-buffer-overflow) + list(APPEND b2 define=BOOST_USE_ASAN) + # `context-impl` is declared in libs/context/build/Jamfile.v2; the headers/stage + # and install targets never load it, so b2 aborts with `unknown feature + # ""`. Name the context project as a target so its Jamfile loads + # the feature first. + list(PREPEND b2_targets libs/context/build) + list(PREPEND b2_install_targets libs/context/build) endif() set(build_command - ${b2} headers stage + ${b2} ${b2_targets} #"--buildid=ceph" # changes lib names--can omit for static ${boost_features}) set(install_command - ${b2} install) + ${b2} ${b2_install_targets}) if(EXISTS "${PROJECT_SOURCE_DIR}/src/boost/bootstrap.sh") check_boost_version("${PROJECT_SOURCE_DIR}/src/boost" ${version}) set(source_dir @@ -223,6 +234,9 @@ macro(build_boost version) endif() endforeach() set(Boost_BUILD_COMPONENTS ${components}) + # Remove the `headers` from the list of components to build as + # `headers` is an interface only target we add later. + list(REMOVE_ITEM Boost_BUILD_COMPONENTS headers) unset(components) foreach(c ${Boost_BUILD_COMPONENTS}) @@ -251,10 +265,8 @@ macro(build_boost version) set_target_properties(Boost::${c} PROPERTIES INTERFACE_COMPILE_DEFINITIONS "BOOST_USE_VALGRIND") endif() - if((c MATCHES "context") AND (WITH_ASAN)) - set_target_properties(Boost::${c} PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "BOOST_USE_ASAN;BOOST_USE_UCONTEXT") - endif() + # ASan's BOOST_USE_ASAN/BOOST_USE_UCONTEXT are defined tree-wide in the + # top-level CMakeLists.txt, not per-target. list(APPEND Boost_LIBRARIES ${Boost_${upper_c}_LIBRARY}) endforeach() foreach(c ${Boost_BUILD_COMPONENTS}) @@ -278,13 +290,18 @@ macro(build_boost version) endforeach() # for header-only libraries - add_library(Boost::boost INTERFACE IMPORTED) - set_target_properties(Boost::boost PROPERTIES + add_library(Boost::headers INTERFACE IMPORTED) + set_target_properties(Boost::headers PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}") - add_dependencies(Boost::boost Boost) + add_dependencies(Boost::headers Boost) find_package_handle_standard_args(Boost DEFAULT_MSG Boost_INCLUDE_DIRS Boost_LIBRARIES) mark_as_advanced(Boost_LIBRARIES BOOST_INCLUDE_DIRS) + + add_library(Boost::boost INTERFACE IMPORTED) + set_property(TARGET Boost::boost APPEND PROPERTY INTERFACE_LINK_LIBRARIES + Boost::headers) + endmacro() function(maybe_add_boost_dep target) @@ -298,7 +315,7 @@ function(maybe_add_boost_dep target) get_filename_component(ext ${src} EXT) # assuming all cxx source files include boost header(s) if(ext MATCHES ".cc|.cpp|.cxx") - add_dependencies(${target} Boost::boost) + add_dependencies(${target} Boost::headers) return() endif() endforeach() @@ -315,5 +332,8 @@ endfunction() function(add_executable target) _add_executable(${target} ${ARGN}) - maybe_add_boost_dep(${target}) + # can't add dependencies to aliases + if (NOT ";${ARGN};" MATCHES ";(ALIAS);") + maybe_add_boost_dep(${target}) + endif() endfunction() diff --git a/cmake/modules/BuildFIO.cmake b/cmake/modules/BuildFIO.cmake index 49fcfb31d973..61c445628f54 100644 --- a/cmake/modules/BuildFIO.cmake +++ b/cmake/modules/BuildFIO.cmake @@ -15,14 +15,25 @@ function(build_fio) include(FindMake) find_make("MAKE_EXECUTABLE" "make_cmd") + include(CheckTypeSize) + check_type_size("void*" SIZEOF_VOID_P) + + if(SIZEOF_VOID_P EQUAL 8) + set(WORD_SIZE 64) + elseif(SIZEOF_VOID_P EQUAL 4) + set(WORD_SIZE 32) + else() + message(FATAL_ERROR "Unknown wordsize") + endif() + set(source_dir ${CMAKE_BINARY_DIR}/src/fio) file(MAKE_DIRECTORY ${source_dir}) ExternalProject_Add(fio_ext UPDATE_COMMAND "" # this disables rebuild on each run - GIT_REPOSITORY "https://github.com/ceph/fio.git" + GIT_REPOSITORY "https://github.com/axboe/fio.git" GIT_CONFIG advice.detachedHead=false GIT_SHALLOW 1 - GIT_TAG "fio-3.27-cxx" + GIT_TAG "fio-3.42" SOURCE_DIR ${source_dir} BUILD_IN_SOURCE 1 CONFIGURE_COMMAND /configure @@ -39,5 +50,6 @@ function(build_fio) set_target_properties(fio PROPERTIES CXX_EXTENSIONS ON INTERFACE_INCLUDE_DIRECTORIES ${source_dir} - INTERFACE_COMPILE_OPTIONS "-include;${source_dir}/config-host.h;$<$:-std=gnu99>") + INTERFACE_COMPILE_OPTIONS "-include;${source_dir}/config-host.h;$<$:-std=gnu99>" + INTERFACE_COMPILE_DEFINITIONS "BITS_PER_LONG=${WORD_SIZE}") endfunction() diff --git a/cmake/modules/BuildISAL.cmake b/cmake/modules/BuildISAL.cmake index fa1476cabf89..ab2a63b6703e 100644 --- a/cmake/modules/BuildISAL.cmake +++ b/cmake/modules/BuildISAL.cmake @@ -3,13 +3,14 @@ function(build_isal) set(isal_BINARY_DIR ${CMAKE_BINARY_DIR}/src/isa-l) set(isal_INSTALL_DIR ${isal_BINARY_DIR}/install) set(isal_INCLUDE_DIR "${isal_INSTALL_DIR}/include") - set(isal_LIBRARY "${isal_INSTALL_DIR}/lib/libisal.a") + set(isal_LIBRARY_DIR "${isal_INSTALL_DIR}/lib") + set(isal_LIBRARY "${isal_LIBRARY_DIR}/libisal.a") # this include directory won't exist until the install step, but the # imported targets need it early for INTERFACE_INCLUDE_DIRECTORIES file(MAKE_DIRECTORY "${isal_INCLUDE_DIR}") - set(configure_cmd env CC=${CMAKE_C_COMPILER} ./configure --prefix=${isal_INSTALL_DIR}) + set(configure_cmd env CC=${CMAKE_C_COMPILER} ./configure --prefix=${isal_INSTALL_DIR} --libdir=${isal_LIBRARY_DIR}) # build a static library with -fPIC that we can link into crypto/compressor plugins list(APPEND configure_cmd --with-pic --enable-static --disable-shared) @@ -17,18 +18,30 @@ function(build_isal) # because it messes with the internal install paths of arrow's bundled deps set(NO_DESTDIR_COMMAND ${CMAKE_COMMAND} -E env --unset=DESTDIR) + set(arm_cflags "") if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND HAVE_ARMV8_SIMD) - list(APPEND configure_cmd CFLAGS=-no-integrated-as) + list(APPEND arm_cflags "-no-integrated-as") + endif() + # isa-l 2.32.0 includes SVE and SVE2-optimized assembly for better performance on + # compatible ARM CPUs + if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64") + list(APPEND arm_cflags "-Wa,-march=armv8-a+sve") + endif() + if(arm_cflags) + string(REPLACE ";" " " arm_cflags_str "${arm_cflags}") + list(APPEND configure_cmd "CFLAGS=$ENV{CFLAGS} -fPIC ${arm_cflags_str}") endif() include(ExternalProject) ExternalProject_Add(isal_ext SOURCE_DIR "${PROJECT_SOURCE_DIR}/src/isa-l" CONFIGURE_COMMAND ./autogen.sh COMMAND ${configure_cmd} - BUILD_COMMAND ${NO_DESTDIR_COMMAND} make -j3 + BUILD_COMMAND ${NO_DESTDIR_COMMAND} make -j3 libisal.la BUILD_IN_SOURCE 1 BUILD_BYPRODUCTS ${isal_LIBRARY} - INSTALL_COMMAND ${NO_DESTDIR_COMMAND} make install + INSTALL_COMMAND ${NO_DESTDIR_COMMAND} make install-libLTLIBRARIES + install-pkgincludeHEADERS + install-nobase_includeHEADERS UPDATE_COMMAND "" LOG_CONFIGURE ON LOG_BUILD ON diff --git a/cmake/modules/BuildRocksDB.cmake b/cmake/modules/BuildRocksDB.cmake index c1f4823963f2..4ca2b37ad361 100644 --- a/cmake/modules/BuildRocksDB.cmake +++ b/cmake/modules/BuildRocksDB.cmake @@ -14,7 +14,7 @@ function(build_rocksdb) list(APPEND rocksdb_CMAKE_ARGS -DWITH_LIBURING=${WITH_LIBURING}) if(WITH_LIBURING) list(APPEND rocksdb_CMAKE_ARGS -During_INCLUDE_DIR=${URING_INCLUDE_DIR}) - list(APPEND rocksdb_CMAKE_ARGS -During_LIBRARIES=${URING_LIBRARY_DIR}) + list(APPEND rocksdb_CMAKE_ARGS -During_LIBRARIES=${URING_LIBRARY_DIR}/liburing.a) list(APPEND rocksdb_INTERFACE_LINK_LIBRARIES uring::uring) endif() diff --git a/cmake/modules/Buildpmdk.cmake b/cmake/modules/Buildpmdk.cmake index 03a17b99436c..7377fc9d5c87 100644 --- a/cmake/modules/Buildpmdk.cmake +++ b/cmake/modules/Buildpmdk.cmake @@ -1,4 +1,4 @@ -function(build_pmdk enable_ndctl) +function(build_pmdk) include(FindMake) find_make("MAKE_EXECUTABLE" "make_cmd") @@ -15,12 +15,6 @@ function(build_pmdk enable_ndctl) endif() set(LIBPMEM_INTERFACE_LINK_LIBRARIES Threads::Threads) - if(${enable_ndctl}) - set(ndctl "y") - list(APPEND LIBPMEM_INTERFACE_LINK_LIBRARIES ndctl::ndctl daxctl::daxctl) - else() - set(ndctl "n") - endif() # Use debug PMDK libs in debug lib/rbd builds if(CMAKE_BUILD_TYPE STREQUAL Debug) @@ -34,7 +28,7 @@ function(build_pmdk enable_ndctl) ExternalProject_Add(pmdk_ext ${source_dir_args} CONFIGURE_COMMAND "" - BUILD_COMMAND ${make_cmd} CC=${CMAKE_C_COMPILER} "EXTRA_CFLAGS=${pmdk_cflags}" NDCTL_ENABLE=${ndctl} BUILD_EXAMPLES=n BUILD_BENCHMARKS=n DOC=n + BUILD_COMMAND ${make_cmd} CC=${CMAKE_C_COMPILER} "EXTRA_CFLAGS=${pmdk_cflags}" NDCTL_ENABLE=n BUILD_EXAMPLES=n BUILD_BENCHMARKS=n DOC=n BUILD_IN_SOURCE 1 BUILD_BYPRODUCTS "/src/${PMDK_LIB_DIR}/libpmem.a" "/src/${PMDK_LIB_DIR}/libpmemobj.a" INSTALL_COMMAND "") diff --git a/cmake/modules/Builduring.cmake b/cmake/modules/Builduring.cmake index 4e4107fb5ac7..9f753dda5168 100644 --- a/cmake/modules/Builduring.cmake +++ b/cmake/modules/Builduring.cmake @@ -42,4 +42,6 @@ function(build_uring) INTERFACE_INCLUDE_DIRECTORIES ${URING_INCLUDE_DIR} IMPORTED_LINK_INTERFACE_LANGUAGES "C" IMPORTED_LOCATION "${URING_LIBRARY_DIR}/liburing.a") + + add_library(URING::uring ALIAS uring::uring) endfunction() diff --git a/cmake/modules/CephChecks.cmake b/cmake/modules/CephChecks.cmake index 4da4dfad5bf3..9506a4db2209 100644 --- a/cmake/modules/CephChecks.cmake +++ b/cmake/modules/CephChecks.cmake @@ -202,3 +202,12 @@ try_compile(HAVE_LINK_EXCLUDE_LIBS ${CMAKE_CURRENT_BINARY_DIR} SOURCES ${CMAKE_CURRENT_LIST_DIR}/CephCheck_link.c LINK_LIBRARIES "-Wl,--exclude-libs,ALL") + +# Mold linker applies --exclude-libs after version script processing, +# which hides .symver-aliased symbols (e.g. rados_*) even when the +# version script lists them as global. Disable --exclude-libs for Mold; +# version scripts already control symbol visibility. +if(HAVE_LINK_EXCLUDE_LIBS AND USING_MOLD_LINKER) + message(STATUS "Mold linker -- disabling --exclude-libs (incompatible with .symver)") + set(HAVE_LINK_EXCLUDE_LIBS FALSE CACHE INTERNAL "" FORCE) +endif() diff --git a/cmake/modules/CheckNasm.cmake b/cmake/modules/CheckNasm.cmake index 8a45bf38bfbc..e7951f6f354a 100644 --- a/cmake/modules/CheckNasm.cmake +++ b/cmake/modules/CheckNasm.cmake @@ -1,4 +1,5 @@ -macro(check_nasm_support _object_format _support_x64 _support_x64_and_avx2 _support_x64_and_avx512) +macro(check_nasm_support _object_format _support_x64 _support_x64_and_avx2 _support_x64_and_avx512 + _support_x64_and_avx512_vpclmul) execute_process( COMMAND which nasm RESULT_VARIABLE no_nasm @@ -37,6 +38,16 @@ macro(check_nasm_support _object_format _support_x64 _support_x64_and_avx2 _supp if(NOT rt) set(${_support_x64_and_avx512} TRUE) endif() + execute_process(COMMAND nasm -D AS_FEATURE_LEVEL=10 -f ${object_format} + -i ${CMAKE_SOURCE_DIR}/src/isa-l/include/ + ${CMAKE_SOURCE_DIR}/src/isa-l/crc/crc32_iscsi_by16_10.asm + -o /dev/null + RESULT_VARIABLE rt + OUTPUT_QUIET + ERROR_QUIET) + if(NOT rt) + set(${_support_x64_and_avx512_vpclmul} TRUE) + endif() endif(${_support_x64}) endif(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64|x86_64") endif(NOT no_nasm) @@ -44,6 +55,8 @@ macro(check_nasm_support _object_format _support_x64 _support_x64_and_avx2 _supp message(STATUS "Could NOT find nasm") elseif(NOT ${_support_x64}) message(STATUS "Found nasm: but x86_64 with x32 ABI is not supported") + elseif(${_support_x64_and_avx512_vpclmul}) + message(STATUS "Found nasm: best of best -- capable of assembling AVX512 & VPCLMUL") elseif(${_support_x64_and_avx512}) message(STATUS "Found nasm: best -- capable of assembling AVX512") elseif(${_support_x64_and_avx2}) diff --git a/cmake/modules/Distutils.cmake b/cmake/modules/Distutils.cmake index f3d6c41e7317..9d5dd33fcefb 100644 --- a/cmake/modules/Distutils.cmake +++ b/cmake/modules/Distutils.cmake @@ -72,7 +72,11 @@ function(distutils_add_cython_module target name src) list(APPEND PY_CPPFLAGS -D'__Pyx_check_single_interpreter\(ARG\)=ARG\#\#0') set(PY_CC ${compiler_launcher} ${CMAKE_C_COMPILER} ${c_compiler_arg1}) set(PY_CXX ${compiler_launcher} ${CMAKE_CXX_COMPILER} ${cxx_compiler_arg1}) - set(PY_LDSHARED ${link_launcher} ${CMAKE_C_COMPILER} ${c_compiler_arg1} "-shared") + if(USING_MOLD_LINKER) + set(PY_LDSHARED ${link_launcher} ${CMAKE_C_COMPILER} ${c_compiler_arg1} "-shared" "${MOLD_FUSE_LD_FLAG}") + else() + set(PY_LDSHARED ${link_launcher} ${CMAKE_C_COMPILER} ${c_compiler_arg1} "-shared") + endif() string(REPLACE " " ";" PY_LDFLAGS "${CMAKE_SHARED_LINKER_FLAGS}") list(APPEND PY_LDFLAGS -L${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) @@ -117,7 +121,12 @@ function(distutils_install_cython_module name) get_property(compiler_launcher GLOBAL PROPERTY RULE_LAUNCH_COMPILE) get_property(link_launcher GLOBAL PROPERTY RULE_LAUNCH_LINK) set(PY_CC "${compiler_launcher} ${CMAKE_C_COMPILER}") - set(PY_LDSHARED "${link_launcher} ${CMAKE_C_COMPILER} -shared") + if(USING_MOLD_LINKER) + set(PY_LDSHARED "${link_launcher} ${CMAKE_C_COMPILER} -shared ${MOLD_FUSE_LD_FLAG}") + else() + set(PY_LDSHARED "${link_launcher} ${CMAKE_C_COMPILER} -shared") + endif() + set(PY_LDFLAGS "${CMAKE_SHARED_LINKER_FLAGS} -L${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") cmake_parse_arguments(DU "DISABLE_VTA" "" "" ${ARGN}) if(DU_DISABLE_VTA AND HAS_VTA) set(CFLAG_DISABLE_VTA -fno-var-tracking-assignments) @@ -136,25 +145,27 @@ function(distutils_install_cython_module name) set(ENV{CYTHON_BUILD_DIR} \"${CMAKE_CURRENT_BINARY_DIR}\") set(ENV{CEPH_LIBDIR} \"${CMAKE_LIBRARY_OUTPUT_DIRECTORY}\") - set(options --prefix=${CMAKE_INSTALL_PREFIX}) + set(options + --prefix=${CMAKE_INSTALL_PREFIX} + --use-pep517 + --no-build-isolation + --no-deps + --ignore-installed) if(DEFINED ENV{DESTDIR}) if(EXISTS /etc/debian_version) - list(APPEND options --install-layout=deb) + list(APPEND env_vars \"DEB_PYTHON_INSTALL_LAYOUT=deb\") endif() list(APPEND options --root=\$ENV{DESTDIR}) else() list(APPEND options --root=/) endif() execute_process( - COMMAND - ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/setup.py - build ${maybe_verbose} --build-base ${CYTHON_MODULE_DIR} - --build-platlib ${CYTHON_MODULE_DIR}/lib.3 - build_ext --cython-c-in-temp --build-temp ${CMAKE_CURRENT_BINARY_DIR} --cython-include-dirs ${PROJECT_SOURCE_DIR}/src/pybind/rados - install \${options} --single-version-externally-managed --record /dev/null - egg_info --egg-base ${CMAKE_CURRENT_BINARY_DIR} + COMMAND env \${env_vars} + ${Python3_EXECUTABLE} -m pip install + \${options} ${maybe_verbose} - WORKING_DIRECTORY \"${CMAKE_CURRENT_SOURCE_DIR}\" + ${CMAKE_CURRENT_SOURCE_DIR} + WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\" RESULT_VARIABLE install_res) if(NOT \"\${install_res}\" STREQUAL 0) message(FATAL_ERROR \"Failed to build and install ${name} python module\") diff --git a/cmake/modules/FindBoost.cmake b/cmake/modules/FindBoost.cmake deleted file mode 100644 index 631ebcaaa668..000000000000 --- a/cmake/modules/FindBoost.cmake +++ /dev/null @@ -1,2648 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file LICENSE.rst or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindBoost ---------- - -.. versionchanged:: 3.30 - This module is available only if policy :policy:`CMP0167` is not set to - ``NEW``. Port projects to upstream Boost's ``BoostConfig.cmake`` package - configuration file, for which ``find_package(Boost)`` now searches. - -Find Boost include dirs and libraries - -Use this module by invoking :command:`find_package` with the form: - -.. code-block:: cmake - - find_package(Boost - [version] [EXACT] # Minimum or EXACT version e.g. 1.67.0 - [REQUIRED] # Fail with error if Boost is not found - [COMPONENTS ...] # Boost libraries by their canonical name - # e.g. "date_time" for "libboost_date_time" - [OPTIONAL_COMPONENTS ...] - # Optional Boost libraries by their canonical name) - ) # e.g. "date_time" for "libboost_date_time" - -This module finds headers and requested component libraries OR a CMake -package configuration file provided by a "Boost CMake" build. For the -latter case skip to the :ref:`Boost CMake` section below. - -.. versionadded:: 3.7 - ``bzip2`` and ``zlib`` components (Windows only). - -.. versionadded:: 3.11 - The ``OPTIONAL_COMPONENTS`` option. - -.. versionadded:: 3.13 - ``stacktrace_*`` components. - -.. versionadded:: 3.19 - ``bzip2`` and ``zlib`` components on all platforms. - -Result Variables -^^^^^^^^^^^^^^^^ - -This module defines the following variables: - -``Boost_FOUND`` - True if headers and requested libraries were found. - -``Boost_INCLUDE_DIRS`` - Boost include directories. - -``Boost_LIBRARY_DIRS`` - Link directories for Boost libraries. - -``Boost_LIBRARIES`` - Boost component libraries to be linked. - -``Boost__FOUND`` - True if component ```` was found (```` name is upper-case). - -``Boost__LIBRARY`` - Libraries to link for component ```` (may include - :command:`target_link_libraries` debug/optimized keywords). - -``Boost_VERSION_MACRO`` - ``BOOST_VERSION`` value from ``boost/version.hpp``. - -``Boost_VERSION_STRING`` - Boost version number in ``X.Y.Z`` format. - -``Boost_VERSION`` - Boost version number in ``X.Y.Z`` format (same as ``Boost_VERSION_STRING``). - - .. versionchanged:: 3.15 - In previous CMake versions, this variable used the raw version string - from the Boost header (same as ``Boost_VERSION_MACRO``). - See policy :policy:`CMP0093`. - -``Boost_LIB_VERSION`` - Version string appended to library filenames. - -``Boost_VERSION_MAJOR``, ``Boost_MAJOR_VERSION`` - Boost major version number (``X`` in ``X.Y.Z``). - -``Boost_VERSION_MINOR``, ``Boost_MINOR_VERSION`` - Boost minor version number (``Y`` in ``X.Y.Z``). - -``Boost_VERSION_PATCH``, ``Boost_SUBMINOR_VERSION`` - Boost subminor version number (``Z`` in ``X.Y.Z``). - -``Boost_VERSION_COUNT`` - Amount of version components (3). - -``Boost_LIB_DIAGNOSTIC_DEFINITIONS`` (Windows-specific) - Pass to :command:`add_definitions` to have diagnostic - information about Boost's automatic linking - displayed during compilation - -.. versionadded:: 3.15 - The ``Boost_VERSION_`` variables. - -Cache variables -^^^^^^^^^^^^^^^ - -Search results are saved persistently in CMake cache entries: - -``Boost_INCLUDE_DIR`` - Directory containing Boost headers. - -``Boost_LIBRARY_DIR_RELEASE`` - Directory containing release Boost libraries. - -``Boost_LIBRARY_DIR_DEBUG`` - Directory containing debug Boost libraries. - -``Boost__LIBRARY_DEBUG`` - Component ```` library debug variant. - -``Boost__LIBRARY_RELEASE`` - Component ```` library release variant. - -.. versionadded:: 3.3 - Per-configuration variables ``Boost_LIBRARY_DIR_RELEASE`` and - ``Boost_LIBRARY_DIR_DEBUG``. - -Hints -^^^^^ - -This module reads hints about search locations from variables: - -``BOOST_ROOT``, ``BOOSTROOT`` - Preferred installation prefix. - -``BOOST_INCLUDEDIR`` - Preferred include directory e.g. ``/include``. - -``BOOST_LIBRARYDIR`` - Preferred library directory e.g. ``/lib``. - -``Boost_NO_SYSTEM_PATHS`` - Set to ``ON`` to disable searching in locations not - specified by these hint variables. Default is ``OFF``. - -``Boost_ADDITIONAL_VERSIONS`` - List of Boost versions not known to this module. - (Boost install locations may contain the version). - -Users may set these hints or results as ``CACHE`` entries. Projects -should not read these entries directly but instead use the above -result variables. Note that some hint names start in upper-case -``BOOST``. One may specify these as environment variables if they are -not specified as CMake variables or cache entries. - -This module first searches for the Boost header files using the above -hint variables (excluding ``BOOST_LIBRARYDIR``) and saves the result in -``Boost_INCLUDE_DIR``. Then it searches for requested component libraries -using the above hints (excluding ``BOOST_INCLUDEDIR`` and -``Boost_ADDITIONAL_VERSIONS``), "lib" directories near ``Boost_INCLUDE_DIR``, -and the library name configuration settings below. It saves the -library directories in ``Boost_LIBRARY_DIR_DEBUG`` and -``Boost_LIBRARY_DIR_RELEASE`` and individual library -locations in ``Boost__LIBRARY_DEBUG`` and ``Boost__LIBRARY_RELEASE``. -When one changes settings used by previous searches in the same build -tree (excluding environment variables) this module discards previous -search results affected by the changes and searches again. - -Imported Targets -^^^^^^^^^^^^^^^^ - -.. versionadded:: 3.5 - -This module defines the following :prop_tgt:`IMPORTED` targets: - -``Boost::boost`` - Target for header-only dependencies. (Boost include directory). - -``Boost::headers`` - .. versionadded:: 3.15 - Alias for ``Boost::boost``. - -``Boost::`` - Target for specific component dependency (shared or static library); - ```` name is lower-case. - -``Boost::diagnostic_definitions`` - Interface target to enable diagnostic information about Boost's automatic - linking during compilation (adds ``-DBOOST_LIB_DIAGNOSTIC``). - -``Boost::disable_autolinking`` - Interface target to disable automatic linking with MSVC - (adds ``-DBOOST_ALL_NO_LIB``). - -``Boost::dynamic_linking`` - Interface target to enable dynamic linking with MSVC - (adds ``-DBOOST_ALL_DYN_LINK``). - -Implicit dependencies such as ``Boost::filesystem`` requiring -``Boost::system`` will be automatically detected and satisfied, even -if system is not specified when using :command:`find_package` and if -``Boost::system`` is not added to :command:`target_link_libraries`. If using -``Boost::thread``, then ``Threads::Threads`` will also be added automatically. - -It is important to note that the imported targets behave differently -than variables created by this module: multiple calls to -:command:`find_package(Boost)` in the same directory or sub-directories with -different options (e.g. static or shared) will not override the -values of the targets created by the first call. - -Other Variables -^^^^^^^^^^^^^^^ - -Boost libraries come in many variants encoded in their file name. -Users or projects may tell this module which variant to find by -setting variables: - -``Boost_USE_DEBUG_LIBS`` - .. versionadded:: 3.10 - - Set to ``ON`` or ``OFF`` to specify whether to search and use the debug - libraries. Default is ``ON``. - -``Boost_USE_RELEASE_LIBS`` - .. versionadded:: 3.10 - - Set to ``ON`` or ``OFF`` to specify whether to search and use the release - libraries. Default is ``ON``. - -``Boost_USE_MULTITHREADED`` - Set to OFF to use the non-multithreaded libraries ("mt" tag). Default is - ``ON``. - -``Boost_USE_STATIC_LIBS`` - Set to ON to force the use of the static libraries. Default is ``OFF``. - -``Boost_USE_STATIC_RUNTIME`` - Set to ``ON`` or ``OFF`` to specify whether to use libraries linked - statically to the C++ runtime ("s" tag). Default is platform dependent. - -``Boost_USE_DEBUG_RUNTIME`` - Set to ``ON`` or ``OFF`` to specify whether to use libraries linked to the - MS debug C++ runtime ("g" tag). Default is ``ON``. - -``Boost_USE_DEBUG_PYTHON`` - Set to ``ON`` to use libraries compiled with a debug Python build ("y" - tag). Default is ``OFF``. - -``Boost_USE_STLPORT`` - Set to ``ON`` to use libraries compiled with STLPort ("p" tag). Default is - ``OFF``. - -``Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS`` - Set to ON to use libraries compiled with STLPort deprecated "native - iostreams" ("n" tag). Default is ``OFF``. - -``Boost_COMPILER`` - Set to the compiler-specific library suffix (e.g. ``-gcc43``). Default is - auto-computed for the C++ compiler in use. - - .. versionchanged:: 3.9 - A list may be used if multiple compatible suffixes should be tested for, - in decreasing order of preference. - -``Boost_LIB_PREFIX`` - .. versionadded:: 3.18 - - Set to the platform-specific library name prefix (e.g. ``lib``) used by - Boost static libs. This is needed only on platforms where CMake does not - know the prefix by default. - -``Boost_ARCHITECTURE`` - .. versionadded:: 3.13 - - Set to the architecture-specific library suffix (e.g. ``-x64``). - Default is auto-computed for the C++ compiler in use. - -``Boost_THREADAPI`` - Suffix for ``thread`` component library name, such as ``pthread`` or - ``win32``. Names with and without this suffix will both be tried. - -``Boost_NAMESPACE`` - Alternate namespace used to build boost with e.g. if set to ``myboost``, - will search for ``myboost_thread`` instead of ``boost_thread``. - -Other variables one may set to control this module are: - -``Boost_DEBUG`` - Set to ``ON`` to enable debug output from ``FindBoost``. - Please enable this before filing any bug report. - -``Boost_REALPATH`` - Set to ``ON`` to resolve symlinks for discovered libraries to assist with - packaging. For example, the "system" component library may be resolved to - ``/usr/lib/libboost_system.so.1.67.0`` instead of - ``/usr/lib/libboost_system.so``. This does not affect linking and should - not be enabled unless the user needs this information. - -``Boost_LIBRARY_DIR`` - Default value for ``Boost_LIBRARY_DIR_RELEASE`` and - ``Boost_LIBRARY_DIR_DEBUG``. - -``Boost_NO_WARN_NEW_VERSIONS`` - .. versionadded:: 3.20 - - Set to ``ON`` to suppress the warning about unknown dependencies for new - Boost versions. - -On Visual Studio and Borland compilers Boost headers request automatic -linking to corresponding libraries. This requires matching libraries -to be linked explicitly or available in the link library search path. -In this case setting ``Boost_USE_STATIC_LIBS`` to ``OFF`` may not achieve -dynamic linking. Boost automatic linking typically requests static -libraries with a few exceptions (such as ``Boost.Python``). Use: - -.. code-block:: cmake - - add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS}) - -to ask Boost to report information about automatic linking requests. - -Examples -^^^^^^^^ - -Find Boost headers only: - -.. code-block:: cmake - - find_package(Boost 1.36.0) - if(Boost_FOUND) - include_directories(${Boost_INCLUDE_DIRS}) - add_executable(foo foo.cc) - endif() - -Find Boost libraries and use imported targets: - -.. code-block:: cmake - - find_package(Boost 1.56 REQUIRED COMPONENTS - date_time filesystem iostreams) - add_executable(foo foo.cc) - target_link_libraries(foo Boost::date_time Boost::filesystem - Boost::iostreams) - -Find Boost Python 3.6 libraries and use imported targets: - -.. code-block:: cmake - - find_package(Boost 1.67 REQUIRED COMPONENTS - python36 numpy36) - add_executable(foo foo.cc) - target_link_libraries(foo Boost::python36 Boost::numpy36) - -Find Boost headers and some *static* (release only) libraries: - -.. code-block:: cmake - - set(Boost_USE_STATIC_LIBS ON) # only find static libs - set(Boost_USE_DEBUG_LIBS OFF) # ignore debug libs and - set(Boost_USE_RELEASE_LIBS ON) # only find release libs - set(Boost_USE_MULTITHREADED ON) - set(Boost_USE_STATIC_RUNTIME OFF) - find_package(Boost 1.66.0 COMPONENTS date_time filesystem system ...) - if(Boost_FOUND) - include_directories(${Boost_INCLUDE_DIRS}) - add_executable(foo foo.cc) - target_link_libraries(foo ${Boost_LIBRARIES}) - endif() - -.. _`Boost CMake`: - -Boost CMake -^^^^^^^^^^^ - -If Boost was built using the boost-cmake project or from Boost 1.70.0 on -it provides a package configuration file for use with find_package's config mode. -This module looks for the package configuration file called -``BoostConfig.cmake`` or ``boost-config.cmake`` and stores the result in -``CACHE`` entry ``Boost_DIR``. If found, the package configuration file is loaded -and this module returns with no further action. See documentation of -the Boost CMake package configuration for details on what it provides. - -Set ``Boost_NO_BOOST_CMAKE`` to ``ON``, to disable the search for boost-cmake. -#]=======================================================================] - -if(POLICY CMP0167) - cmake_policy(GET CMP0167 _FindBoost_CMP0167) - if(_FindBoost_CMP0167 STREQUAL "NEW") - message(FATAL_ERROR "The FindBoost module has been removed by policy CMP0167.") - endif() -endif() - -if(_FindBoost_testing) - set(_FindBoost_included TRUE) - return() -endif() - -# The FPHSA helper provides standard way of reporting final search results to -# the user including the version and component checks. -include(FindPackageHandleStandardArgs) - -# Save project's policies -cmake_policy(PUSH) -cmake_policy(SET CMP0057 NEW) # if IN_LIST -if(POLICY CMP0102) - cmake_policy(SET CMP0102 NEW) # if mark_as_advanced(non_cache_var) -endif() -if(POLICY CMP0159) - cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_ -endif() - -function(_boost_get_existing_target component target_var) - set(names "${component}") - if(component MATCHES "^([a-z_]*)(python|numpy)([1-9])\\.?([0-9]+)?$") - # handle pythonXY and numpyXY versioned components and also python X.Y, mpi_python etc. - list(APPEND names - "${CMAKE_MATCH_1}${CMAKE_MATCH_2}" # python - "${CMAKE_MATCH_1}${CMAKE_MATCH_2}${CMAKE_MATCH_3}" # pythonX - "${CMAKE_MATCH_1}${CMAKE_MATCH_2}${CMAKE_MATCH_3}${CMAKE_MATCH_4}" #pythonXY - ) - endif() - # https://github.com/boost-cmake/boost-cmake uses boost::file_system etc. - # So handle similar constructions of target names - string(TOLOWER "${component}" lower_component) - list(APPEND names "${lower_component}") - foreach(prefix Boost boost) - foreach(name IN LISTS names) - if(TARGET "${prefix}::${name}") - # The target may be an INTERFACE library that wraps around a single other - # target for compatibility. Unwrap this layer so we can extract real info. - if("${name}" MATCHES "^(python|numpy|mpi_python)([1-9])([0-9]+)$") - set(name_nv "${CMAKE_MATCH_1}") - if(TARGET "${prefix}::${name_nv}") - get_property(type TARGET "${prefix}::${name}" PROPERTY TYPE) - if(type STREQUAL "INTERFACE_LIBRARY") - get_property(lib TARGET "${prefix}::${name}" PROPERTY INTERFACE_LINK_LIBRARIES) - if("${lib}" STREQUAL "${prefix}::${name_nv}") - set(${target_var} "${prefix}::${name_nv}" PARENT_SCOPE) - return() - endif() - endif() - endif() - endif() - set(${target_var} "${prefix}::${name}" PARENT_SCOPE) - return() - endif() - endforeach() - endforeach() - set(${target_var} "" PARENT_SCOPE) -endfunction() - -function(_boost_get_canonical_target_name component target_var) - string(TOLOWER "${component}" component) - if(component MATCHES "^([a-z_]*)(python|numpy)([1-9])\\.?([0-9]+)?$") - # handle pythonXY and numpyXY versioned components and also python X.Y, mpi_python etc. - set(${target_var} "Boost::${CMAKE_MATCH_1}${CMAKE_MATCH_2}" PARENT_SCOPE) - else() - set(${target_var} "Boost::${component}" PARENT_SCOPE) - endif() -endfunction() - -macro(_boost_set_in_parent_scope name value) - # Set a variable in parent scope and make it visible in current scope - set(${name} "${value}" PARENT_SCOPE) - set(${name} "${value}") -endmacro() - -macro(_boost_set_if_unset name value) - if(NOT ${name}) - _boost_set_in_parent_scope(${name} "${value}") - endif() -endmacro() - -macro(_boost_set_cache_if_unset name value) - if(NOT ${name}) - set(${name} "${value}" CACHE STRING "" FORCE) - endif() -endmacro() - -macro(_boost_append_include_dir target) - get_target_property(inc "${target}" INTERFACE_INCLUDE_DIRECTORIES) - if(inc) - list(APPEND include_dirs "${inc}") - endif() -endmacro() - -function(_boost_set_legacy_variables_from_config) - # Set legacy variables for compatibility if not set - set(include_dirs "") - set(library_dirs "") - set(libraries "") - # Header targets Boost::headers or Boost::boost - foreach(comp headers boost) - _boost_get_existing_target(${comp} target) - if(target) - _boost_append_include_dir("${target}") - endif() - endforeach() - # Library targets - foreach(comp IN LISTS Boost_FIND_COMPONENTS) - string(TOUPPER ${comp} uppercomp) - # Overwrite if set - _boost_set_in_parent_scope(Boost_${uppercomp}_FOUND "${Boost_${comp}_FOUND}") - if(Boost_${comp}_FOUND) - _boost_get_existing_target(${comp} target) - if(NOT target) - if(Boost_DEBUG OR Boost_VERBOSE) - message(WARNING "Could not find imported target for required component '${comp}'. Legacy variables for this component might be missing. Refer to the documentation of your Boost installation for help on variables to use.") - endif() - continue() - endif() - _boost_append_include_dir("${target}") - _boost_set_if_unset(Boost_${uppercomp}_LIBRARY "${target}") - _boost_set_if_unset(Boost_${uppercomp}_LIBRARIES "${target}") # Very old legacy variable - list(APPEND libraries "${target}") - get_property(type TARGET "${target}" PROPERTY TYPE) - if(NOT type STREQUAL "INTERFACE_LIBRARY") - foreach(cfg RELEASE DEBUG) - get_target_property(lib ${target} IMPORTED_LOCATION_${cfg}) - if(lib) - get_filename_component(lib_dir "${lib}" DIRECTORY) - list(APPEND library_dirs ${lib_dir}) - _boost_set_cache_if_unset(Boost_${uppercomp}_LIBRARY_${cfg} "${lib}") - endif() - endforeach() - elseif(Boost_DEBUG OR Boost_VERBOSE) - # For projects using only the Boost::* targets this warning can be safely ignored. - message(WARNING "Imported target '${target}' for required component '${comp}' has no artifact. Legacy variables for this component might be missing. Refer to the documentation of your Boost installation for help on variables to use.") - endif() - _boost_get_canonical_target_name("${comp}" canonical_target) - if(NOT TARGET "${canonical_target}") - add_library("${canonical_target}" INTERFACE IMPORTED) - target_link_libraries("${canonical_target}" INTERFACE "${target}") - endif() - endif() - endforeach() - list(REMOVE_DUPLICATES include_dirs) - list(REMOVE_DUPLICATES library_dirs) - _boost_set_if_unset(Boost_INCLUDE_DIRS "${include_dirs}") - _boost_set_if_unset(Boost_LIBRARY_DIRS "${library_dirs}") - _boost_set_if_unset(Boost_LIBRARIES "${libraries}") - _boost_set_if_unset(Boost_VERSION_STRING "${Boost_VERSION_MAJOR}.${Boost_VERSION_MINOR}.${Boost_VERSION_PATCH}") - find_path(Boost_INCLUDE_DIR - NAMES boost/version.hpp boost/config.hpp - HINTS ${Boost_INCLUDE_DIRS} - NO_DEFAULT_PATH - ) - if(NOT Boost_VERSION_MACRO OR NOT Boost_LIB_VERSION) - set(version_file ${Boost_INCLUDE_DIR}/boost/version.hpp) - if(EXISTS "${version_file}") - file(STRINGS "${version_file}" contents REGEX "#define BOOST_(LIB_)?VERSION ") - if(contents MATCHES "#define BOOST_VERSION ([0-9]+)") - _boost_set_if_unset(Boost_VERSION_MACRO "${CMAKE_MATCH_1}") - endif() - if(contents MATCHES "#define BOOST_LIB_VERSION \"([0-9_]+)\"") - _boost_set_if_unset(Boost_LIB_VERSION "${CMAKE_MATCH_1}") - endif() - endif() - endif() - _boost_set_if_unset(Boost_MAJOR_VERSION ${Boost_VERSION_MAJOR}) - _boost_set_if_unset(Boost_MINOR_VERSION ${Boost_VERSION_MINOR}) - _boost_set_if_unset(Boost_SUBMINOR_VERSION ${Boost_VERSION_PATCH}) - if(WIN32) - _boost_set_if_unset(Boost_LIB_DIAGNOSTIC_DEFINITIONS "-DBOOST_LIB_DIAGNOSTIC") - endif() - if(NOT TARGET Boost::headers) - add_library(Boost::headers INTERFACE IMPORTED) - target_include_directories(Boost::headers INTERFACE ${Boost_INCLUDE_DIRS}) - endif() - # Legacy targets w/o functionality as all handled by defined targets - foreach(lib diagnostic_definitions disable_autolinking dynamic_linking) - if(NOT TARGET Boost::${lib}) - add_library(Boost::${lib} INTERFACE IMPORTED) - endif() - endforeach() - if(NOT TARGET Boost::boost) - add_library(Boost::boost INTERFACE IMPORTED) - target_link_libraries(Boost::boost INTERFACE Boost::headers) - endif() -endfunction() - -#------------------------------------------------------------------------------- -# Before we go searching, check whether a boost cmake package is available, unless -# the user specifically asked NOT to search for one. -# -# If Boost_DIR is set, this behaves as any find_package call would. If not, -# it looks at BOOST_ROOT and BOOSTROOT to find Boost. -# -if (NOT Boost_NO_BOOST_CMAKE) - # If Boost_DIR is not set, look for BOOSTROOT and BOOST_ROOT as alternatives, - # since these are more conventional for Boost. - if ("$ENV{Boost_DIR}" STREQUAL "") - if (NOT "$ENV{BOOST_ROOT}" STREQUAL "") - set(ENV{Boost_DIR} $ENV{BOOST_ROOT}) - elseif (NOT "$ENV{BOOSTROOT}" STREQUAL "") - set(ENV{Boost_DIR} $ENV{BOOSTROOT}) - endif() - endif() - - set(_boost_FIND_PACKAGE_ARGS "") - if(Boost_NO_SYSTEM_PATHS) - list(APPEND _boost_FIND_PACKAGE_ARGS NO_CMAKE_SYSTEM_PATH NO_SYSTEM_ENVIRONMENT_PATH) - endif() - - # Do the same find_package call but look specifically for the CMake version. - # Note that args are passed in the Boost_FIND_xxxxx variables, so there is no - # need to delegate them to this find_package call. - cmake_policy(PUSH) - if(BOOST_ROOT AND NOT Boost_ROOT) - # Honor BOOST_ROOT by setting Boost_ROOT with CMP0074 NEW behavior. - if(POLICY CMP0074) - cmake_policy(SET CMP0074 NEW) - endif() - set(Boost_ROOT "${BOOST_ROOT}") - set(_Boost_ROOT_FOR_CONFIG 1) - endif() - find_package(Boost QUIET NO_MODULE ${_boost_FIND_PACKAGE_ARGS}) - cmake_policy(POP) - if (DEFINED Boost_DIR) - mark_as_advanced(Boost_DIR) - endif () - - # If we found a boost cmake package, then we're done. Print out what we found. - # Otherwise let the rest of the module try to find it. - if(Boost_FOUND) - # Convert component found variables to standard variables if required - # Necessary for legacy boost-cmake and 1.70 builtin BoostConfig - if(Boost_FIND_COMPONENTS) - # Ignore the meta-component "ALL", introduced by Boost 1.73 - list(REMOVE_ITEM Boost_FIND_COMPONENTS "ALL") - - foreach(_comp IN LISTS Boost_FIND_COMPONENTS) - if(DEFINED Boost_${_comp}_FOUND) - continue() - endif() - string(TOUPPER ${_comp} _uppercomp) - if(DEFINED Boost${_comp}_FOUND) # legacy boost-cmake project - set(Boost_${_comp}_FOUND ${Boost${_comp}_FOUND}) - elseif(DEFINED Boost_${_uppercomp}_FOUND) # Boost 1.70 - set(Boost_${_comp}_FOUND ${Boost_${_uppercomp}_FOUND}) - endif() - endforeach() - endif() - - find_package_handle_standard_args(Boost HANDLE_COMPONENTS CONFIG_MODE) - _boost_set_legacy_variables_from_config() - - # Restore project's policies - cmake_policy(POP) - return() - endif() -endif() - - -#------------------------------------------------------------------------------- -# FindBoost functions & macros -# - -# -# Print debug text if Boost_DEBUG is set. -# Call example: -# _Boost_DEBUG_PRINT("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "debug message") -# -function(_Boost_DEBUG_PRINT file line text) - if(Boost_DEBUG) - message(STATUS "[ ${file}:${line} ] ${text}") - endif() -endfunction() - -# -# _Boost_DEBUG_PRINT_VAR(file line variable_name [ENVIRONMENT] -# [SOURCE "short explanation of origin of var value"]) -# -# ENVIRONMENT - look up environment variable instead of CMake variable -# -# Print variable name and its value if Boost_DEBUG is set. -# Call example: -# _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" BOOST_ROOT) -# -function(_Boost_DEBUG_PRINT_VAR file line name) - if(Boost_DEBUG) - cmake_parse_arguments(_args "ENVIRONMENT" "SOURCE" "" ${ARGN}) - - unset(source) - if(_args_SOURCE) - set(source " (${_args_SOURCE})") - endif() - - if(_args_ENVIRONMENT) - if(DEFINED ENV{${name}}) - set(value "\"$ENV{${name}}\"") - else() - set(value "") - endif() - set(_name "ENV{${name}}") - else() - if(DEFINED "${name}") - set(value "\"${${name}}\"") - else() - set(value "") - endif() - set(_name "${name}") - endif() - - _Boost_DEBUG_PRINT("${file}" "${line}" "${_name} = ${value}${source}") - endif() -endfunction() - -############################################ -# -# Check the existence of the libraries. -# -############################################ -# This macro was taken directly from the FindQt4.cmake file that is included -# with the CMake distribution. This is NOT my work. All work was done by the -# original authors of the FindQt4.cmake file. Only minor modifications were -# made to remove references to Qt and make this file more generally applicable -# And ELSE/ENDIF pairs were removed for readability. -######################################################################### - -macro(_Boost_ADJUST_LIB_VARS basename) - if(Boost_INCLUDE_DIR ) - if(Boost_${basename}_LIBRARY_DEBUG AND Boost_${basename}_LIBRARY_RELEASE) - # if the generator is multi-config or if CMAKE_BUILD_TYPE is set for - # single-config generators, set optimized and debug libraries - get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) - if(_isMultiConfig OR CMAKE_BUILD_TYPE) - set(Boost_${basename}_LIBRARY optimized ${Boost_${basename}_LIBRARY_RELEASE} debug ${Boost_${basename}_LIBRARY_DEBUG}) - else() - # For single-config generators where CMAKE_BUILD_TYPE has no value, - # just use the release libraries - set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE} ) - endif() - # FIXME: This probably should be set for both cases - set(Boost_${basename}_LIBRARIES optimized ${Boost_${basename}_LIBRARY_RELEASE} debug ${Boost_${basename}_LIBRARY_DEBUG}) - endif() - - # if only the release version was found, set the debug variable also to the release version - if(Boost_${basename}_LIBRARY_RELEASE AND NOT Boost_${basename}_LIBRARY_DEBUG) - set(Boost_${basename}_LIBRARY_DEBUG ${Boost_${basename}_LIBRARY_RELEASE}) - set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE}) - set(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_RELEASE}) - endif() - - # if only the debug version was found, set the release variable also to the debug version - if(Boost_${basename}_LIBRARY_DEBUG AND NOT Boost_${basename}_LIBRARY_RELEASE) - set(Boost_${basename}_LIBRARY_RELEASE ${Boost_${basename}_LIBRARY_DEBUG}) - set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_DEBUG}) - set(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_DEBUG}) - endif() - - # If the debug & release library ends up being the same, omit the keywords - if("${Boost_${basename}_LIBRARY_RELEASE}" STREQUAL "${Boost_${basename}_LIBRARY_DEBUG}") - set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE} ) - set(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_RELEASE} ) - endif() - - if(Boost_${basename}_LIBRARY AND Boost_${basename}_HEADER) - set(Boost_${basename}_FOUND ON) - if("x${basename}" STREQUAL "xTHREAD" AND NOT TARGET Threads::Threads) - string(APPEND Boost_ERROR_REASON_THREAD " (missing dependency: Threads)") - set(Boost_THREAD_FOUND OFF) - endif() - endif() - - endif() - # Make variables changeable to the advanced user - mark_as_advanced( - Boost_${basename}_LIBRARY_RELEASE - Boost_${basename}_LIBRARY_DEBUG - ) -endmacro() - -# Detect changes in used variables. -# Compares the current variable value with the last one. -# In short form: -# v != v_LAST -> CHANGED = 1 -# v is defined, v_LAST not -> CHANGED = 1 -# v is not defined, but v_LAST is -> CHANGED = 1 -# otherwise -> CHANGED = 0 -# CHANGED is returned in variable named ${changed_var} -macro(_Boost_CHANGE_DETECT changed_var) - set(${changed_var} 0) - foreach(v ${ARGN}) - if(DEFINED _Boost_COMPONENTS_SEARCHED) - if(${v}) - if(_${v}_LAST) - string(COMPARE NOTEQUAL "${${v}}" "${_${v}_LAST}" _${v}_CHANGED) - else() - set(_${v}_CHANGED 1) - endif() - elseif(_${v}_LAST) - set(_${v}_CHANGED 1) - endif() - if(_${v}_CHANGED) - set(${changed_var} 1) - endif() - else() - set(_${v}_CHANGED 0) - endif() - endforeach() -endmacro() - -# -# Find the given library (var). -# Use 'build_type' to support different lib paths for RELEASE or DEBUG builds -# -macro(_Boost_FIND_LIBRARY var build_type) - - find_library(${var} ${ARGN}) - - if(${var}) - # If this is the first library found then save Boost_LIBRARY_DIR_[RELEASE,DEBUG]. - if(NOT Boost_LIBRARY_DIR_${build_type}) - get_filename_component(_dir "${${var}}" PATH) - set(Boost_LIBRARY_DIR_${build_type} "${_dir}" CACHE PATH "Boost library directory ${build_type}" FORCE) - endif() - elseif(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT) - # Try component-specific hints but do not save Boost_LIBRARY_DIR_[RELEASE,DEBUG]. - find_library(${var} HINTS ${_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT} ${ARGN}) - endif() - - # If Boost_LIBRARY_DIR_[RELEASE,DEBUG] is known then search only there. - if(Boost_LIBRARY_DIR_${build_type}) - set(_boost_LIBRARY_SEARCH_DIRS_${build_type} ${Boost_LIBRARY_DIR_${build_type}} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) - _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" - "Boost_LIBRARY_DIR_${build_type}") - _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" - "_boost_LIBRARY_SEARCH_DIRS_${build_type}") - endif() -endmacro() - -#------------------------------------------------------------------------------- - -# Convert CMAKE_CXX_COMPILER_VERSION to boost compiler suffix version. -function(_Boost_COMPILER_DUMPVERSION _OUTPUT_VERSION _OUTPUT_VERSION_MAJOR _OUTPUT_VERSION_MINOR) - string(REGEX REPLACE "([0-9]+)\\.([0-9]+)(\\.[0-9]+)?" "\\1" - _boost_COMPILER_VERSION_MAJOR "${CMAKE_CXX_COMPILER_VERSION}") - string(REGEX REPLACE "([0-9]+)\\.([0-9]+)(\\.[0-9]+)?" "\\2" - _boost_COMPILER_VERSION_MINOR "${CMAKE_CXX_COMPILER_VERSION}") - - set(_boost_COMPILER_VERSION "${_boost_COMPILER_VERSION_MAJOR}${_boost_COMPILER_VERSION_MINOR}") - - set(${_OUTPUT_VERSION} ${_boost_COMPILER_VERSION} PARENT_SCOPE) - set(${_OUTPUT_VERSION_MAJOR} ${_boost_COMPILER_VERSION_MAJOR} PARENT_SCOPE) - set(${_OUTPUT_VERSION_MINOR} ${_boost_COMPILER_VERSION_MINOR} PARENT_SCOPE) -endfunction() - -# -# Take a list of libraries with "thread" in it -# and prepend duplicates with "thread_${Boost_THREADAPI}" -# at the front of the list -# -function(_Boost_PREPEND_LIST_WITH_THREADAPI _output) - set(_orig_libnames ${ARGN}) - string(REPLACE "thread" "thread_${Boost_THREADAPI}" _threadapi_libnames "${_orig_libnames}") - set(${_output} ${_threadapi_libnames} ${_orig_libnames} PARENT_SCOPE) -endfunction() - -# -# If a library is found, replace its cache entry with its REALPATH -# -function(_Boost_SWAP_WITH_REALPATH _library _docstring) - if(${_library}) - get_filename_component(_boost_filepathreal ${${_library}} REALPATH) - unset(${_library} CACHE) - set(${_library} ${_boost_filepathreal} CACHE FILEPATH "${_docstring}") - endif() -endfunction() - -function(_Boost_CHECK_SPELLING _var) - if(${_var}) - string(TOUPPER ${_var} _var_UC) - message(FATAL_ERROR "ERROR: ${_var} is not the correct spelling. The proper spelling is ${_var_UC}.") - endif() -endfunction() - -# Guesses Boost's compiler prefix used in built library names -# Returns the guess by setting the variable pointed to by _ret -function(_Boost_GUESS_COMPILER_PREFIX _ret) - if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xIntel" - OR "x${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "xIntelLLVM") - if(WIN32) - set (_boost_COMPILER "-iw") - else() - set (_boost_COMPILER "-il") - endif() - elseif (GHSMULTI) - set(_boost_COMPILER "-ghs") - elseif("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" OR "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") - if(MSVC_TOOLSET_VERSION GREATER_EQUAL 150) - # Not yet known. - set(_boost_COMPILER "") - elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 140) - # MSVC toolset 14.x versions are forward compatible. - set(_boost_COMPILER "") - foreach(v 9 8 7 6 5 4 3 2 1 0) - if(MSVC_TOOLSET_VERSION GREATER_EQUAL 14${v}) - list(APPEND _boost_COMPILER "-vc14${v}") - endif() - endforeach() - elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 80) - set(_boost_COMPILER "-vc${MSVC_TOOLSET_VERSION}") - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.10) - set(_boost_COMPILER "-vc71") - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13) # Good luck! - set(_boost_COMPILER "-vc7") # yes, this is correct - else() # VS 6.0 Good luck! - set(_boost_COMPILER "-vc6") # yes, this is correct - endif() - - if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xClang") - string(REPLACE "." ";" VERSION_LIST "${CMAKE_CXX_COMPILER_VERSION}") - list(GET VERSION_LIST 0 CLANG_VERSION_MAJOR) - set(_boost_COMPILER "-clangw${CLANG_VERSION_MAJOR};${_boost_COMPILER}") - endif() - elseif (BORLAND) - set(_boost_COMPILER "-bcb") - elseif(CMAKE_CXX_COMPILER_ID STREQUAL "SunPro") - set(_boost_COMPILER "-sw") - elseif(CMAKE_CXX_COMPILER_ID STREQUAL "XL") - set(_boost_COMPILER "-xlc") - elseif (MINGW) - if(Boost_VERSION_STRING VERSION_LESS 1.34) - set(_boost_COMPILER "-mgw") # no GCC version encoding prior to 1.34 - else() - _Boost_COMPILER_DUMPVERSION(_boost_COMPILER_VERSION _boost_COMPILER_VERSION_MAJOR _boost_COMPILER_VERSION_MINOR) - if(Boost_VERSION_STRING VERSION_GREATER_EQUAL 1.73 AND _boost_COMPILER_VERSION_MAJOR VERSION_GREATER_EQUAL 5) - set(_boost_COMPILER "-mgw${_boost_COMPILER_VERSION_MAJOR}") - else() - set(_boost_COMPILER "-mgw${_boost_COMPILER_VERSION}") - endif() - endif() - elseif (UNIX) - _Boost_COMPILER_DUMPVERSION(_boost_COMPILER_VERSION _boost_COMPILER_VERSION_MAJOR _boost_COMPILER_VERSION_MINOR) - if(NOT Boost_VERSION_STRING VERSION_LESS 1.69.0) - # From GCC 5 and clang 4, versioning changes and minor becomes patch. - # For those compilers, patch is exclude from compiler tag in Boost 1.69+ library naming. - if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND _boost_COMPILER_VERSION_MAJOR VERSION_GREATER 4) OR CMAKE_CXX_COMPILER_ID STREQUAL "LCC") - set(_boost_COMPILER_VERSION "${_boost_COMPILER_VERSION_MAJOR}") - elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND _boost_COMPILER_VERSION_MAJOR VERSION_GREATER 3) - set(_boost_COMPILER_VERSION "${_boost_COMPILER_VERSION_MAJOR}") - endif() - endif() - - if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "LCC") - if(Boost_VERSION_STRING VERSION_LESS 1.34) - set(_boost_COMPILER "-gcc") # no GCC version encoding prior to 1.34 - else() - # Determine which version of GCC we have. - if(APPLE) - if(Boost_VERSION_STRING VERSION_LESS 1.36.0) - # In Boost <= 1.35.0, there is no mangled compiler name for - # the macOS/Darwin version of GCC. - set(_boost_COMPILER "") - else() - # In Boost 1.36.0 and newer, the mangled compiler name used - # on macOS/Darwin is "xgcc". - set(_boost_COMPILER "-xgcc${_boost_COMPILER_VERSION}") - endif() - else() - set(_boost_COMPILER "-gcc${_boost_COMPILER_VERSION}") - endif() - endif() - elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - # TODO: Find out any Boost version constraints vs clang support. - set(_boost_COMPILER "-clang${_boost_COMPILER_VERSION}") - endif() - else() - set(_boost_COMPILER "") - endif() - _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" - "_boost_COMPILER" SOURCE "guessed") - set(${_ret} ${_boost_COMPILER} PARENT_SCOPE) -endfunction() - -# -# Get component dependencies. Requires the dependencies to have been -# defined for the Boost release version. -# -# component - the component to check -# _ret - list of library dependencies -# -function(_Boost_COMPONENT_DEPENDENCIES component _ret) - # Note: to add a new Boost release, run - # - # % cmake -DBOOST_DIR=/path/to/boost/source -P Utilities/Scripts/BoostScanDeps.cmake - # - # The output may be added in a new block below. If it's the same as - # the previous release, simply update the version range of the block - # for the previous release. Also check if any new components have - # been added, and add any new components to - # _Boost_COMPONENT_HEADERS. - # - # This information was originally generated by running - # BoostScanDeps.cmake against every boost release to date supported - # by FindBoost: - # - # % for version in /path/to/boost/sources/* - # do - # cmake -DBOOST_DIR=$version -P Utilities/Scripts/BoostScanDeps.cmake - # done - # - # The output was then updated by search and replace with these regexes: - # - # - Strip message(STATUS) prefix dashes - # s;^-- ;; - # - Indent - # s;^set(; set(;; - # - Add conditionals - # s;Scanning /path/to/boost/sources/boost_\(.*\)_\(.*\)_\(.*); elseif(NOT Boost_VERSION_STRING VERSION_LESS \1\.\2\.\3 AND Boost_VERSION_STRING VERSION_LESS xxxx); - # - # This results in the logic seen below, but will require the xxxx - # replacing with the following Boost release version (or the next - # minor version to be released, e.g. 1.59 was the latest at the time - # of writing, making 1.60 the next. Identical consecutive releases - # were then merged together by updating the end range of the first - # block and removing the following redundant blocks. - # - # Running the script against all historical releases should be - # required only if the BoostScanDeps.cmake script logic is changed. - # The addition of a new release should only require it to be run - # against the new release. - - # Handle Python version suffixes - if(component MATCHES "^(python|mpi_python|numpy)([0-9][0-9]?|[0-9]\\.[0-9]+)\$") - set(component "${CMAKE_MATCH_1}") - set(component_python_version "${CMAKE_MATCH_2}") - endif() - - set(_Boost_IMPORTED_TARGETS TRUE) - if(Boost_VERSION_STRING) - if(Boost_VERSION_STRING VERSION_LESS 1.33.0) - message(WARNING "Imported targets and dependency information not available for Boost version ${Boost_VERSION_STRING} (all versions older than 1.33)") - set(_Boost_IMPORTED_TARGETS FALSE) - elseif(Boost_VERSION_STRING VERSION_LESS 1.35.0) - set(_Boost_IOSTREAMS_DEPENDENCIES regex thread) - set(_Boost_REGEX_DEPENDENCIES thread) - set(_Boost_WAVE_DEPENDENCIES filesystem thread) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.36.0) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_WAVE_DEPENDENCIES filesystem system thread) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.38.0) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_WAVE_DEPENDENCIES filesystem system thread) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.43.0) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES date_time) - set(_Boost_WAVE_DEPENDENCIES filesystem system thread date_time) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.44.0) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES date_time) - set(_Boost_WAVE_DEPENDENCIES filesystem system thread date_time) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.45.0) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random serialization) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES date_time) - set(_Boost_WAVE_DEPENDENCIES serialization filesystem system thread date_time) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.47.0) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES date_time) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.48.0) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES date_time) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.50.0) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES date_time) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.53.0) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.54.0) - set(_Boost_ATOMIC_DEPENDENCIES thread chrono system date_time) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.55.0) - set(_Boost_ATOMIC_DEPENDENCIES thread chrono system date_time) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.56.0) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.59.0) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.60.0) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.61.0) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.62.0) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.63.0) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.65.0) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_COROUTINE2_DEPENDENCIES context fiber thread chrono system date_time) - set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.67.0) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.68.0) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.69.0) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) - set(_Boost_CONTRACT_DEPENDENCIES thread chrono system date_time) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.70.0) - set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time) - set(_Boost_COROUTINE_DEPENDENCIES context) - set(_Boost_FIBER_DEPENDENCIES context) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) - set(_Boost_THREAD_DEPENDENCIES chrono date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.72.0) - set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time) - set(_Boost_COROUTINE_DEPENDENCIES context) - set(_Boost_FIBER_DEPENDENCIES context) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) - set(_Boost_THREAD_DEPENDENCIES chrono date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono) - set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.73.0) - set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time) - set(_Boost_COROUTINE_DEPENDENCIES context) - set(_Boost_FIBER_DEPENDENCIES context) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l chrono atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) - set(_Boost_THREAD_DEPENDENCIES chrono date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono) - set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.75.0) - set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time) - set(_Boost_COROUTINE_DEPENDENCIES context) - set(_Boost_FIBER_DEPENDENCIES context) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) - set(_Boost_THREAD_DEPENDENCIES chrono date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono) - set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.77.0) - set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time) - set(_Boost_COROUTINE_DEPENDENCIES context) - set(_Boost_FIBER_DEPENDENCIES context) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_JSON_DEPENDENCIES container) - set(_Boost_LOG_DEPENDENCIES date_time log_setup filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) - set(_Boost_THREAD_DEPENDENCIES chrono date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono) - set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.78.0) - set(_Boost_CONTRACT_DEPENDENCIES thread chrono) - set(_Boost_COROUTINE_DEPENDENCIES context) - set(_Boost_FIBER_DEPENDENCIES context) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_JSON_DEPENDENCIES container) - set(_Boost_LOG_DEPENDENCIES date_time log_setup filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) - set(_Boost_THREAD_DEPENDENCIES chrono atomic) - set(_Boost_TIMER_DEPENDENCIES chrono) - set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.83.0) - set(_Boost_CONTRACT_DEPENDENCIES thread chrono) - set(_Boost_COROUTINE_DEPENDENCIES context) - set(_Boost_FIBER_DEPENDENCIES context) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_JSON_DEPENDENCIES container) - set(_Boost_LOG_DEPENDENCIES log_setup filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) - set(_Boost_THREAD_DEPENDENCIES chrono atomic) - set(_Boost_TIMER_DEPENDENCIES chrono) - set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(Boost_VERSION_STRING VERSION_LESS 1.87.0) - set(_Boost_CONTRACT_DEPENDENCIES thread chrono) - set(_Boost_COROUTINE_DEPENDENCIES context) - set(_Boost_FIBER_DEPENDENCIES context) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_JSON_DEPENDENCIES container) - set(_Boost_LOG_DEPENDENCIES log_setup filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) - set(_Boost_THREAD_DEPENDENCIES chrono atomic) - set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - else() - set(_Boost_CONTRACT_DEPENDENCIES thread chrono) - set(_Boost_COROUTINE_DEPENDENCIES context) - set(_Boost_FIBER_DEPENDENCIES context) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_JSON_DEPENDENCIES container) - set(_Boost_LOG_DEPENDENCIES log_setup filesystem thread regex atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) - set(_Boost_PROCESS_DEPENDENCIES filesystem) - set(_Boost_THREAD_DEPENDENCIES chrono atomic) - set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - if(Boost_VERSION_STRING VERSION_GREATER_EQUAL 1.89.0 AND NOT Boost_NO_WARN_NEW_VERSIONS) - message(WARNING "New Boost version may have incorrect or missing dependencies and imported targets") - endif() - endif() - endif() - - string(TOUPPER ${component} uppercomponent) - set(${_ret} ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE) - set(_Boost_IMPORTED_TARGETS ${_Boost_IMPORTED_TARGETS} PARENT_SCOPE) - - string(REGEX REPLACE ";" " " _boost_DEPS_STRING "${_Boost_${uppercomponent}_DEPENDENCIES}") - if (NOT _boost_DEPS_STRING) - set(_boost_DEPS_STRING "(none)") - endif() - # message(STATUS "Dependencies for Boost::${component}: ${_boost_DEPS_STRING}") -endfunction() - -# -# Get component headers. This is the primary header (or headers) for -# a given component, and is used to check that the headers are present -# as well as the library itself as an extra sanity check of the build -# environment. -# -# component - the component to check -# _hdrs -# -function(_Boost_COMPONENT_HEADERS component _hdrs) - # Handle Python version suffixes - if(component MATCHES "^(python|mpi_python|numpy)([0-9]+|[0-9]\\.[0-9]+)\$") - set(component "${CMAKE_MATCH_1}") - set(component_python_version "${CMAKE_MATCH_2}") - endif() - - # Note: new boost components will require adding here. The header - # must be present in all versions of Boost providing a library. - set(_Boost_ATOMIC_HEADERS "boost/atomic.hpp") - set(_Boost_CHRONO_HEADERS "boost/chrono.hpp") - set(_Boost_CONTAINER_HEADERS "boost/container/container_fwd.hpp") - set(_Boost_CONTRACT_HEADERS "boost/contract.hpp") - if(Boost_VERSION_STRING VERSION_LESS 1.61.0) - set(_Boost_CONTEXT_HEADERS "boost/context/all.hpp") - else() - set(_Boost_CONTEXT_HEADERS "boost/context/detail/fcontext.hpp") - endif() - set(_Boost_COROUTINE_HEADERS "boost/coroutine/all.hpp") - set(_Boost_DATE_TIME_HEADERS "boost/date_time/date.hpp") - set(_Boost_EXCEPTION_HEADERS "boost/exception/exception.hpp") - set(_Boost_FIBER_HEADERS "boost/fiber/all.hpp") - set(_Boost_FILESYSTEM_HEADERS "boost/filesystem/path.hpp") - set(_Boost_GRAPH_HEADERS "boost/graph/adjacency_list.hpp") - set(_Boost_GRAPH_PARALLEL_HEADERS "boost/graph/adjacency_list.hpp") - set(_Boost_IOSTREAMS_HEADERS "boost/iostreams/stream.hpp") - set(_Boost_LOCALE_HEADERS "boost/locale.hpp") - set(_Boost_LOG_HEADERS "boost/log/core.hpp") - set(_Boost_LOG_SETUP_HEADERS "boost/log/detail/setup_config.hpp") - set(_Boost_JSON_HEADERS "boost/json.hpp") - set(_Boost_MATH_HEADERS "boost/math_fwd.hpp") - set(_Boost_MATH_C99_HEADERS "boost/math/tr1.hpp") - set(_Boost_MATH_C99F_HEADERS "boost/math/tr1.hpp") - set(_Boost_MATH_C99L_HEADERS "boost/math/tr1.hpp") - set(_Boost_MATH_TR1_HEADERS "boost/math/tr1.hpp") - set(_Boost_MATH_TR1F_HEADERS "boost/math/tr1.hpp") - set(_Boost_MATH_TR1L_HEADERS "boost/math/tr1.hpp") - set(_Boost_MPI_HEADERS "boost/mpi.hpp") - set(_Boost_MPI_PYTHON_HEADERS "boost/mpi/python/config.hpp") - set(_Boost_MYSQL_HEADERS "boost/mysql.hpp") - set(_Boost_NUMPY_HEADERS "boost/python/numpy.hpp") - set(_Boost_NOWIDE_HEADERS "boost/nowide/cstdlib.hpp") - set(_Boost_PRG_EXEC_MONITOR_HEADERS "boost/test/prg_exec_monitor.hpp") - set(_Boost_PROGRAM_OPTIONS_HEADERS "boost/program_options.hpp") - set(_Boost_PYTHON_HEADERS "boost/python.hpp") - set(_Boost_RANDOM_HEADERS "boost/random.hpp") - set(_Boost_REGEX_HEADERS "boost/regex.hpp") - set(_Boost_SERIALIZATION_HEADERS "boost/serialization/serialization.hpp") - set(_Boost_SIGNALS_HEADERS "boost/signals.hpp") - set(_Boost_STACKTRACE_ADDR2LINE_HEADERS "boost/stacktrace.hpp") - set(_Boost_STACKTRACE_BACKTRACE_HEADERS "boost/stacktrace.hpp") - set(_Boost_STACKTRACE_BASIC_HEADERS "boost/stacktrace.hpp") - set(_Boost_STACKTRACE_NOOP_HEADERS "boost/stacktrace.hpp") - set(_Boost_STACKTRACE_WINDBG_CACHED_HEADERS "boost/stacktrace.hpp") - set(_Boost_STACKTRACE_WINDBG_HEADERS "boost/stacktrace.hpp") - set(_Boost_SYSTEM_HEADERS "boost/system/config.hpp") - set(_Boost_TEST_EXEC_MONITOR_HEADERS "boost/test/test_exec_monitor.hpp") - set(_Boost_THREAD_HEADERS "boost/thread.hpp") - set(_Boost_TIMER_HEADERS "boost/timer.hpp") - set(_Boost_TYPE_ERASURE_HEADERS "boost/type_erasure/config.hpp") - set(_Boost_UNIT_TEST_FRAMEWORK_HEADERS "boost/test/framework.hpp") - set(_Boost_URL_HEADERS "boost/url.hpp") - set(_Boost_WAVE_HEADERS "boost/wave.hpp") - set(_Boost_WSERIALIZATION_HEADERS "boost/archive/text_wiarchive.hpp") - set(_Boost_BZIP2_HEADERS "boost/iostreams/filter/bzip2.hpp") - set(_Boost_ZLIB_HEADERS "boost/iostreams/filter/zlib.hpp") - - string(TOUPPER ${component} uppercomponent) - set(${_hdrs} ${_Boost_${uppercomponent}_HEADERS} PARENT_SCOPE) - - string(REGEX REPLACE ";" " " _boost_HDRS_STRING "${_Boost_${uppercomponent}_HEADERS}") - if (NOT _boost_HDRS_STRING) - set(_boost_HDRS_STRING "(none)") - endif() - # message(STATUS "Headers for Boost::${component}: ${_boost_HDRS_STRING}") -endfunction() - -# -# Determine if any missing dependencies require adding to the component list. -# -# Sets _Boost_${COMPONENT}_DEPENDENCIES for each required component, -# plus _Boost_IMPORTED_TARGETS (TRUE if imported targets should be -# defined; FALSE if dependency information is unavailable). -# -# componentvar - the component list variable name -# extravar - the indirect dependency list variable name -# -# -function(_Boost_MISSING_DEPENDENCIES componentvar extravar) - # _boost_unprocessed_components - list of components requiring processing - # _boost_processed_components - components already processed (or currently being processed) - # _boost_new_components - new components discovered for future processing - # - list(APPEND _boost_unprocessed_components ${${componentvar}}) - - while(_boost_unprocessed_components) - list(APPEND _boost_processed_components ${_boost_unprocessed_components}) - foreach(component ${_boost_unprocessed_components}) - string(TOUPPER ${component} uppercomponent) - set(${_ret} ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE) - _Boost_COMPONENT_DEPENDENCIES("${component}" _Boost_${uppercomponent}_DEPENDENCIES) - set(_Boost_${uppercomponent}_DEPENDENCIES ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE) - set(_Boost_IMPORTED_TARGETS ${_Boost_IMPORTED_TARGETS} PARENT_SCOPE) - foreach(componentdep ${_Boost_${uppercomponent}_DEPENDENCIES}) - if (NOT ("${componentdep}" IN_LIST _boost_processed_components OR "${componentdep}" IN_LIST _boost_new_components)) - list(APPEND _boost_new_components ${componentdep}) - endif() - endforeach() - endforeach() - set(_boost_unprocessed_components ${_boost_new_components}) - unset(_boost_new_components) - endwhile() - set(_boost_extra_components ${_boost_processed_components}) - if(_boost_extra_components AND ${componentvar}) - list(REMOVE_ITEM _boost_extra_components ${${componentvar}}) - endif() - set(${componentvar} ${_boost_processed_components} PARENT_SCOPE) - set(${extravar} ${_boost_extra_components} PARENT_SCOPE) -endfunction() - -# -# Some boost libraries may require particular set of compler features. -# The very first one was `boost::fiber` introduced in Boost 1.62. -# One can check required compiler features of it in -# - `${Boost_ROOT}/libs/fiber/build/Jamfile.v2`; -# - `${Boost_ROOT}/libs/context/build/Jamfile.v2`. -# -# TODO (Re)Check compiler features on (every?) release ??? -# One may use the following command to get the files to check: -# -# $ find . -name Jamfile.v2 | grep build | xargs grep -l cxx1 -# -function(_Boost_COMPILER_FEATURES component _ret) - # Boost >= 1.62 - if(NOT Boost_VERSION_STRING VERSION_LESS 1.62.0) - set(_Boost_FIBER_COMPILER_FEATURES - cxx_alias_templates - cxx_auto_type - cxx_constexpr - cxx_defaulted_functions - cxx_final - cxx_lambdas - cxx_noexcept - cxx_nullptr - cxx_rvalue_references - cxx_thread_local - cxx_variadic_templates - ) - # Compiler feature for `context` same as for `fiber`. - set(_Boost_CONTEXT_COMPILER_FEATURES ${_Boost_FIBER_COMPILER_FEATURES}) - endif() - - # Boost Contract library available in >= 1.67 - if(NOT Boost_VERSION_STRING VERSION_LESS 1.67.0) - # From `libs/contract/build/boost_contract_build.jam` - set(_Boost_CONTRACT_COMPILER_FEATURES - cxx_lambdas - cxx_variadic_templates - ) - endif() - - string(TOUPPER ${component} uppercomponent) - set(${_ret} ${_Boost_${uppercomponent}_COMPILER_FEATURES} PARENT_SCOPE) -endfunction() - -# -# Update library search directory hint variable with paths used by prebuilt boost binaries. -# -# Prebuilt windows binaries (https://sourceforge.net/projects/boost/files/boost-binaries/) -# have library directories named using MSVC compiler version and architecture. -# This function would append corresponding directories if MSVC is a current compiler, -# so having `BOOST_ROOT` would be enough to specify to find everything. -# -function(_Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS componentlibvar basedir) - if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC") - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(_arch_suffix 64) - else() - set(_arch_suffix 32) - endif() - if(MSVC_TOOLSET_VERSION GREATER_EQUAL 150) - # Not yet known. - elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 140) - # MSVC toolset 14.x versions are forward compatible. - foreach(v 9 8 7 6 5 4 3 2 1 0) - if(MSVC_TOOLSET_VERSION GREATER_EQUAL 14${v}) - list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-14.${v}) - endif() - endforeach() - elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 80) - math(EXPR _toolset_major_version "${MSVC_TOOLSET_VERSION} / 10") - list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-${_toolset_major_version}.0) - endif() - set(${componentlibvar} ${${componentlibvar}} PARENT_SCOPE) - endif() -endfunction() - -# -# End functions/macros -# -#------------------------------------------------------------------------------- - -#------------------------------------------------------------------------------- -# main. -#------------------------------------------------------------------------------- - - -# If the user sets Boost_LIBRARY_DIR, use it as the default for both -# configurations. -if(NOT Boost_LIBRARY_DIR_RELEASE AND Boost_LIBRARY_DIR) - set(Boost_LIBRARY_DIR_RELEASE "${Boost_LIBRARY_DIR}") -endif() -if(NOT Boost_LIBRARY_DIR_DEBUG AND Boost_LIBRARY_DIR) - set(Boost_LIBRARY_DIR_DEBUG "${Boost_LIBRARY_DIR}") -endif() - -if(NOT DEFINED Boost_USE_DEBUG_LIBS) - set(Boost_USE_DEBUG_LIBS TRUE) -endif() -if(NOT DEFINED Boost_USE_RELEASE_LIBS) - set(Boost_USE_RELEASE_LIBS TRUE) -endif() -if(NOT DEFINED Boost_USE_MULTITHREADED) - set(Boost_USE_MULTITHREADED TRUE) -endif() -if(NOT DEFINED Boost_USE_DEBUG_RUNTIME) - set(Boost_USE_DEBUG_RUNTIME TRUE) -endif() - -# Check the version of Boost against the requested version. -if(Boost_FIND_VERSION AND NOT Boost_FIND_VERSION_MINOR) - message(SEND_ERROR "When requesting a specific version of Boost, you must provide at least the major and minor version numbers, e.g., 1.34") -endif() - -if(Boost_FIND_VERSION_EXACT) - # The version may appear in a directory with or without the patch - # level, even when the patch level is non-zero. - set(_boost_TEST_VERSIONS - "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}.${Boost_FIND_VERSION_PATCH}" - "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}") -else() - # The user has not requested an exact version. Among known - # versions, find those that are acceptable to the user request. - # - # Note: When adding a new Boost release, also update the dependency - # information in _Boost_COMPONENT_DEPENDENCIES and - # _Boost_COMPONENT_HEADERS. See the instructions at the top of - # _Boost_COMPONENT_DEPENDENCIES. - set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS} - "1.87.0" "1.87" "1.86.0" "1.86" "1.85.0" "1.85" "1.84.0" "1.84" - "1.83.0" "1.83" "1.82.0" "1.82" "1.81.0" "1.81" "1.80.0" "1.80" "1.79.0" "1.79" - "1.78.0" "1.78" "1.77.0" "1.77" "1.76.0" "1.76" "1.75.0" "1.75" "1.74.0" "1.74" - "1.73.0" "1.73" "1.72.0" "1.72" "1.71.0" "1.71" "1.70.0" "1.70" "1.69.0" "1.69" - "1.68.0" "1.68" "1.67.0" "1.67" "1.66.0" "1.66" "1.65.1" "1.65.0" "1.65" - "1.64.0" "1.64" "1.63.0" "1.63" "1.62.0" "1.62" "1.61.0" "1.61" "1.60.0" "1.60" - "1.59.0" "1.59" "1.58.0" "1.58" "1.57.0" "1.57" "1.56.0" "1.56" "1.55.0" "1.55" - "1.54.0" "1.54" "1.53.0" "1.53" "1.52.0" "1.52" "1.51.0" "1.51" - "1.50.0" "1.50" "1.49.0" "1.49" "1.48.0" "1.48" "1.47.0" "1.47" "1.46.1" - "1.46.0" "1.46" "1.45.0" "1.45" "1.44.0" "1.44" "1.43.0" "1.43" "1.42.0" "1.42" - "1.41.0" "1.41" "1.40.0" "1.40" "1.39.0" "1.39" "1.38.0" "1.38" "1.37.0" "1.37" - "1.36.1" "1.36.0" "1.36" "1.35.1" "1.35.0" "1.35" "1.34.1" "1.34.0" - "1.34" "1.33.1" "1.33.0" "1.33") - - set(_boost_TEST_VERSIONS) - if(Boost_FIND_VERSION) - set(_Boost_FIND_VERSION_SHORT "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}") - # Select acceptable versions. - foreach(version ${_Boost_KNOWN_VERSIONS}) - if(NOT "${version}" VERSION_LESS "${Boost_FIND_VERSION}") - # This version is high enough. - list(APPEND _boost_TEST_VERSIONS "${version}") - elseif("${version}.99" VERSION_EQUAL "${_Boost_FIND_VERSION_SHORT}.99") - # This version is a short-form for the requested version with - # the patch level dropped. - list(APPEND _boost_TEST_VERSIONS "${version}") - endif() - endforeach() - else() - # Any version is acceptable. - set(_boost_TEST_VERSIONS "${_Boost_KNOWN_VERSIONS}") - endif() -endif() - -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "_boost_TEST_VERSIONS") -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_USE_MULTITHREADED") -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_USE_STATIC_LIBS") -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_USE_STATIC_RUNTIME") -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_ADDITIONAL_VERSIONS") -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_NO_SYSTEM_PATHS") - -if(POLICY CMP0074) - cmake_policy(GET CMP0074 _Boost_CMP0074) - if(NOT "x${_Boost_CMP0074}x" STREQUAL "xNEWx") - _Boost_CHECK_SPELLING(Boost_ROOT) - endif() - unset(_Boost_CMP0074) -endif() -_Boost_CHECK_SPELLING(Boost_LIBRARYDIR) -_Boost_CHECK_SPELLING(Boost_INCLUDEDIR) - -# Collect environment variable inputs as hints. Do not consider changes. -foreach(v BOOSTROOT BOOST_ROOT BOOST_INCLUDEDIR BOOST_LIBRARYDIR) - set(_env $ENV{${v}}) - if(_env) - file(TO_CMAKE_PATH "${_env}" _ENV_${v}) - else() - set(_ENV_${v} "") - endif() -endforeach() -if(NOT _ENV_BOOST_ROOT AND _ENV_BOOSTROOT) - set(_ENV_BOOST_ROOT "${_ENV_BOOSTROOT}") -endif() - -# Collect inputs and cached results. Detect changes since the last run. -if(NOT BOOST_ROOT AND BOOSTROOT) - set(BOOST_ROOT "${BOOSTROOT}") -endif() -set(_Boost_VARS_DIR - BOOST_ROOT - Boost_NO_SYSTEM_PATHS - ) - -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "BOOST_ROOT") -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "BOOST_ROOT" ENVIRONMENT) -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "BOOST_INCLUDEDIR") -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "BOOST_INCLUDEDIR" ENVIRONMENT) -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "BOOST_LIBRARYDIR") -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "BOOST_LIBRARYDIR" ENVIRONMENT) - -# ------------------------------------------------------------------------ -# Search for Boost include DIR -# ------------------------------------------------------------------------ - -set(_Boost_VARS_INC BOOST_INCLUDEDIR Boost_INCLUDE_DIR Boost_ADDITIONAL_VERSIONS) -_Boost_CHANGE_DETECT(_Boost_CHANGE_INCDIR ${_Boost_VARS_DIR} ${_Boost_VARS_INC}) -# Clear Boost_INCLUDE_DIR if it did not change but other input affecting the -# location did. We will find a new one based on the new inputs. -if(_Boost_CHANGE_INCDIR AND NOT _Boost_INCLUDE_DIR_CHANGED) - unset(Boost_INCLUDE_DIR CACHE) -endif() - -if(NOT Boost_INCLUDE_DIR) - set(_boost_INCLUDE_SEARCH_DIRS "") - if(BOOST_INCLUDEDIR) - list(APPEND _boost_INCLUDE_SEARCH_DIRS ${BOOST_INCLUDEDIR}) - elseif(_ENV_BOOST_INCLUDEDIR) - list(APPEND _boost_INCLUDE_SEARCH_DIRS ${_ENV_BOOST_INCLUDEDIR}) - endif() - - if( BOOST_ROOT ) - list(APPEND _boost_INCLUDE_SEARCH_DIRS ${BOOST_ROOT}/include ${BOOST_ROOT}) - elseif( _ENV_BOOST_ROOT ) - list(APPEND _boost_INCLUDE_SEARCH_DIRS ${_ENV_BOOST_ROOT}/include ${_ENV_BOOST_ROOT}) - endif() - - if( Boost_NO_SYSTEM_PATHS) - list(APPEND _boost_INCLUDE_SEARCH_DIRS NO_CMAKE_SYSTEM_PATH NO_SYSTEM_ENVIRONMENT_PATH) - else() - if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC") - foreach(ver ${_boost_TEST_VERSIONS}) - string(REPLACE "." "_" ver "${ver}") - list(APPEND _boost_INCLUDE_SEARCH_DIRS PATHS "C:/local/boost_${ver}") - endforeach() - endif() - list(APPEND _boost_INCLUDE_SEARCH_DIRS PATHS - C:/boost/include - C:/boost - /sw/local/include - ) - endif() - - # Try to find Boost by stepping backwards through the Boost versions - # we know about. - # Build a list of path suffixes for each version. - set(_boost_PATH_SUFFIXES) - foreach(_boost_VER ${_boost_TEST_VERSIONS}) - # Add in a path suffix, based on the required version, ideally - # we could read this from version.hpp, but for that to work we'd - # need to know the include dir already - set(_boost_BOOSTIFIED_VERSION) - - # Transform 1.35 => 1_35 and 1.36.0 => 1_36_0 - if(_boost_VER MATCHES "([0-9]+)\\.([0-9]+)\\.([0-9]+)") - set(_boost_BOOSTIFIED_VERSION - "${CMAKE_MATCH_1}_${CMAKE_MATCH_2}_${CMAKE_MATCH_3}") - elseif(_boost_VER MATCHES "([0-9]+)\\.([0-9]+)") - set(_boost_BOOSTIFIED_VERSION - "${CMAKE_MATCH_1}_${CMAKE_MATCH_2}") - endif() - - list(APPEND _boost_PATH_SUFFIXES - "boost-${_boost_BOOSTIFIED_VERSION}" - "boost_${_boost_BOOSTIFIED_VERSION}" - "boost/boost-${_boost_BOOSTIFIED_VERSION}" - "boost/boost_${_boost_BOOSTIFIED_VERSION}" - ) - - endforeach() - - _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "_boost_INCLUDE_SEARCH_DIRS") - _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "_boost_PATH_SUFFIXES") - - # Look for a standard boost header file. - find_path(Boost_INCLUDE_DIR - NAMES boost/config.hpp - HINTS ${_boost_INCLUDE_SEARCH_DIRS} - PATH_SUFFIXES ${_boost_PATH_SUFFIXES} - ) -endif() - -# ------------------------------------------------------------------------ -# Extract version information from version.hpp -# ------------------------------------------------------------------------ - -if(Boost_INCLUDE_DIR) - _Boost_DEBUG_PRINT("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" - "location of version.hpp: ${Boost_INCLUDE_DIR}/boost/version.hpp") - - # Extract Boost_VERSION_MACRO and Boost_LIB_VERSION from version.hpp - set(Boost_VERSION_MACRO 0) - set(Boost_LIB_VERSION "") - file(STRINGS "${Boost_INCLUDE_DIR}/boost/version.hpp" _boost_VERSION_HPP_CONTENTS REGEX "#define BOOST_(LIB_)?VERSION ") - if("${_boost_VERSION_HPP_CONTENTS}" MATCHES "#define BOOST_VERSION ([0-9]+)") - set(Boost_VERSION_MACRO "${CMAKE_MATCH_1}") - endif() - if("${_boost_VERSION_HPP_CONTENTS}" MATCHES "#define BOOST_LIB_VERSION \"([0-9_]+)\"") - set(Boost_LIB_VERSION "${CMAKE_MATCH_1}") - endif() - unset(_boost_VERSION_HPP_CONTENTS) - - # Calculate version components - math(EXPR Boost_VERSION_MAJOR "${Boost_VERSION_MACRO} / 100000") - math(EXPR Boost_VERSION_MINOR "${Boost_VERSION_MACRO} / 100 % 1000") - math(EXPR Boost_VERSION_PATCH "${Boost_VERSION_MACRO} % 100") - set(Boost_VERSION_COUNT 3) - - # Define alias variables for backwards compat. - set(Boost_MAJOR_VERSION ${Boost_VERSION_MAJOR}) - set(Boost_MINOR_VERSION ${Boost_VERSION_MINOR}) - set(Boost_SUBMINOR_VERSION ${Boost_VERSION_PATCH}) - - # Define Boost version in x.y.z format - set(Boost_VERSION_STRING "${Boost_VERSION_MAJOR}.${Boost_VERSION_MINOR}.${Boost_VERSION_PATCH}") - - # Define final Boost_VERSION - if(POLICY CMP0093) - cmake_policy(GET CMP0093 _Boost_CMP0093 - PARENT_SCOPE # undocumented, do not use outside of CMake - ) - if("x${_Boost_CMP0093}x" STREQUAL "xNEWx") - set(Boost_VERSION ${Boost_VERSION_STRING}) - else() - set(Boost_VERSION ${Boost_VERSION_MACRO}) - endif() - unset(_Boost_CMP0093) - else() - set(Boost_VERSION ${Boost_VERSION_MACRO}) - endif() - unset(_Boost_CMP0093) - - _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_VERSION") - _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_VERSION_STRING") - _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_VERSION_MACRO") - _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_VERSION_MAJOR") - _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_VERSION_MINOR") - _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_VERSION_PATCH") - _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_VERSION_COUNT") -endif() - -# ------------------------------------------------------------------------ -# Prefix initialization -# ------------------------------------------------------------------------ - -if ( NOT DEFINED Boost_LIB_PREFIX ) - # Boost's static libraries use a "lib" prefix on DLL platforms - # to distinguish them from the DLL import libraries. - if (Boost_USE_STATIC_LIBS AND ( - (WIN32 AND NOT CYGWIN) - OR GHSMULTI - )) - set(Boost_LIB_PREFIX "lib") - else() - set(Boost_LIB_PREFIX "") - endif() -endif() - -if ( NOT Boost_NAMESPACE ) - set(Boost_NAMESPACE "boost") -endif() - -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_LIB_PREFIX") -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_NAMESPACE") - -# ------------------------------------------------------------------------ -# Suffix initialization and compiler suffix detection. -# ------------------------------------------------------------------------ - -set(_Boost_VARS_NAME - Boost_NAMESPACE - Boost_COMPILER - Boost_THREADAPI - Boost_USE_DEBUG_PYTHON - Boost_USE_MULTITHREADED - Boost_USE_STATIC_LIBS - Boost_USE_STATIC_RUNTIME - Boost_USE_STLPORT - Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS - ) -_Boost_CHANGE_DETECT(_Boost_CHANGE_LIBNAME ${_Boost_VARS_NAME}) - -# Setting some more suffixes for the library -if (Boost_COMPILER) - set(_boost_COMPILER ${Boost_COMPILER}) - _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" - "_boost_COMPILER" SOURCE "user-specified via Boost_COMPILER") -else() - # Attempt to guess the compiler suffix - # NOTE: this is not perfect yet, if you experience any issues - # please report them and use the Boost_COMPILER variable - # to work around the problems. - _Boost_GUESS_COMPILER_PREFIX(_boost_COMPILER) -endif() - -set (_boost_MULTITHREADED "-mt") -if( NOT Boost_USE_MULTITHREADED ) - set (_boost_MULTITHREADED "") -endif() -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "_boost_MULTITHREADED") - -#====================== -# Systematically build up the Boost ABI tag for the 'tagged' and 'versioned' layouts -# http://boost.org/doc/libs/1_66_0/more/getting_started/windows.html#library-naming -# http://boost.org/doc/libs/1_66_0/boost/config/auto_link.hpp -# http://boost.org/doc/libs/1_66_0/tools/build/src/tools/common.jam -# http://boost.org/doc/libs/1_66_0/boostcpp.jam -set( _boost_RELEASE_ABI_TAG "-") -set( _boost_DEBUG_ABI_TAG "-") -# Key Use this library when: -# s linking statically to the C++ standard library and -# compiler runtime support libraries. -if(Boost_USE_STATIC_RUNTIME) - set( _boost_RELEASE_ABI_TAG "${_boost_RELEASE_ABI_TAG}s") - set( _boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}s") -endif() -# g using debug versions of the standard and runtime -# support libraries -if(WIN32 AND Boost_USE_DEBUG_RUNTIME) - if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" - OR "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xClang" - OR "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xIntel" - OR "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xIntelLLVM") - string(APPEND _boost_DEBUG_ABI_TAG "g") - endif() -endif() -# y using special debug build of python -if(Boost_USE_DEBUG_PYTHON) - string(APPEND _boost_DEBUG_ABI_TAG "y") -endif() -# d using a debug version of your code -string(APPEND _boost_DEBUG_ABI_TAG "d") -# p using the STLport standard library rather than the -# default one supplied with your compiler -if(Boost_USE_STLPORT) - string(APPEND _boost_RELEASE_ABI_TAG "p") - string(APPEND _boost_DEBUG_ABI_TAG "p") -endif() -# n using the STLport deprecated "native iostreams" feature -# removed from the documentation in 1.43.0 but still present in -# boost/config/auto_link.hpp -if(Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS) - string(APPEND _boost_RELEASE_ABI_TAG "n") - string(APPEND _boost_DEBUG_ABI_TAG "n") -endif() - -# -x86 Architecture and address model tag -# First character is the architecture, then word-size, either 32 or 64 -# Only used in 'versioned' layout, added in Boost 1.66.0 -if(DEFINED Boost_ARCHITECTURE) - set(_boost_ARCHITECTURE_TAG "${Boost_ARCHITECTURE}") - _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" - "_boost_ARCHITECTURE_TAG" SOURCE "user-specified via Boost_ARCHITECTURE") -else() - set(_boost_ARCHITECTURE_TAG "") - # {CMAKE_CXX_COMPILER_ARCHITECTURE_ID} is not currently set for all compilers - if(NOT "x${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "x" AND NOT Boost_VERSION_STRING VERSION_LESS 1.66.0) - string(APPEND _boost_ARCHITECTURE_TAG "-") - # This needs to be kept in-sync with the section of CMakePlatformId.h.in - # inside 'defined(_WIN32) && defined(_MSC_VER)' - if(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "IA64") - string(APPEND _boost_ARCHITECTURE_TAG "i") - elseif(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "X86" - OR CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "x64") - string(APPEND _boost_ARCHITECTURE_TAG "x") - elseif(CMAKE_CXX_COMPILER_ARCHITECTURE_ID MATCHES "^ARM") - string(APPEND _boost_ARCHITECTURE_TAG "a") - elseif(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "MIPS") - string(APPEND _boost_ARCHITECTURE_TAG "m") - endif() - - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - string(APPEND _boost_ARCHITECTURE_TAG "64") - else() - string(APPEND _boost_ARCHITECTURE_TAG "32") - endif() - endif() - _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" - "_boost_ARCHITECTURE_TAG" SOURCE "detected") -endif() - -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "_boost_RELEASE_ABI_TAG") -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "_boost_DEBUG_ABI_TAG") - -# ------------------------------------------------------------------------ -# Begin finding boost libraries -# ------------------------------------------------------------------------ - -set(_Boost_VARS_LIB "") -foreach(c DEBUG RELEASE) - set(_Boost_VARS_LIB_${c} BOOST_LIBRARYDIR Boost_LIBRARY_DIR_${c}) - list(APPEND _Boost_VARS_LIB ${_Boost_VARS_LIB_${c}}) - _Boost_CHANGE_DETECT(_Boost_CHANGE_LIBDIR_${c} ${_Boost_VARS_DIR} ${_Boost_VARS_LIB_${c}} Boost_INCLUDE_DIR) - # Clear Boost_LIBRARY_DIR_${c} if it did not change but other input affecting the - # location did. We will find a new one based on the new inputs. - if(_Boost_CHANGE_LIBDIR_${c} AND NOT _Boost_LIBRARY_DIR_${c}_CHANGED) - unset(Boost_LIBRARY_DIR_${c} CACHE) - endif() - - # If Boost_LIBRARY_DIR_[RELEASE,DEBUG] is set, prefer its value. - if(Boost_LIBRARY_DIR_${c}) - set(_boost_LIBRARY_SEARCH_DIRS_${c} ${Boost_LIBRARY_DIR_${c}} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) - else() - set(_boost_LIBRARY_SEARCH_DIRS_${c} "") - if(BOOST_LIBRARYDIR) - list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${BOOST_LIBRARYDIR}) - elseif(_ENV_BOOST_LIBRARYDIR) - list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${_ENV_BOOST_LIBRARYDIR}) - endif() - - if(BOOST_ROOT) - list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${BOOST_ROOT}/lib ${BOOST_ROOT}/stage/lib) - _Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS(_boost_LIBRARY_SEARCH_DIRS_${c} "${BOOST_ROOT}") - elseif(_ENV_BOOST_ROOT) - list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${_ENV_BOOST_ROOT}/lib ${_ENV_BOOST_ROOT}/stage/lib) - _Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS(_boost_LIBRARY_SEARCH_DIRS_${c} "${_ENV_BOOST_ROOT}") - endif() - - list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} - ${Boost_INCLUDE_DIR}/lib - ${Boost_INCLUDE_DIR}/../lib - ${Boost_INCLUDE_DIR}/stage/lib - ) - _Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS(_boost_LIBRARY_SEARCH_DIRS_${c} "${Boost_INCLUDE_DIR}/..") - _Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS(_boost_LIBRARY_SEARCH_DIRS_${c} "${Boost_INCLUDE_DIR}") - if( Boost_NO_SYSTEM_PATHS ) - list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} NO_CMAKE_SYSTEM_PATH NO_SYSTEM_ENVIRONMENT_PATH) - else() - foreach(ver ${_boost_TEST_VERSIONS}) - string(REPLACE "." "_" ver "${ver}") - _Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS(_boost_LIBRARY_SEARCH_DIRS_${c} "C:/local/boost_${ver}") - endforeach() - _Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS(_boost_LIBRARY_SEARCH_DIRS_${c} "C:/boost") - list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} PATHS - C:/boost/lib - C:/boost - /sw/local/lib - ) - endif() - endif() -endforeach() - -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "_boost_LIBRARY_SEARCH_DIRS_RELEASE") -_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "_boost_LIBRARY_SEARCH_DIRS_DEBUG") - -# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES -if( Boost_USE_STATIC_LIBS ) - set( _boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - if(WIN32) - list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .lib .a) - else() - set(CMAKE_FIND_LIBRARY_SUFFIXES .a) - endif() -endif() - -# We want to use the tag inline below without risking double dashes -if(_boost_RELEASE_ABI_TAG) - if(${_boost_RELEASE_ABI_TAG} STREQUAL "-") - set(_boost_RELEASE_ABI_TAG "") - endif() -endif() -if(_boost_DEBUG_ABI_TAG) - if(${_boost_DEBUG_ABI_TAG} STREQUAL "-") - set(_boost_DEBUG_ABI_TAG "") - endif() -endif() - -# The previous behavior of FindBoost when Boost_USE_STATIC_LIBS was enabled -# on WIN32 was to: -# 1. Search for static libs compiled against a SHARED C++ standard runtime library (use if found) -# 2. Search for static libs compiled against a STATIC C++ standard runtime library (use if found) -# We maintain this behavior since changing it could break people's builds. -# To disable the ambiguous behavior, the user need only -# set Boost_USE_STATIC_RUNTIME either ON or OFF. -set(_boost_STATIC_RUNTIME_WORKAROUND false) -if(WIN32 AND Boost_USE_STATIC_LIBS) - if(NOT DEFINED Boost_USE_STATIC_RUNTIME) - set(_boost_STATIC_RUNTIME_WORKAROUND TRUE) - endif() -endif() - -# On versions < 1.35, remove the System library from the considered list -# since it wasn't added until 1.35. -if(Boost_VERSION_STRING AND Boost_FIND_COMPONENTS) - if(Boost_VERSION_STRING VERSION_LESS 1.35.0) - list(REMOVE_ITEM Boost_FIND_COMPONENTS system) - endif() -endif() - -# Additional components may be required via component dependencies. -# Add any missing components to the list. -_Boost_MISSING_DEPENDENCIES(Boost_FIND_COMPONENTS _Boost_EXTRA_FIND_COMPONENTS) - -# If thread is required, get the thread libs as a dependency -if("thread" IN_LIST Boost_FIND_COMPONENTS) - if(Boost_FIND_QUIETLY) - set(_Boost_find_quiet QUIET) - else() - set(_Boost_find_quiet "") - endif() - find_package(Threads ${_Boost_find_quiet}) - unset(_Boost_find_quiet) -endif() - -# If the user changed any of our control inputs flush previous results. -if(_Boost_CHANGE_LIBDIR_DEBUG OR _Boost_CHANGE_LIBDIR_RELEASE OR _Boost_CHANGE_LIBNAME) - foreach(COMPONENT ${_Boost_COMPONENTS_SEARCHED}) - string(TOUPPER ${COMPONENT} UPPERCOMPONENT) - foreach(c DEBUG RELEASE) - set(_var Boost_${UPPERCOMPONENT}_LIBRARY_${c}) - unset(${_var} CACHE) - set(${_var} "${_var}-NOTFOUND") - endforeach() - endforeach() - set(_Boost_COMPONENTS_SEARCHED "") -endif() - -foreach(COMPONENT ${Boost_FIND_COMPONENTS}) - string(TOUPPER ${COMPONENT} UPPERCOMPONENT) - - set( _boost_docstring_release "Boost ${COMPONENT} library (release)") - set( _boost_docstring_debug "Boost ${COMPONENT} library (debug)") - - # Compute component-specific hints. - set(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT "") - if(${COMPONENT} STREQUAL "mpi" OR ${COMPONENT} STREQUAL "mpi_python" OR - ${COMPONENT} STREQUAL "graph_parallel") - foreach(lib ${MPI_CXX_LIBRARIES} ${MPI_C_LIBRARIES}) - if(IS_ABSOLUTE "${lib}") - get_filename_component(libdir "${lib}" PATH) - string(REPLACE "\\" "/" libdir "${libdir}") - list(APPEND _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT ${libdir}) - endif() - endforeach() - endif() - - # Handle Python version suffixes - unset(COMPONENT_PYTHON_VERSION_MAJOR) - unset(COMPONENT_PYTHON_VERSION_MINOR) - if(${COMPONENT} MATCHES "^(python|mpi_python|numpy)([0-9])\$") - set(COMPONENT_UNVERSIONED "${CMAKE_MATCH_1}") - set(COMPONENT_PYTHON_VERSION_MAJOR "${CMAKE_MATCH_2}") - elseif(${COMPONENT} MATCHES "^(python|mpi_python|numpy)([0-9])\\.?([0-9]+)\$") - set(COMPONENT_UNVERSIONED "${CMAKE_MATCH_1}") - set(COMPONENT_PYTHON_VERSION_MAJOR "${CMAKE_MATCH_2}") - set(COMPONENT_PYTHON_VERSION_MINOR "${CMAKE_MATCH_3}") - endif() - - unset(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME) - if (COMPONENT_PYTHON_VERSION_MINOR) - # Boost >= 1.67 - list(APPEND _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME "${COMPONENT_UNVERSIONED}${COMPONENT_PYTHON_VERSION_MAJOR}${COMPONENT_PYTHON_VERSION_MINOR}") - # Debian/Ubuntu (Some versions omit the 2 and/or 3 from the suffix) - list(APPEND _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME "${COMPONENT_UNVERSIONED}${COMPONENT_PYTHON_VERSION_MAJOR}-py${COMPONENT_PYTHON_VERSION_MAJOR}${COMPONENT_PYTHON_VERSION_MINOR}") - list(APPEND _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME "${COMPONENT_UNVERSIONED}-py${COMPONENT_PYTHON_VERSION_MAJOR}${COMPONENT_PYTHON_VERSION_MINOR}") - # Gentoo - list(APPEND _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME "${COMPONENT_UNVERSIONED}-${COMPONENT_PYTHON_VERSION_MAJOR}.${COMPONENT_PYTHON_VERSION_MINOR}") - # RPMs - list(APPEND _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME "${COMPONENT_UNVERSIONED}-${COMPONENT_PYTHON_VERSION_MAJOR}${COMPONENT_PYTHON_VERSION_MINOR}") - endif() - if (COMPONENT_PYTHON_VERSION_MAJOR AND NOT COMPONENT_PYTHON_VERSION_MINOR) - # Boost < 1.67 - list(APPEND _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME "${COMPONENT_UNVERSIONED}${COMPONENT_PYTHON_VERSION_MAJOR}") - endif() - - # Consolidate and report component-specific hints. - if(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME) - list(REMOVE_DUPLICATES _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME) - _Boost_DEBUG_PRINT("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" - "Component-specific library search names for ${COMPONENT_NAME}: ${_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME}") - endif() - if(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT) - list(REMOVE_DUPLICATES _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT) - _Boost_DEBUG_PRINT("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" - "Component-specific library search paths for ${COMPONENT}: ${_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT}") - endif() - - # - # Find headers - # - _Boost_COMPONENT_HEADERS("${COMPONENT}" Boost_${UPPERCOMPONENT}_HEADER_NAME) - # Look for a standard boost header file. - if(Boost_${UPPERCOMPONENT}_HEADER_NAME) - if(EXISTS "${Boost_INCLUDE_DIR}/${Boost_${UPPERCOMPONENT}_HEADER_NAME}") - set(Boost_${UPPERCOMPONENT}_HEADER ON) - else() - set(Boost_${UPPERCOMPONENT}_HEADER OFF) - endif() - else() - set(Boost_${UPPERCOMPONENT}_HEADER ON) - message(WARNING "No header defined for ${COMPONENT}; skipping header check " - "(note: header-only libraries have no designated component)") - endif() - - # - # Find RELEASE libraries - # - unset(_boost_RELEASE_NAMES) - foreach(component IN LISTS _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME COMPONENT) - foreach(compiler IN LISTS _boost_COMPILER) - list(APPEND _boost_RELEASE_NAMES - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG} ) - endforeach() - list(APPEND _boost_RELEASE_NAMES - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component} ) - if(_boost_STATIC_RUNTIME_WORKAROUND) - set(_boost_RELEASE_STATIC_ABI_TAG "-s${_boost_RELEASE_ABI_TAG}") - foreach(compiler IN LISTS _boost_COMPILER) - list(APPEND _boost_RELEASE_NAMES - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} ) - endforeach() - list(APPEND _boost_RELEASE_NAMES - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} ) - endif() - endforeach() - if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread") - _Boost_PREPEND_LIST_WITH_THREADAPI(_boost_RELEASE_NAMES ${_boost_RELEASE_NAMES}) - endif() - _Boost_DEBUG_PRINT("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" - "Searching for ${UPPERCOMPONENT}_LIBRARY_RELEASE: ${_boost_RELEASE_NAMES}") - - # if Boost_LIBRARY_DIR_RELEASE is not defined, - # but Boost_LIBRARY_DIR_DEBUG is, look there first for RELEASE libs - if(NOT Boost_LIBRARY_DIR_RELEASE AND Boost_LIBRARY_DIR_DEBUG) - list(INSERT _boost_LIBRARY_SEARCH_DIRS_RELEASE 0 ${Boost_LIBRARY_DIR_DEBUG}) - endif() - - # Avoid passing backslashes to _Boost_FIND_LIBRARY due to macro re-parsing. - string(REPLACE "\\" "/" _boost_LIBRARY_SEARCH_DIRS_tmp "${_boost_LIBRARY_SEARCH_DIRS_RELEASE}") - - if(Boost_USE_RELEASE_LIBS) - _Boost_FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE RELEASE - NAMES ${_boost_RELEASE_NAMES} - HINTS ${_boost_LIBRARY_SEARCH_DIRS_tmp} - NAMES_PER_DIR - DOC "${_boost_docstring_release}" - ) - endif() - - # - # Find DEBUG libraries - # - unset(_boost_DEBUG_NAMES) - foreach(component IN LISTS _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME COMPONENT) - foreach(compiler IN LISTS _boost_COMPILER) - list(APPEND _boost_DEBUG_NAMES - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG} ) - endforeach() - list(APPEND _boost_DEBUG_NAMES - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component} ) - if(_boost_STATIC_RUNTIME_WORKAROUND) - set(_boost_DEBUG_STATIC_ABI_TAG "-s${_boost_DEBUG_ABI_TAG}") - foreach(compiler IN LISTS _boost_COMPILER) - list(APPEND _boost_DEBUG_NAMES - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} ) - endforeach() - list(APPEND _boost_DEBUG_NAMES - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} ) - endif() - endforeach() - if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread") - _Boost_PREPEND_LIST_WITH_THREADAPI(_boost_DEBUG_NAMES ${_boost_DEBUG_NAMES}) - endif() - _Boost_DEBUG_PRINT("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" - "Searching for ${UPPERCOMPONENT}_LIBRARY_DEBUG: ${_boost_DEBUG_NAMES}") - - # if Boost_LIBRARY_DIR_DEBUG is not defined, - # but Boost_LIBRARY_DIR_RELEASE is, look there first for DEBUG libs - if(NOT Boost_LIBRARY_DIR_DEBUG AND Boost_LIBRARY_DIR_RELEASE) - list(INSERT _boost_LIBRARY_SEARCH_DIRS_DEBUG 0 ${Boost_LIBRARY_DIR_RELEASE}) - endif() - - # Avoid passing backslashes to _Boost_FIND_LIBRARY due to macro re-parsing. - string(REPLACE "\\" "/" _boost_LIBRARY_SEARCH_DIRS_tmp "${_boost_LIBRARY_SEARCH_DIRS_DEBUG}") - - if(Boost_USE_DEBUG_LIBS) - _Boost_FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG DEBUG - NAMES ${_boost_DEBUG_NAMES} - HINTS ${_boost_LIBRARY_SEARCH_DIRS_tmp} - NAMES_PER_DIR - DOC "${_boost_docstring_debug}" - ) - endif () - - if(Boost_REALPATH) - _Boost_SWAP_WITH_REALPATH(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE "${_boost_docstring_release}") - _Boost_SWAP_WITH_REALPATH(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG "${_boost_docstring_debug}" ) - endif() - - _Boost_ADJUST_LIB_VARS(${UPPERCOMPONENT}) - - # Check if component requires some compiler features - _Boost_COMPILER_FEATURES(${COMPONENT} _Boost_${UPPERCOMPONENT}_COMPILER_FEATURES) - -endforeach() - -# Restore the original find library ordering -if( Boost_USE_STATIC_LIBS ) - set(CMAKE_FIND_LIBRARY_SUFFIXES ${_boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) -endif() - -# ------------------------------------------------------------------------ -# End finding boost libraries -# ------------------------------------------------------------------------ - -set(Boost_INCLUDE_DIRS ${Boost_INCLUDE_DIR}) -set(Boost_LIBRARY_DIRS) -if(Boost_LIBRARY_DIR_RELEASE) - list(APPEND Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIR_RELEASE}) -endif() -if(Boost_LIBRARY_DIR_DEBUG) - list(APPEND Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIR_DEBUG}) -endif() -if(Boost_LIBRARY_DIRS) - list(REMOVE_DUPLICATES Boost_LIBRARY_DIRS) -endif() - -# ------------------------------------------------------------------------ -# Call FPHSA helper, see https://cmake.org/cmake/help/latest/module/FindPackageHandleStandardArgs.html -# ------------------------------------------------------------------------ - -# Define aliases as needed by the component handler in the FPHSA helper below -foreach(_comp IN LISTS Boost_FIND_COMPONENTS) - string(TOUPPER ${_comp} _uppercomp) - if(DEFINED Boost_${_uppercomp}_FOUND) - set(Boost_${_comp}_FOUND ${Boost_${_uppercomp}_FOUND}) - endif() -endforeach() - -find_package_handle_standard_args(Boost - REQUIRED_VARS Boost_INCLUDE_DIR - VERSION_VAR Boost_VERSION_STRING - HANDLE_COMPONENTS) - -if(Boost_FOUND) - if( NOT Boost_LIBRARY_DIRS ) - # Compatibility Code for backwards compatibility with CMake - # 2.4's FindBoost module. - - # Look for the boost library path. - # Note that the user may not have installed any libraries - # so it is quite possible the Boost_LIBRARY_DIRS may not exist. - set(_boost_LIB_DIR ${Boost_INCLUDE_DIR}) - - if("${_boost_LIB_DIR}" MATCHES "boost-[0-9]+") - get_filename_component(_boost_LIB_DIR ${_boost_LIB_DIR} PATH) - endif() - - if("${_boost_LIB_DIR}" MATCHES "/include$") - # Strip off the trailing "/include" in the path. - get_filename_component(_boost_LIB_DIR ${_boost_LIB_DIR} PATH) - endif() - - if(EXISTS "${_boost_LIB_DIR}/lib") - string(APPEND _boost_LIB_DIR /lib) - elseif(EXISTS "${_boost_LIB_DIR}/stage/lib") - string(APPEND _boost_LIB_DIR "/stage/lib") - else() - set(_boost_LIB_DIR "") - endif() - - if(_boost_LIB_DIR AND EXISTS "${_boost_LIB_DIR}") - set(Boost_LIBRARY_DIRS ${_boost_LIB_DIR}) - endif() - - endif() -else() - # Boost headers were not found so no components were found. - foreach(COMPONENT ${Boost_FIND_COMPONENTS}) - string(TOUPPER ${COMPONENT} UPPERCOMPONENT) - set(Boost_${UPPERCOMPONENT}_FOUND 0) - endforeach() -endif() - -# ------------------------------------------------------------------------ -# Add imported targets -# ------------------------------------------------------------------------ - -if(Boost_FOUND) - # The builtin CMake package in Boost 1.70+ introduces a new name - # for the header-only lib, let's provide the same UI in module mode - if(NOT TARGET Boost::headers) - add_library(Boost::headers INTERFACE IMPORTED) - if(Boost_INCLUDE_DIRS) - set_target_properties(Boost::headers PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}") - endif() - endif() - - # Define the old target name for header-only libraries for backwards - # compat. - if(NOT TARGET Boost::boost) - add_library(Boost::boost INTERFACE IMPORTED) - set_target_properties(Boost::boost - PROPERTIES INTERFACE_LINK_LIBRARIES Boost::headers) - endif() - - foreach(COMPONENT ${Boost_FIND_COMPONENTS}) - if(_Boost_IMPORTED_TARGETS AND NOT TARGET Boost::${COMPONENT}) - string(TOUPPER ${COMPONENT} UPPERCOMPONENT) - if(Boost_${UPPERCOMPONENT}_FOUND) - if(Boost_USE_STATIC_LIBS) - add_library(Boost::${COMPONENT} STATIC IMPORTED) - else() - # Even if Boost_USE_STATIC_LIBS is OFF, we might have static - # libraries as a result. - add_library(Boost::${COMPONENT} UNKNOWN IMPORTED) - endif() - if(Boost_INCLUDE_DIRS) - set_target_properties(Boost::${COMPONENT} PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}") - endif() - if(EXISTS "${Boost_${UPPERCOMPONENT}_LIBRARY}") - set_target_properties(Boost::${COMPONENT} PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" - IMPORTED_LOCATION "${Boost_${UPPERCOMPONENT}_LIBRARY}") - endif() - if(EXISTS "${Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE}") - set_property(TARGET Boost::${COMPONENT} APPEND PROPERTY - IMPORTED_CONFIGURATIONS RELEASE) - set_target_properties(Boost::${COMPONENT} PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX" - IMPORTED_LOCATION_RELEASE "${Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE}") - endif() - if(EXISTS "${Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG}") - set_property(TARGET Boost::${COMPONENT} APPEND PROPERTY - IMPORTED_CONFIGURATIONS DEBUG) - set_target_properties(Boost::${COMPONENT} PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX" - IMPORTED_LOCATION_DEBUG "${Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG}") - endif() - if(_Boost_${UPPERCOMPONENT}_DEPENDENCIES) - unset(_Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES) - foreach(dep ${_Boost_${UPPERCOMPONENT}_DEPENDENCIES}) - list(APPEND _Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES Boost::${dep}) - endforeach() - if(COMPONENT STREQUAL "thread") - list(APPEND _Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES Threads::Threads) - endif() - set_target_properties(Boost::${COMPONENT} PROPERTIES - INTERFACE_LINK_LIBRARIES "${_Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES}") - endif() - if(_Boost_${UPPERCOMPONENT}_COMPILER_FEATURES) - set_target_properties(Boost::${COMPONENT} PROPERTIES - INTERFACE_COMPILE_FEATURES "${_Boost_${UPPERCOMPONENT}_COMPILER_FEATURES}") - endif() - endif() - endif() - endforeach() - - # Supply Boost_LIB_DIAGNOSTIC_DEFINITIONS as a convenience target. It - # will only contain any interface definitions on WIN32, but is created - # on all platforms to keep end user code free from platform dependent - # code. Also provide convenience targets to disable autolinking and - # enable dynamic linking. - if(NOT TARGET Boost::diagnostic_definitions) - add_library(Boost::diagnostic_definitions INTERFACE IMPORTED) - add_library(Boost::disable_autolinking INTERFACE IMPORTED) - add_library(Boost::dynamic_linking INTERFACE IMPORTED) - set_target_properties(Boost::dynamic_linking PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_DYN_LINK") - endif() - if(WIN32) - # In windows, automatic linking is performed, so you do not have - # to specify the libraries. If you are linking to a dynamic - # runtime, then you can choose to link to either a static or a - # dynamic Boost library, the default is to do a static link. You - # can alter this for a specific library "whatever" by defining - # BOOST_WHATEVER_DYN_LINK to force Boost library "whatever" to be - # linked dynamically. Alternatively you can force all Boost - # libraries to dynamic link by defining BOOST_ALL_DYN_LINK. - - # This feature can be disabled for Boost library "whatever" by - # defining BOOST_WHATEVER_NO_LIB, or for all of Boost by defining - # BOOST_ALL_NO_LIB. - - # If you want to observe which libraries are being linked against - # then defining BOOST_LIB_DIAGNOSTIC will cause the auto-linking - # code to emit a #pragma message each time a library is selected - # for linking. - set(Boost_LIB_DIAGNOSTIC_DEFINITIONS "-DBOOST_LIB_DIAGNOSTIC") - set_target_properties(Boost::diagnostic_definitions PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "BOOST_LIB_DIAGNOSTIC") - set_target_properties(Boost::disable_autolinking PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_NO_LIB") - endif() -endif() - -# ------------------------------------------------------------------------ -# Finalize -# ------------------------------------------------------------------------ - -# Report Boost_LIBRARIES -set(Boost_LIBRARIES "") -foreach(_comp IN LISTS Boost_FIND_COMPONENTS) - string(TOUPPER ${_comp} _uppercomp) - if(Boost_${_uppercomp}_FOUND) - list(APPEND Boost_LIBRARIES ${Boost_${_uppercomp}_LIBRARY}) - if(_comp STREQUAL "thread") - list(APPEND Boost_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) - endif() - endif() -endforeach() - -# Configure display of cache entries in GUI. -foreach(v BOOSTROOT BOOST_ROOT ${_Boost_VARS_INC} ${_Boost_VARS_LIB}) - get_property(_type CACHE ${v} PROPERTY TYPE) - if(_type) - set_property(CACHE ${v} PROPERTY ADVANCED 1) - if("x${_type}" STREQUAL "xUNINITIALIZED") - if("x${v}" STREQUAL "xBoost_ADDITIONAL_VERSIONS") - set_property(CACHE ${v} PROPERTY TYPE STRING) - else() - set_property(CACHE ${v} PROPERTY TYPE PATH) - endif() - endif() - endif() -endforeach() - -# Record last used values of input variables so we can -# detect on the next run if the user changed them. -foreach(v - ${_Boost_VARS_INC} ${_Boost_VARS_LIB} - ${_Boost_VARS_DIR} ${_Boost_VARS_NAME} - ) - if(DEFINED ${v}) - set(_${v}_LAST "${${v}}" CACHE INTERNAL "Last used ${v} value.") - else() - unset(_${v}_LAST CACHE) - endif() -endforeach() - -# Maintain a persistent list of components requested anywhere since -# the last flush. -set(_Boost_COMPONENTS_SEARCHED "${_Boost_COMPONENTS_SEARCHED}") -list(APPEND _Boost_COMPONENTS_SEARCHED ${Boost_FIND_COMPONENTS}) -list(REMOVE_DUPLICATES _Boost_COMPONENTS_SEARCHED) -list(SORT _Boost_COMPONENTS_SEARCHED) -set(_Boost_COMPONENTS_SEARCHED "${_Boost_COMPONENTS_SEARCHED}" - CACHE INTERNAL "Components requested for this build tree.") - -# Restore project's policies -cmake_policy(POP) diff --git a/cmake/modules/FindJerasure.cmake b/cmake/modules/FindJerasure.cmake new file mode 100644 index 000000000000..b27b687e8c83 --- /dev/null +++ b/cmake/modules/FindJerasure.cmake @@ -0,0 +1,66 @@ +# - Find Jerasure and GF-Complete +# Find the jerasure and gf-complete libraries and includes +# +# Jerasure_INCLUDE_DIR - where to find jerasure.h +# Jerasure_SUBHEADER_DIR - where to find galois.h, cauchy.h, etc. +# Jerasure_LIBRARY - the jerasure library +# GFComplete_INCLUDE_DIR - where to find gf_complete.h +# GFComplete_LIBRARY - the gf-complete library +# Jerasure_FOUND - True if both jerasure and gf-complete found. + +find_path(Jerasure_INCLUDE_DIR jerasure.h) + +# jerasure sub-headers (galois.h, cauchy.h, etc.) may be installed in a +# jerasure/ subdirectory. The main jerasure.h includes them with bare +# #include "galois.h", so this directory must be on the include path. +find_path(Jerasure_SUBHEADER_DIR galois.h + PATH_SUFFIXES jerasure) + +find_library(Jerasure_LIBRARY NAMES Jerasure) + +find_path(GFComplete_INCLUDE_DIR gf_complete.h) + +find_library(GFComplete_LIBRARY NAMES gf_complete) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Jerasure + REQUIRED_VARS + Jerasure_INCLUDE_DIR + Jerasure_SUBHEADER_DIR + Jerasure_LIBRARY + GFComplete_INCLUDE_DIR + GFComplete_LIBRARY) + +if(Jerasure_FOUND) + set(Jerasure_INCLUDE_DIRS + ${Jerasure_INCLUDE_DIR} + ${Jerasure_SUBHEADER_DIR} + ${GFComplete_INCLUDE_DIR}) + set(Jerasure_LIBRARIES + ${Jerasure_LIBRARY} + ${GFComplete_LIBRARY}) + + if(NOT TARGET Jerasure::jerasure) + add_library(Jerasure::jerasure UNKNOWN IMPORTED GLOBAL) + set_target_properties(Jerasure::jerasure PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${Jerasure_INCLUDE_DIR};${Jerasure_SUBHEADER_DIR}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${Jerasure_LIBRARY}" + INTERFACE_LINK_LIBRARIES "${GFComplete_LIBRARY}") + endif() + + if(NOT TARGET Jerasure::GFComplete) + add_library(Jerasure::GFComplete UNKNOWN IMPORTED GLOBAL) + set_target_properties(Jerasure::GFComplete PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${GFComplete_INCLUDE_DIR}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${GFComplete_LIBRARY}") + endif() +endif() + +mark_as_advanced( + Jerasure_INCLUDE_DIR + Jerasure_SUBHEADER_DIR + Jerasure_LIBRARY + GFComplete_INCLUDE_DIR + GFComplete_LIBRARY) diff --git a/cmake/modules/FindPython/Support.cmake b/cmake/modules/FindPython/Support.cmake deleted file mode 100644 index 141c261dff65..000000000000 --- a/cmake/modules/FindPython/Support.cmake +++ /dev/null @@ -1,4141 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -# -# This file is a "template" file used by various FindPython modules. -# - -# -# Initial configuration -# - -cmake_policy(PUSH) -# list supports empty elements -cmake_policy (SET CMP0007 NEW) -# numbers and boolean constants -cmake_policy (SET CMP0012 NEW) -# IN_LIST operator -cmake_policy (SET CMP0057 NEW) - -if (NOT DEFINED _PYTHON_PREFIX) - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() -if (NOT DEFINED _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() -if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL "3") - set(_${_PYTHON_PREFIX}_VERSIONS 3.13 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0) -elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL "2") - set(_${_PYTHON_PREFIX}_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0) -else() - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() - -get_property(_${_PYTHON_PREFIX}_CMAKE_ROLE GLOBAL PROPERTY CMAKE_ROLE) - -include (FindPackageHandleStandardArgs) - -# -# helper commands -# -macro (_PYTHON_DISPLAY_FAILURE _PYTHON_MSG) - if (${_PYTHON_PREFIX}_FIND_REQUIRED) - message (FATAL_ERROR "${_PYTHON_MSG}") - else() - if (NOT ${_PYTHON_PREFIX}_FIND_QUIETLY) - message(STATUS "${_PYTHON_MSG}") - endif () - endif() - - set (${_PYTHON_PREFIX}_FOUND FALSE) - string (TOUPPER "${_PYTHON_PREFIX}" _${_PYTHON_PREFIX}_UPPER_PREFIX) - set (${_PYTHON_UPPER_PREFIX}_FOUND FALSE) -endmacro() - - -function (_PYTHON_ADD_REASON_FAILURE module message) - if (_${_PYTHON_PREFIX}_${module}_REASON_FAILURE) - string (LENGTH "${_${_PYTHON_PREFIX}_${module}_REASON_FAILURE}" length) - math (EXPR length "${length} + 10") - string (REPEAT " " ${length} shift) - set_property (CACHE _${_PYTHON_PREFIX}_${module}_REASON_FAILURE PROPERTY VALUE "${_${_PYTHON_PREFIX}_${module}_REASON_FAILURE}\n${shift}${message}") - else() - set_property (CACHE _${_PYTHON_PREFIX}_${module}_REASON_FAILURE PROPERTY VALUE "${message}") - endif() -endfunction() - - -function (_PYTHON_MARK_AS_INTERNAL) - foreach (var IN LISTS ARGV) - if (DEFINED CACHE{${var}}) - set_property (CACHE ${var} PROPERTY TYPE INTERNAL) - endif() - endforeach() -endfunction() - - -macro (_PYTHON_SELECT_LIBRARY_CONFIGURATIONS _PYTHON_BASENAME) - if(NOT DEFINED ${_PYTHON_BASENAME}_LIBRARY_RELEASE) - set(${_PYTHON_BASENAME}_LIBRARY_RELEASE "${_PYTHON_BASENAME}_LIBRARY_RELEASE-NOTFOUND") - endif() - if(NOT DEFINED ${_PYTHON_BASENAME}_LIBRARY_DEBUG) - set(${_PYTHON_BASENAME}_LIBRARY_DEBUG "${_PYTHON_BASENAME}_LIBRARY_DEBUG-NOTFOUND") - endif() - - get_property(_PYTHON_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) - if (${_PYTHON_BASENAME}_LIBRARY_DEBUG AND ${_PYTHON_BASENAME}_LIBRARY_RELEASE AND - NOT ${_PYTHON_BASENAME}_LIBRARY_DEBUG STREQUAL ${_PYTHON_BASENAME}_LIBRARY_RELEASE AND - (_PYTHON_isMultiConfig OR CMAKE_BUILD_TYPE)) - # if the generator is multi-config or if CMAKE_BUILD_TYPE is set for - # single-config generators, set optimized and debug libraries - set (${_PYTHON_BASENAME}_LIBRARIES "") - foreach (_PYTHON_libname IN LISTS ${_PYTHON_BASENAME}_LIBRARY_RELEASE) - list( APPEND ${_PYTHON_BASENAME}_LIBRARIES optimized "${_PYTHON_libname}") - endforeach() - foreach (_PYTHON_libname IN LISTS ${_PYTHON_BASENAME}_LIBRARY_DEBUG) - list( APPEND ${_PYTHON_BASENAME}_LIBRARIES debug "${_PYTHON_libname}") - endforeach() - elseif (${_PYTHON_BASENAME}_LIBRARY_RELEASE) - set (${_PYTHON_BASENAME}_LIBRARIES "${${_PYTHON_BASENAME}_LIBRARY_RELEASE}") - elseif (${_PYTHON_BASENAME}_LIBRARY_DEBUG) - set (${_PYTHON_BASENAME}_LIBRARIES "${${_PYTHON_BASENAME}_LIBRARY_DEBUG}") - else() - set (${_PYTHON_BASENAME}_LIBRARIES "${_PYTHON_BASENAME}_LIBRARY-NOTFOUND") - endif() -endmacro() - - -macro (_PYTHON_FIND_FRAMEWORKS) - if (CMAKE_HOST_APPLE OR APPLE) - file(TO_CMAKE_PATH "$ENV{CMAKE_FRAMEWORK_PATH}" _pff_CMAKE_FRAMEWORK_PATH) - set (_pff_frameworks ${CMAKE_FRAMEWORK_PATH} - ${_pff_CMAKE_FRAMEWORK_PATH} - ~/Library/Frameworks - /usr/local/Frameworks - /opt/homebrew/Frameworks - ${CMAKE_SYSTEM_FRAMEWORK_PATH}) - list (REMOVE_DUPLICATES _pff_frameworks) - foreach (_pff_implementation IN LISTS _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS) - unset (_${_PYTHON_PREFIX}_${_pff_implementation}_FRAMEWORKS) - if (_pff_implementation STREQUAL "CPython") - foreach (_pff_framework IN LISTS _pff_frameworks) - if (EXISTS ${_pff_framework}/Python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}.framework) - list (APPEND _${_PYTHON_PREFIX}_${_pff_implementation}_FRAMEWORKS ${_pff_framework}/Python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}.framework) - endif() - if (EXISTS ${_pff_framework}/Python.framework) - list (APPEND _${_PYTHON_PREFIX}_${_pff_implementation}_FRAMEWORKS ${_pff_framework}/Python.framework) - endif() - endforeach() - elseif (_pff_implementation STREQUAL "IronPython") - foreach (_pff_framework IN LISTS _pff_frameworks) - if (EXISTS ${_pff_framework}/IronPython.framework) - list (APPEND _${_PYTHON_PREFIX}_${_pff_implementation}_FRAMEWORKS ${_pff_framework}/IronPython.framework) - endif() - endforeach() - endif() - endforeach() - unset (_pff_implementation) - unset (_pff_frameworks) - unset (_pff_framework) - endif() -endmacro() - -function (_PYTHON_GET_FRAMEWORKS _PYTHON_PGF_FRAMEWORK_PATHS) - cmake_parse_arguments (PARSE_ARGV 1 _PGF "" "" "IMPLEMENTATIONS;VERSION") - - if (NOT _PGF_IMPLEMENTATIONS) - set (_PGF_IMPLEMENTATIONS ${_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS}) - endif() - - set (framework_paths) - - foreach (implementation IN LISTS _PGF_IMPLEMENTATIONS) - if (implementation STREQUAL "CPython") - foreach (version IN LISTS _PGF_VERSION) - foreach (framework IN LISTS _${_PYTHON_PREFIX}_${implementation}_FRAMEWORKS) - if (EXISTS "${framework}/Versions/${version}") - list (APPEND framework_paths "${framework}/Versions/${version}") - endif() - endforeach() - endforeach() - elseif (implementation STREQUAL "IronPython") - foreach (version IN LISTS _PGF_VERSION) - foreach (framework IN LISTS _${_PYTHON_PREFIX}_${implementation}_FRAMEWORKS) - # pick-up all available versions - file (GLOB versions LIST_DIRECTORIES true RELATIVE "${framework}/Versions/" - "${framework}/Versions/${version}*") - list (SORT versions ORDER DESCENDING) - list (TRANSFORM versions PREPEND "${framework}/Versions/") - list (APPEND framework_paths ${versions}) - endforeach() - endforeach() - endif() - endforeach() - - set (${_PYTHON_PGF_FRAMEWORK_PATHS} ${framework_paths} PARENT_SCOPE) -endfunction() - -function (_PYTHON_GET_REGISTRIES _PYTHON_PGR_REGISTRY_PATHS) - cmake_parse_arguments (PARSE_ARGV 1 _PGR "" "" "IMPLEMENTATIONS;VERSION") - - if (NOT _PGR_IMPLEMENTATIONS) - set (_PGR_IMPLEMENTATIONS ${_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS}) - endif() - - set (registries) - - foreach (implementation IN LISTS _PGR_IMPLEMENTATIONS) - if (implementation STREQUAL "CPython") - foreach (version IN LISTS _PGR_VERSION) - string (REPLACE "." "" version_no_dots ${version}) - list (TRANSFORM _${_PYTHON_PREFIX}_ARCH REPLACE "^(.+)$" "[HKEY_CURRENT_USER/SOFTWARE/Python/PythonCore/${version}-\\1/InstallPath]" OUTPUT_VARIABLE reg_paths) - list (APPEND registries ${reg_paths}) - if (version VERSION_GREATER_EQUAL "3.5") - # cmake_host_system_information is not usable in bootstrap - get_filename_component (arch "[HKEY_CURRENT_USER\\Software\\Python\\PythonCore\\${version};SysArchitecture]" NAME) - string (REPLACE "bit" "" arch "${arch}") - if (arch IN_LIST _${_PYTHON_PREFIX}_ARCH) - list (APPEND registries [HKEY_CURRENT_USER/SOFTWARE/Python/PythonCore/${version}/InstallPath]) - endif() - else() - list (APPEND registries [HKEY_CURRENT_USER/SOFTWARE/Python/PythonCore/${version}/InstallPath]) - endif() - list (TRANSFORM _${_PYTHON_PREFIX}_ARCH REPLACE "^(.+)$" "[HKEY_CURRENT_USER/SOFTWARE/Python/ContinuumAnalytics/Anaconda${version_no_dots}-\\1/InstallPath]" OUTPUT_VARIABLE reg_paths) - list (APPEND registries ${reg_paths}) - list (TRANSFORM _${_PYTHON_PREFIX}_ARCH REPLACE "^(.+)$" "[HKEY_CURRENT_USER/SOFTWARE/Python/PythonCore/${version}-\\1/InstallPath]" OUTPUT_VARIABLE reg_paths) - list (APPEND registries ${reg_paths}) - list (APPEND registries [HKEY_LOCAL_MACHINE/SOFTWARE/Python/PythonCore/${version}/InstallPath]) - list (TRANSFORM _${_PYTHON_PREFIX}_ARCH REPLACE "^(.+)$" "[HKEY_LOCAL_MACHINE/SOFTWARE/Python/ContinuumAnalytics/Anaconda${version_no_dots}-\\1/InstallPath]" OUTPUT_VARIABLE reg_paths) - list (APPEND registries ${reg_paths}) - endforeach() - elseif (implementation STREQUAL "IronPython") - foreach (version IN LISTS _PGR_VERSION) - list (APPEND registries [HKEY_LOCAL_MACHINE/SOFTWARE/IronPython/${version}/InstallPath]) - endforeach() - endif() - endforeach() - - set (${_PYTHON_PGR_REGISTRY_PATHS} "${registries}" PARENT_SCOPE) -endfunction() - - -function (_PYTHON_GET_ABIFLAGS _PGABIFLAGS) - set (abiflags) - list (GET _${_PYTHON_PREFIX}_FIND_ABI 0 pydebug) - list (GET _${_PYTHON_PREFIX}_FIND_ABI 1 pymalloc) - list (GET _${_PYTHON_PREFIX}_FIND_ABI 2 unicode) - - if (pymalloc STREQUAL "ANY" AND unicode STREQUAL "ANY") - set (abiflags "mu" "m" "u" "") - elseif (pymalloc STREQUAL "ANY" AND unicode STREQUAL "ON") - set (abiflags "mu" "u") - elseif (pymalloc STREQUAL "ANY" AND unicode STREQUAL "OFF") - set (abiflags "m" "") - elseif (pymalloc STREQUAL "ON" AND unicode STREQUAL "ANY") - set (abiflags "mu" "m") - elseif (pymalloc STREQUAL "ON" AND unicode STREQUAL "ON") - set (abiflags "mu") - elseif (pymalloc STREQUAL "ON" AND unicode STREQUAL "OFF") - set (abiflags "m") - elseif (pymalloc STREQUAL "ON" AND unicode STREQUAL "ANY") - set (abiflags "u" "") - elseif (pymalloc STREQUAL "OFF" AND unicode STREQUAL "ON") - set (abiflags "u") - endif() - - if (pydebug STREQUAL "ON") - if (abiflags) - list (TRANSFORM abiflags PREPEND "d") - else() - set (abiflags "d") - endif() - elseif (pydebug STREQUAL "ANY") - if (abiflags) - set (flags "${abiflags}") - list (TRANSFORM flags PREPEND "d") - list (APPEND abiflags "${flags}") - else() - set (abiflags "" "d") - endif() - endif() - - set (${_PGABIFLAGS} "${abiflags}" PARENT_SCOPE) -endfunction() - -function (_PYTHON_GET_PATH_SUFFIXES _PYTHON_PGPS_PATH_SUFFIXES) - cmake_parse_arguments (PARSE_ARGV 1 _PGPS "INTERPRETER;COMPILER;LIBRARY;INCLUDE" "" "IMPLEMENTATIONS;VERSION") - - if (NOT _PGPS_IMPLEMENTATIONS) - set (_PGPS_IMPLEMENTATIONS ${_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS}) - endif() - - if (DEFINED _${_PYTHON_PREFIX}_ABIFLAGS) - set (abi "${_${_PYTHON_PREFIX}_ABIFLAGS}") - else() - set (abi "mu" "m" "u" "") - endif() - - set (path_suffixes) - - foreach (implementation IN LISTS _PGPS_IMPLEMENTATIONS) - if (implementation STREQUAL "CPython") - if (_PGPS_INTERPRETER) - list (APPEND path_suffixes bin Scripts) - else() - foreach (version IN LISTS _PGPS_VERSION) - if (_PGPS_LIBRARY) - if (CMAKE_LIBRARY_ARCHITECTURE) - list (APPEND path_suffixes lib/${CMAKE_LIBRARY_ARCHITECTURE}) - endif() - list (APPEND path_suffixes lib libs) - - if (CMAKE_LIBRARY_ARCHITECTURE) - set (suffixes "${abi}") - if (suffixes) - list (TRANSFORM suffixes PREPEND "lib/python${version}/config-${version}") - list (TRANSFORM suffixes APPEND "-${CMAKE_LIBRARY_ARCHITECTURE}") - else() - set (suffixes "lib/python${version}/config-${version}-${CMAKE_LIBRARY_ARCHITECTURE}") - endif() - list (APPEND path_suffixes ${suffixes}) - endif() - set (suffixes "${abi}") - if (suffixes) - list (TRANSFORM suffixes PREPEND "lib/python${version}/config-${version}") - else() - set (suffixes "lib/python${version}/config-${version}") - endif() - list (APPEND path_suffixes ${suffixes}) - elseif (_PGPS_INCLUDE) - set (suffixes "${abi}") - if (suffixes) - list (TRANSFORM suffixes PREPEND "include/python${version}") - else() - set (suffixes "include/python${version}") - endif() - list (APPEND path_suffixes ${suffixes} include) - endif() - endforeach() - endif() - elseif (implementation STREQUAL "IronPython") - if (_PGPS_INTERPRETER OR _PGPS_COMPILER) - foreach (version IN LISTS _PGPS_VERSION) - list (APPEND path_suffixes "share/ironpython${version}") - endforeach() - list (APPEND path_suffixes ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}) - endif() - elseif (implementation STREQUAL "PyPy") - if (_PGPS_INTERPRETER) - list (APPEND path_suffixes ${_${_PYTHON_PREFIX}_PYPY_EXECUTABLE_PATH_SUFFIXES}) - elseif (_PGPS_LIBRARY) - list (APPEND path_suffixes ${_${_PYTHON_PREFIX}_PYPY_LIBRARY_PATH_SUFFIXES}) - elseif (_PGPS_INCLUDE) - foreach (version IN LISTS _PGPS_VERSION) - list (APPEND path_suffixes lib/pypy${version}/include pypy${version}/include) - endforeach() - list (APPEND path_suffixes ${_${_PYTHON_PREFIX}_PYPY_INCLUDE_PATH_SUFFIXES}) - endif() - endif() - endforeach() - list (REMOVE_DUPLICATES path_suffixes) - - set (${_PYTHON_PGPS_PATH_SUFFIXES} ${path_suffixes} PARENT_SCOPE) -endfunction() - -function (_PYTHON_GET_NAMES _PYTHON_PGN_NAMES) - cmake_parse_arguments (PARSE_ARGV 1 _PGN "POSIX;INTERPRETER;COMPILER;CONFIG;LIBRARY;WIN32;DEBUG" "" "IMPLEMENTATIONS;VERSION") - - if (NOT _PGN_IMPLEMENTATIONS) - set (_PGN_IMPLEMENTATIONS ${_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS}) - endif() - - set (names) - - foreach (implementation IN LISTS _PGN_IMPLEMENTATIONS) - if (implementation STREQUAL "CPython") - if (_PGN_INTERPRETER AND _${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES STREQUAL "FIRST") - list (APPEND names python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} python) - endif() - foreach (version IN LISTS _PGN_VERSION) - if (_PGN_WIN32) - string (REPLACE "." "" version_no_dots ${version}) - - set (name python${version_no_dots}) - if (_PGN_DEBUG) - string (APPEND name "_d") - endif() - - list (APPEND names "${name}") - endif() - - if (_PGN_POSIX) - if (DEFINED _${_PYTHON_PREFIX}_ABIFLAGS) - set (abi "${_${_PYTHON_PREFIX}_ABIFLAGS}") - else() - if (_PGN_INTERPRETER OR _PGN_CONFIG) - set (abi "") - else() - set (abi "mu" "m" "u" "") - endif() - endif() - - if (abi) - if (_PGN_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE) - set (abinames "${abi}") - list (TRANSFORM abinames PREPEND "${CMAKE_LIBRARY_ARCHITECTURE}-python${version}") - list (TRANSFORM abinames APPEND "-config") - list (APPEND names ${abinames}) - endif() - set (abinames "${abi}") - list (TRANSFORM abinames PREPEND "python${version}") - if (_PGN_CONFIG) - list (TRANSFORM abinames APPEND "-config") - endif() - list (APPEND names ${abinames}) - else() - unset (abinames) - if (_PGN_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE) - set (abinames "${CMAKE_LIBRARY_ARCHITECTURE}-python${version}") - endif() - list (APPEND abinames "python${version}") - if (_PGN_CONFIG) - list (TRANSFORM abinames APPEND "-config") - endif() - list (APPEND names ${abinames}) - endif() - endif() - endforeach() - if (_PGN_INTERPRETER AND _${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES STREQUAL "LAST") - list (APPEND names python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} python) - endif() - elseif (implementation STREQUAL "IronPython") - if (_PGN_INTERPRETER) - if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") - # Do not use wrapper script on Linux because it is buggy: -c interpreter option cannot be used - foreach (version IN LISTS _PGN_VERSION) - list (APPEND names "ipy${version}") - endforeach() - endif() - list (APPEND names ${_${_PYTHON_PREFIX}_IRON_PYTHON_INTERPRETER_NAMES}) - elseif (_PGN_COMPILER) - list (APPEND names ${_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_NAMES}) - endif() - elseif (implementation STREQUAL "PyPy") - if (_PGN_INTERPRETER) - list (APPEND names ${_${_PYTHON_PREFIX}_PYPY_NAMES}) - elseif (_PGN_LIBRARY) - if (_PGN_WIN32) - foreach (version IN LISTS _PGN_VERSION) - string (REPLACE "." "" version_no_dots ${version}) - set (name "python${version_no_dots}") - if (_PGN_DEBUG) - string (APPEND name "_d") - endif() - list (APPEND names "${name}") - endforeach() - endif() - - if (_PGN_POSIX) - foreach(version IN LISTS _PGN_VERSION) - list (APPEND names "pypy${version}-c") - endforeach() - endif() - - list (APPEND names ${_${_PYTHON_PREFIX}_PYPY_LIB_NAMES}) - endif() - endif() - endforeach() - - set (${_PYTHON_PGN_NAMES} ${names} PARENT_SCOPE) -endfunction() - -function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) - unset (${_PYTHON_PGCV_VALUE} PARENT_SCOPE) - - if (NOT NAME MATCHES "^(PREFIX|ABIFLAGS|CONFIGDIR|INCLUDES|LIBS|SOABI|SOSABI)$") - return() - endif() - - if (NAME STREQUAL "SOSABI") - # assume some default - if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR CMAKE_SYSTEM_NAME MATCHES "MSYS|CYGWIN") - set (_values "") - else() - set (_values "abi${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}") - endif() - elseif (_${_PYTHON_PREFIX}_CONFIG) - if (NAME STREQUAL "SOABI") - set (config_flag "--extension-suffix") - else() - set (config_flag "--${NAME}") - endif() - string (TOLOWER "${config_flag}" config_flag) - execute_process (COMMAND ${_${_PYTHON_PREFIX}_CONFIG_LAUNCHER} ${config_flag} - RESULT_VARIABLE _result - OUTPUT_VARIABLE _values - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_result) - unset (_values) - else() - if (NAME STREQUAL "INCLUDES") - # do some clean-up - string (REGEX MATCHALL "(-I|-iwithsysroot)[ ]*[^ ]+" _values "${_values}") - string (REGEX REPLACE "(-I|-iwithsysroot)[ ]*" "" _values "${_values}") - list (REMOVE_DUPLICATES _values) - elseif (NAME STREQUAL "SOABI") - # clean-up: remove prefix character and suffix - if (_values MATCHES "^(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.so|\\.pyd)$") - set(_values "") - else() - string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}") - endif() - endif() - endif() - endif() - - if (_${_PYTHON_PREFIX}_EXECUTABLE AND NOT CMAKE_CROSSCOMPILING) - if (NAME STREQUAL "PREFIX") - execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_config_var('base') or '', sysconfig.get_config_var('installed_base') or '']))\nexcept Exception:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.PREFIX,sysconfig.EXEC_PREFIX,sysconfig.BASE_EXEC_PREFIX]))" - RESULT_VARIABLE _result - OUTPUT_VARIABLE _values - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_result) - unset (_values) - else() - list (REMOVE_DUPLICATES _values) - endif() - elseif (NAME STREQUAL "INCLUDES") - if (WIN32) - set (_scheme "nt") - else() - set (_scheme "posix_prefix") - endif() - execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys\ntry:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_path('platinclude'),sysconfig.get_path('platinclude','${_scheme}'),sysconfig.get_path('include'),sysconfig.get_path('include','${_scheme}')]))\nexcept Exception:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_python_inc(plat_specific=True),sysconfig.get_python_inc(plat_specific=False)]))" - RESULT_VARIABLE _result - OUTPUT_VARIABLE _values - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_result) - unset (_values) - else() - list (REMOVE_DUPLICATES _values) - endif() - elseif (NAME STREQUAL "SOABI") - # first step: compute SOABI form EXT_SUFFIX config variable - execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys\ntry:\n import sysconfig\n sys.stdout.write(sysconfig.get_config_var('EXT_SUFFIX') or '')\nexcept Exception:\n from distutils import sysconfig;sys.stdout.write(sysconfig.get_config_var('EXT_SUFFIX') or '')" - RESULT_VARIABLE _result - OUTPUT_VARIABLE _values - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_result) - unset (_values) - else() - if (_values) - # clean-up: remove prefix character and suffix - if (_values MATCHES "^(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.so|\\.pyd)$") - set(_values "") - else() - string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}") - endif() - endif() - endif() - - # second step: use SOABI or SO config variables as fallback - if (NOT _values) - execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys\ntry:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('SO') or '']))\nexcept Exception:\n from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('SO') or '']))" - RESULT_VARIABLE _result - OUTPUT_VARIABLE _soabi - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_result) - unset (_values) - else() - foreach (_item IN LISTS _soabi) - if (_item) - set (_values "${_item}") - break() - endif() - endforeach() - if (_values) - # clean-up: remove prefix character and suffix - if (_values MATCHES "^(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.so|\\.pyd)$") - set(_values "") - else() - string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}") - endif() - endif() - endif() - endif() - elseif (NAME STREQUAL "SOSABI") - execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\nimport re\nimport importlib.machinery\nsys.stdout.write(next(filter(lambda x: re.search('^\\.abi', x), importlib.machinery.EXTENSION_SUFFIXES)))" - RESULT_VARIABLE _result - OUTPUT_VARIABLE _values - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_result) - unset (_values) - else() - string (REGEX REPLACE "^\\.(.+)\\.[^.]+$" "\\1" _values "${_values}") - endif() - else() - set (config_flag "${NAME}") - if (NAME STREQUAL "CONFIGDIR") - set (config_flag "LIBPL") - endif() - execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys\ntry:\n import sysconfig\n sys.stdout.write(sysconfig.get_config_var('${config_flag}'))\nexcept Exception:\n from distutils import sysconfig\n sys.stdout.write(sysconfig.get_config_var('${config_flag}'))" - RESULT_VARIABLE _result - OUTPUT_VARIABLE _values - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_result) - unset (_values) - endif() - endif() - endif() - - if (NAME STREQUAL "ABIFLAGS" OR NAME STREQUAL "SOABI" OR NAME STREQUAL "SOSABI") - set (${_PYTHON_PGCV_VALUE} "${_values}" PARENT_SCOPE) - return() - endif() - - if (NOT _values OR _values STREQUAL "None") - return() - endif() - - if (NAME STREQUAL "LIBS") - # do some clean-up - string (REGEX MATCHALL "-(l|framework)[ ]*[^ ]+" _values "${_values}") - # remove elements relative to python library itself - list (FILTER _values EXCLUDE REGEX "-lpython") - list (REMOVE_DUPLICATES _values) - endif() - - if (WIN32 AND NAME MATCHES "^(PREFIX|CONFIGDIR|INCLUDES)$") - file (TO_CMAKE_PATH "${_values}" _values) - endif() - - set (${_PYTHON_PGCV_VALUE} "${_values}" PARENT_SCOPE) -endfunction() - -function (_PYTHON_GET_VERSION) - cmake_parse_arguments (PARSE_ARGV 0 _PGV "LIBRARY;SABI_LIBRARY;INCLUDE" "PREFIX" "") - - unset (${_PGV_PREFIX}VERSION PARENT_SCOPE) - unset (${_PGV_PREFIX}VERSION_MAJOR PARENT_SCOPE) - unset (${_PGV_PREFIX}VERSION_MINOR PARENT_SCOPE) - unset (${_PGV_PREFIX}VERSION_PATCH PARENT_SCOPE) - unset (${_PGV_PREFIX}ABI PARENT_SCOPE) - - if (_PGV_LIBRARY) - # retrieve version and abi from library name - if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE) - get_filename_component (library_name "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" NAME) - # extract version from library name - if (library_name MATCHES "python([23])([0-9]+)") - set (${_PGV_PREFIX}VERSION_MAJOR "${CMAKE_MATCH_1}" PARENT_SCOPE) - set (${_PGV_PREFIX}VERSION_MINOR "${CMAKE_MATCH_2}" PARENT_SCOPE) - set (${_PGV_PREFIX}VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}" PARENT_SCOPE) - set (${_PGV_PREFIX}ABI "" PARENT_SCOPE) - elseif (library_name MATCHES "python([23])\\.([0-9]+)([dmu]*)") - set (${_PGV_PREFIX}VERSION_MAJOR "${CMAKE_MATCH_1}" PARENT_SCOPE) - set (${_PGV_PREFIX}VERSION_MINOR "${CMAKE_MATCH_2}" PARENT_SCOPE) - set (${_PGV_PREFIX}VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}" PARENT_SCOPE) - set (${_PGV_PREFIX}ABI "${CMAKE_MATCH_3}" PARENT_SCOPE) - elseif (library_name MATCHES "pypy([23])\\.([0-9]+)-c") - set (${_PGV_PREFIX}VERSION_MAJOR "${CMAKE_MATCH_1}" PARENT_SCOPE) - set (${_PGV_PREFIX}VERSION_MINOR "${CMAKE_MATCH_2}" PARENT_SCOPE) - set (${_PGV_PREFIX}VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}" PARENT_SCOPE) - set (${_PGV_PREFIX}ABI "" PARENT_SCOPE) - elseif (library_name MATCHES "pypy(3)?-c") - set (version "${CMAKE_MATCH_1}") - # try to pick-up a more precise version from the path - get_filename_component (library_dir "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - if (library_dir MATCHES "/pypy([23])\\.([0-9]+)/") - set (${_PGV_PREFIX}VERSION_MAJOR "${CMAKE_MATCH_1}" PARENT_SCOPE) - set (${_PGV_PREFIX}VERSION_MINOR "${CMAKE_MATCH_2}" PARENT_SCOPE) - set (${_PGV_PREFIX}VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}" PARENT_SCOPE) - elseif (version EQUAL "3") - set (${_PGV_PREFIX}VERSION_MAJOR "3" PARENT_SCOPE) - set (${_PGV_PREFIX}VERSION "3" PARENT_SCOPE) - else() - set (${_PGV_PREFIX}VERSION_MAJOR "2" PARENT_SCOPE) - set (${_PGV_PREFIX}VERSION "2" PARENT_SCOPE) - endif() - set (${_PGV_PREFIX}ABI "" PARENT_SCOPE) - endif() - endif() - elseif (_PGV_SABI_LIBRARY) - # retrieve version and abi from library name - if (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) - get_filename_component (library_name "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}" NAME) - # extract version from library name - if (library_name MATCHES "python([23])([dmu]*)") - set (${_PGV_PREFIX}VERSION_MAJOR "${CMAKE_MATCH_1}" PARENT_SCOPE) - set (${_PGV_PREFIX}VERSION "${CMAKE_MATCH_1}" PARENT_SCOPE) - set (${_PGV_PREFIX}ABI "${CMAKE_MATCH_2}" PARENT_SCOPE) - elseif (library_name MATCHES "pypy([23])-c") - set (${_PGV_PREFIX}VERSION_MAJOR "${CMAKE_MATCH_1}" PARENT_SCOPE) - set (${_PGV_PREFIX}VERSION "${CMAKE_MATCH_1}" PARENT_SCOPE) - set (${_PGV_PREFIX}ABI "" PARENT_SCOPE) - elseif (library_name MATCHES "pypy-c") - # try to pick-up a more precise version from the path - get_filename_component (library_dir "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}" DIRECTORY) - if (library_dir MATCHES "/pypy([23])\\.([0-9]+)/") - set (${_PGV_PREFIX}VERSION_MAJOR "${CMAKE_MATCH_1}" PARENT_SCOPE) - set (${_PGV_PREFIX}VERSION "${CMAKE_MATCH_1}" PARENT_SCOPE) - endif() - set (${_PGV_PREFIX}ABI "" PARENT_SCOPE) - endif() - endif() - else() - if (_${_PYTHON_PREFIX}_INCLUDE_DIR) - # retrieve version from header file - file (STRINGS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/patchlevel.h" version - REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"") - string (REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" - version "${version}") - string (REGEX MATCHALL "[0-9]+" versions "${version}") - list (GET versions 0 version_major) - list (GET versions 1 version_minor) - list (GET versions 2 version_patch) - - set (${_PGV_PREFIX}VERSION "${version_major}.${version_minor}.${version_patch}" PARENT_SCOPE) - set (${_PGV_PREFIX}VERSION_MAJOR ${version_major} PARENT_SCOPE) - set (${_PGV_PREFIX}VERSION_MINOR ${version_minor} PARENT_SCOPE) - set (${_PGV_PREFIX}VERSION_PATCH ${version_patch} PARENT_SCOPE) - - # compute ABI flags - if (version_major VERSION_GREATER "2") - file (STRINGS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/pyconfig.h" config REGEX "(Py_DEBUG|WITH_PYMALLOC|Py_UNICODE_SIZE|MS_WIN32)") - set (abi) - if (config MATCHES "#[ ]*define[ ]+MS_WIN32") - # ABI not used on Windows - set (abi "") - else() - if (NOT config) - # pyconfig.h can be a wrapper to a platform specific pyconfig.h - # In this case, try to identify ABI from include directory - if (_${_PYTHON_PREFIX}_INCLUDE_DIR MATCHES "python${version_major}\\.${version_minor}+([dmu]*)") - set (abi "${CMAKE_MATCH_1}") - else() - set (abi "") - endif() - else() - if (config MATCHES "#[ ]*define[ ]+Py_DEBUG[ ]+1") - string (APPEND abi "d") - endif() - if (config MATCHES "#[ ]*define[ ]+WITH_PYMALLOC[ ]+1") - string (APPEND abi "m") - endif() - if (config MATCHES "#[ ]*define[ ]+Py_UNICODE_SIZE[ ]+4") - string (APPEND abi "u") - endif() - endif() - set (${_PGV_PREFIX}ABI "${abi}" PARENT_SCOPE) - endif() - else() - # ABI not supported - set (${_PGV_PREFIX}ABI "" PARENT_SCOPE) - endif() - endif() - endif() -endfunction() - -function (_PYTHON_GET_LAUNCHER _PYTHON_PGL_NAME) - cmake_parse_arguments (PARSE_ARGV 1 _PGL "INTERPRETER;COMPILER" "CONFIG" "") - - unset (${_PYTHON_PGL_NAME} PARENT_SCOPE) - - if ((_PGL_INTERPRETER AND NOT _${_PYTHON_PREFIX}_EXECUTABLE) - OR (_PGL_COMPILER AND NOT _${_PYTHON_PREFIX}_COMPILER) - OR (_PGL_CONFIG AND NOT _${_PYTHON_PREFIX}_CONFIG)) - return() - endif() - - if (_PGL_CONFIG) - # default config script can be launched directly - set (${_PYTHON_PGL_NAME} "${_${_PYTHON_PREFIX}_CONFIG}" PARENT_SCOPE) - - if (NOT MINGW) - return() - endif() - # on MINGW environment, python-config script may require bash to be launched - execute_process (COMMAND cygpath.exe -u "${_${_PYTHON_PREFIX}_CONFIG}" - RESULT_VARIABLE _result - OUTPUT_VARIABLE _config - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_result) - # impossible to convert path, keep default config - return() - endif() - execute_process (COMMAND bash.exe "${_config}" --prefix - RESULT_VARIABLE _result - OUTPUT_QUIET - ERROR_QUIET) - if (_result) - # fail to execute through bash, keep default config - return() - endif() - - set(${_PYTHON_PGL_NAME} bash.exe "${_config}" PARENT_SCOPE) - return() - endif() - - if ("IronPython" IN_LIST _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS - AND NOT SYSTEM_NAME MATCHES "Windows|Linux") - if (_PGL_INTERPRETER) - get_filename_component (name "${_${_PYTHON_PREFIX}_EXECUTABLE}" NAME) - get_filename_component (ext "${_${_PYTHON_PREFIX}_EXECUTABLE}" LAST_EXT) - if (name IN_LIST _${_PYTHON_PREFIX}_IRON_PYTHON_INTERPRETER_NAMES - AND ext STREQUAL ".exe") - set (${_PYTHON_PGL_NAME} "${${_PYTHON_PREFIX}_DOTNET_LAUNCHER}" PARENT_SCOPE) - endif() - elseif (_PGL_COMPILER) - get_filename_component (name "${_${_PYTHON_PREFIX}_COMPILER}" NAME) - get_filename_component (ext "${_${_PYTHON_PREFIX}_COMPILER}" LAST_EXT) - if (name IN_LIST _${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_NAMES - AND ext STREQUAL ".exe") - set (${_PYTHON_PGL_NAME} "${${_PYTHON_PREFIX}_DOTNET_LAUNCHER}" PARENT_SCOPE) - endif() - endif() - endif() -endfunction() - - -function (_PYTHON_VALIDATE_INTERPRETER) - if (NOT _${_PYTHON_PREFIX}_EXECUTABLE) - return() - endif() - - cmake_parse_arguments (PARSE_ARGV 0 _PVI "IN_RANGE;EXACT;CHECK_EXISTS" "VERSION" "") - - if (_PVI_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_EXECUTABLE}") - # interpreter does not exist anymore - set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Cannot find the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") - set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") - return() - endif() - - _python_get_launcher (launcher INTERPRETER) - - # validate ABI compatibility - if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI) - execute_process (COMMAND ${launcher} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write(sys.abiflags)" - RESULT_VARIABLE result - OUTPUT_VARIABLE abi - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result) - # assume ABI is not supported - set (abi "") - endif() - if (NOT abi IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS) - # incompatible ABI - set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong ABI for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") - set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") - return() - endif() - endif() - - if (_PVI_IN_RANGE OR _PVI_VERSION) - # retrieve full version - execute_process (COMMAND ${launcher} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result) - # interpreter is not usable - set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") - set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") - return() - endif() - - if (_PVI_VERSION) - # check against specified version - ## compute number of components for version - string (REGEX REPLACE "[^.]" "" dots "${_PVI_VERSION}") - ## add one dot because there is one dot less than there are components - string (LENGTH "${dots}." count) - if (count GREATER 3) - set (count 3) - endif() - set (version_regex "^[0-9]+") - if (count EQUAL 3) - string (APPEND version_regex "\\.[0-9]+\\.[0-9]+") - elseif (count EQUAL 2) - string (APPEND version_regex "\\.[0-9]+") - endif() - # extract needed range - string (REGEX MATCH "${version_regex}" version "${version}") - - if (_PVI_EXACT AND NOT version VERSION_EQUAL _PVI_VERSION) - # interpreter has wrong version - set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") - set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") - return() - else() - # check that version is OK - string(REGEX REPLACE "^([0-9]+)\\.?.*$" "\\1" major_version "${version}") - string(REGEX REPLACE "^([0-9]+)\\.?.*$" "\\1" expected_major_version "${_PVI_VERSION}") - if (NOT major_version VERSION_EQUAL expected_major_version - OR NOT version VERSION_GREATER_EQUAL _PVI_VERSION) - set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") - set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") - return() - endif() - endif() - endif() - - if (_PVI_IN_RANGE) - # check if version is in the requested range - find_package_check_version ("${version}" in_range HANDLE_VERSION_RANGE) - if (NOT in_range) - # interpreter has invalid version - set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") - set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") - return() - endif() - endif() - else() - get_filename_component (python_name "${_${_PYTHON_PREFIX}_EXECUTABLE}" NAME) - if (NOT python_name STREQUAL "python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}${CMAKE_EXECUTABLE_SUFFIX}") - # executable found do not have version in name - # ensure major version is OK - execute_process (COMMAND ${launcher} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write(str(sys.version_info[0]))" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - # interpreter not usable or has wrong major version - if (result) - set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") - else() - set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong major version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") - endif() - set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") - return() - endif() - endif() - endif() - - if (CMAKE_SIZEOF_VOID_P AND ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - OR "Development.SABIModule" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - AND NOT CMAKE_CROSSCOMPILING) - # In this case, interpreter must have same architecture as environment - execute_process (COMMAND ${launcher} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys, struct; sys.stdout.write(str(struct.calcsize(\"P\")))" - RESULT_VARIABLE result - OUTPUT_VARIABLE size - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT size EQUAL CMAKE_SIZEOF_VOID_P) - # interpreter not usable or has wrong architecture - if (result) - set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") - else() - set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong architecture for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") - endif() - set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") - return() - endif() - - if (WIN32) - # In this case, check if the interpreter is compatible with the target processor architecture - if (NOT CMAKE_GENERATOR_PLATFORM AND CMAKE_SYSTEM_PROCESSOR MATCHES "ARM" OR CMAKE_GENERATOR_PLATFORM MATCHES "ARM") - set(target_arm TRUE) - else() - set(target_arm FALSE) - endif() - execute_process (COMMAND ${launcher} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys, sysconfig; sys.stdout.write(sysconfig.get_platform())" - RESULT_VARIABLE result - OUTPUT_VARIABLE platform - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - string(TOUPPER "${platform}" platform) - if (result OR ((target_arm AND NOT platform MATCHES "ARM") OR - (NOT target_arm AND platform MATCHES "ARM"))) - # interpreter not usable or has wrong architecture - if (result) - set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") - else() - set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong architecture for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") - endif() - set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") - return() - endif() - endif() - endif() -endfunction() - -function(_python_validate_find_interpreter status interpreter) - set(_${_PYTHON_PREFIX}_EXECUTABLE "${interpreter}" CACHE FILEPATH "" FORCE) - _python_validate_interpreter (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) - if (NOT _${_PYTHON_PREFIX}_EXECUTABLE) - set (${status} FALSE PARENT_SCOPE) - endif() -endfunction() - - -function (_PYTHON_VALIDATE_COMPILER) - if (NOT _${_PYTHON_PREFIX}_COMPILER) - return() - endif() - - cmake_parse_arguments (PARSE_ARGV 0 _PVC "IN_RANGE;EXACT;CHECK_EXISTS" "VERSION" "") - - if (_PVC_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_COMPILER}") - # Compiler does not exist anymore - set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Cannot find the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"") - set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND") - return() - endif() - - _python_get_launcher (launcher COMPILER) - - # retrieve python environment version from compiler - set (working_dir "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") - file (WRITE "${working_dir}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]])); sys.stdout.flush()\n") - execute_process (COMMAND ${launcher} "${_${_PYTHON_PREFIX}_COMPILER}" - ${_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_ARCH_FLAGS} - /target:exe /embed "${working_dir}/version.py" - WORKING_DIRECTORY "${working_dir}" - OUTPUT_QUIET - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - get_filename_component (ir_dir "${_${_PYTHON_PREFIX}_COMPILER}" DIRECTORY) - execute_process (COMMAND "${CMAKE_COMMAND}" -E env "MONO_PATH=${ir_dir}" - ${${_PYTHON_PREFIX}_DOTNET_LAUNCHER} "${working_dir}/version.exe" - WORKING_DIRECTORY "${working_dir}" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET) - file (REMOVE_RECURSE "${working_dir}") - if (result) - # compiler is not usable - set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Cannot use the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"") - set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND") - return() - endif() - - if (_PVC_VERSION OR _PVC_IN_RANGE) - if (_PVC_VERSION) - # check against specified version - ## compute number of components for version - string (REGEX REPLACE "[^.]" "" dots "${_PVC_VERSION}") - ## add one dot because there is one dot less than there are components - string (LENGTH "${dots}." count) - if (count GREATER 3) - set (count 3) - endif() - set (version_regex "^[0-9]+") - if (count EQUAL 3) - string (APPEND version_regex "\\.[0-9]+\\.[0-9]+") - elseif (count EQUAL 2) - string (APPEND version_regex "\\.[0-9]+") - endif() - # extract needed range - string (REGEX MATCH "${version_regex}" version "${version}") - - if (_PVC_EXACT AND NOT version VERSION_EQUAL _PVC_VERSION) - # interpreter has wrong version - set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Wrong version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"") - set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND") - return() - else() - # check that version is OK - string(REGEX REPLACE "^([0-9]+)\\.?.*$" "\\1" major_version "${version}") - string(REGEX REPLACE "^([0-9]+)\\.?.*$" "\\1" expected_major_version "${_PVC_VERSION}") - if (NOT major_version VERSION_EQUAL expected_major_version - OR NOT version VERSION_GREATER_EQUAL _PVC_VERSION) - set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Wrong version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"") - set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND") - return() - endif() - endif() - endif() - - if (_PVC_IN_RANGE) - # check if version is in the requested range - find_package_check_version ("${version}" in_range HANDLE_VERSION_RANGE) - if (NOT in_range) - # interpreter has invalid version - set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Wrong version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"") - set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND") - return() - endif() - endif() - else() - string(REGEX REPLACE "^([0-9]+)\\.?.*$" "\\1" major_version "${version}") - if (NOT major_version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - # Compiler has wrong major version - set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Wrong major version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"") - set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND") - return() - endif() - endif() -endfunction() - -function(_python_validate_find_compiler status compiler) - set(_${_PYTHON_PREFIX}_COMPILER "${compiler}" CACHE FILEPATH "" FORCE) - _python_validate_compiler (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) - if (NOT _${_PYTHON_PREFIX}_COMPILER) - set (${status} FALSE PARENT_SCOPE) - endif() -endfunction() - - -function (_PYTHON_VALIDATE_LIBRARY) - if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE) - unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG) - return() - endif() - - cmake_parse_arguments (PARSE_ARGV 0 _PVL "IN_RANGE;EXACT;CHECK_EXISTS" "VERSION" "") - - if (_PVL_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}") - # library does not exist anymore - set_property (CACHE _${_PYTHON_PREFIX}_Development_LIBRARY_REASON_FAILURE PROPERTY VALUE "Cannot find the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"") - set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND") - if (WIN32) - set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_DEBUG PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_DEBUG-NOTFOUND") - endif() - set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") - return() - endif() - - # retrieve version and abi from library name - _python_get_version (LIBRARY PREFIX lib_) - - if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT lib_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS) - # incompatible ABI - set_property (CACHE _${_PYTHON_PREFIX}_Development_LIBRARY_REASON_FAILURE PROPERTY VALUE "Wrong ABI for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"") - set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND") - else() - if (_PVL_VERSION OR _PVL_IN_RANGE) - if (_PVL_VERSION) - # library have only major.minor information - string (REGEX MATCH "[0-9](\\.[0-9]+)?" version "${_PVL_VERSION}") - if ((_PVL_EXACT AND NOT lib_VERSION VERSION_EQUAL version) OR (lib_VERSION VERSION_LESS version)) - # library has wrong version - set_property (CACHE _${_PYTHON_PREFIX}_Development_LIBRARY_REASON_FAILURE PROPERTY VALUE "Wrong version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"") - set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND") - endif() - endif() - - if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND _PVL_IN_RANGE) - # check if library version is in the requested range - find_package_check_version ("${lib_VERSION}" in_range HANDLE_VERSION_RANGE) - if (NOT in_range) - # library has wrong version - set_property (CACHE _${_PYTHON_PREFIX}_Development_LIBRARY_REASON_FAILURE PROPERTY VALUE "Wrong version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"") - set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND") - endif() - endif() - else() - if (NOT lib_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - # library has wrong major version - set_property (CACHE _${_PYTHON_PREFIX}_Development_LIBRARY_REASON_FAILURE PROPERTY VALUE "Wrong major version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"") - set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND") - endif() - endif() - endif() - - if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE) - if (WIN32) - set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_DEBUG PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_DEBUG-NOTFOUND") - endif() - unset (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE CACHE) - unset (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG CACHE) - set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") - endif() -endfunction() - - -function (_PYTHON_VALIDATE_SABI_LIBRARY) - if (NOT _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) - unset (_${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG) - return() - endif() - - cmake_parse_arguments (PARSE_ARGV 0 _PVL "CHECK_EXISTS" "" "") - - if (_PVL_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}") - # library does not exist anymore - set_property (CACHE _${_PYTHON_PREFIX}_Development_SABI_LIBRARY_REASON_FAILURE PROPERTY VALUE "Cannot find the library \"${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}\"") - set_property (CACHE _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE-NOTFOUND") - if (WIN32) - set_property (CACHE _${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG PROPERTY VALUE "${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG-NOTFOUND") - endif() - set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") - return() - endif() - - # retrieve version and abi from library name - _python_get_version (SABI_LIBRARY PREFIX lib_) - - if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT lib_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS) - # incompatible ABI - set_property (CACHE _${_PYTHON_PREFIX}_Development_SABI_LIBRARY_REASON_FAILURE PROPERTY VALUE "Wrong ABI for the library \"${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}\"") - set_property (CACHE _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE-NOTFOUND") - else() - if (NOT lib_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - # library has wrong major version - set_property (CACHE _${_PYTHON_PREFIX}_Development_SABI_LIBRARY_REASON_FAILURE PROPERTY VALUE "Wrong major version for the library \"${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}\"") - set_property (CACHE _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE-NOTFOUND") - endif() - endif() - - if (NOT _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) - if (WIN32) - set_property (CACHE _${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_DEBUG-NOTFOUND") - endif() - unset (_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_RELEASE CACHE) - unset (_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DEBUG CACHE) - set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") - endif() -endfunction() - - -function (_PYTHON_VALIDATE_INCLUDE_DIR) - if (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR) - return() - endif() - - cmake_parse_arguments (PARSE_ARGV 0 _PVID "IN_RANGE;EXACT;CHECK_EXISTS" "VERSION" "") - - if (_PVID_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}") - # include file does not exist anymore - set_property (CACHE _${_PYTHON_PREFIX}_Development_INCLUDE_DIR_REASON_FAILURE PROPERTY VALUE "Cannot find the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"") - set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") - return() - endif() - - # retrieve version from header file - _python_get_version (INCLUDE PREFIX inc_) - - if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT inc_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS) - # incompatible ABI - set_property (CACHE _${_PYTHON_PREFIX}_Development_INCLUDE_DIR_REASON_FAILURE PROPERTY VALUE "Wrong ABI for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"") - set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") - else() - if (_PVID_VERSION OR _PVID_IN_RANGE) - if (_PVID_VERSION) - if ((_PVID_EXACT AND NOT inc_VERSION VERSION_EQUAL expected_version) OR (inc_VERSION VERSION_LESS expected_version)) - # include dir has wrong version - set_property (CACHE _${_PYTHON_PREFIX}_Development_INCLUDE_DIR_REASON_FAILURE PROPERTY VALUE "Wrong version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"") - set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") - endif() - endif() - - if (_${_PYTHON_PREFIX}_INCLUDE_DIR AND PVID_IN_RANGE) - # check if include dir is in the request range - find_package_check_version ("${inc_VERSION}" in_range HANDLE_VERSION_RANGE) - if (NOT in_range) - # include dir has wrong version - set_property (CACHE _${_PYTHON_PREFIX}_Development_INCLUDE_DIR_REASON_FAILURE PROPERTY VALUE "Wrong version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"") - set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") - endif() - endif() - else() - if (NOT inc_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - # include dir has wrong major version - set_property (CACHE _${_PYTHON_PREFIX}_Development_INCLUDE_DIR_REASON_FAILURE PROPERTY VALUE "Wrong major version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"") - set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") - endif() - endif() - endif() -endfunction() - - -function (_PYTHON_FIND_RUNTIME_LIBRARY _PYTHON_LIB) - string (REPLACE "_RUNTIME" "" _PYTHON_LIB "${_PYTHON_LIB}") - # look at runtime part on systems supporting it - if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR - (CMAKE_SYSTEM_NAME MATCHES "MSYS|CYGWIN" - AND ${_PYTHON_LIB} MATCHES "${CMAKE_IMPORT_LIBRARY_SUFFIX}$")) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX}) - # MSYS has a special syntax for runtime libraries - if (CMAKE_SYSTEM_NAME MATCHES "MSYS") - list (APPEND CMAKE_FIND_LIBRARY_PREFIXES "msys-") - endif() - find_library (${ARGV}) - endif() -endfunction() - - -function (_PYTHON_SET_LIBRARY_DIRS _PYTHON_SLD_RESULT) - unset (_PYTHON_DIRS) - set (_PYTHON_LIBS ${ARGN}) - foreach (_PYTHON_LIB IN LISTS _PYTHON_LIBS) - if (${_PYTHON_LIB}) - get_filename_component (_PYTHON_DIR "${${_PYTHON_LIB}}" DIRECTORY) - list (APPEND _PYTHON_DIRS "${_PYTHON_DIR}") - endif() - endforeach() - list (REMOVE_DUPLICATES _PYTHON_DIRS) - set (${_PYTHON_SLD_RESULT} ${_PYTHON_DIRS} PARENT_SCOPE) -endfunction() - - -function (_PYTHON_SET_DEVELOPMENT_MODULE_FOUND module) - if ("Development.${module}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - if (module STREQUAL "SABIModule" - AND "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}" VERSION_LESS "3.2") - # Stable API was introduced in version 3.2 - set (${_PYTHON_PREFIX}_Development.SABIModule_FOUND FALSE PARENT_SCOPE) - _python_add_reason_failure ("Development" "SABIModule requires version 3.2 or upper.") - return() - endif() - - string(TOUPPER "${module}" id) - set (module_found TRUE) - - if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS - AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE) - set (module_found FALSE) - endif() - if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS - AND NOT _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) - set (module_found FALSE) - endif() - if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS - AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR) - set (module_found FALSE) - endif() - - set (${_PYTHON_PREFIX}_Development.${module}_FOUND ${module_found} PARENT_SCOPE) - endif() -endfunction() - - -if (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) - # range must include internal major version - if (${_PYTHON_PREFIX}_FIND_VERSION_MIN_MAJOR VERSION_GREATER _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR - OR ((${_PYTHON_PREFIX}_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" - AND ${_PYTHON_PREFIX}_FIND_VERSION_MAX VERSION_LESS _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - OR (${_PYTHON_PREFIX}_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" - AND ${_PYTHON_PREFIX}_FIND_VERSION_MAX VERSION_LESS_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR))) - _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Wrong version range specified is \"${${_PYTHON_PREFIX}_FIND_VERSION_RANGE}\", but expected version range must include major version \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") - - cmake_policy(POP) - return() - endif() -else() - if (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR - AND NOT ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - # If major version is specified, it must be the same as internal major version - _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Wrong major version specified is \"${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}\", but expected major version is \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") - - cmake_policy(POP) - return() - endif() -endif() - - -# handle components -if (NOT ${_PYTHON_PREFIX}_FIND_COMPONENTS) - set (${_PYTHON_PREFIX}_FIND_COMPONENTS Interpreter) - set (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter TRUE) -endif() -if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Interpreter" "Development.Module") -endif() -if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Development.Module" "Development.Embed") -endif() -list (REMOVE_DUPLICATES ${_PYTHON_PREFIX}_FIND_COMPONENTS) -foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development Development.Module Development.SABIModule Development.Embed NumPy) - set (${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND FALSE) -endforeach() -if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development) - set (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Module TRUE) - set (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Embed TRUE) -endif() - -unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) -unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS) -unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS) -unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS) -if ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$") - list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS "LIBRARY") - endif() - list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS "INCLUDE_DIR") -endif() -if ("Development.SABIModule" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$") - list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS "SABI_LIBRARY") - endif() - list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS "INCLUDE_DIR") -endif() -if ("Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS "LIBRARY" "INCLUDE_DIR") -endif() -set (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS} ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS} ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS}) -list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) - -# Set versions to search -## default: search any version -set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSIONS}) -unset (_${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - -if (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) - unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_VERSIONS) - if ((${_PYTHON_PREFIX}_FIND_VERSION_RANGE_MIN STREQUAL "INCLUDE" - AND _${_PYTHON_PREFIX}_VERSION VERSION_GREATER_EQUAL ${_PYTHON_PREFIX}_FIND_VERSION_MIN) - AND ((${_PYTHON_PREFIX}_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" - AND _${_PYTHON_PREFIX}_VERSION VERSION_LESS_EQUAL ${_PYTHON_PREFIX}_FIND_VERSION_MAX) - OR (${_PYTHON_PREFIX}_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" - AND _${_PYTHON_PREFIX}_VERSION VERSION_LESS ${_PYTHON_PREFIX}_FIND_VERSION_MAX))) - list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSION}) - endif() - endforeach() -else() - if (${_PYTHON_PREFIX}_FIND_VERSION_COUNT GREATER 1) - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - set (_${_PYTHON_PREFIX}_FIND_VERSION_EXACT "EXACT") - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR}) - else() - unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) - # add all compatible versions - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_VERSIONS) - if (_${_PYTHON_PREFIX}_VERSION VERSION_GREATER_EQUAL "${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR}") - list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSION}) - endif() - endforeach() - endif() - endif() -endif() - -# Set ABIs to search -## default: search any ABI -if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_LESS "3") - # ABI not supported - unset (_${_PYTHON_PREFIX}_FIND_ABI) - set (_${_PYTHON_PREFIX}_ABIFLAGS "") -else() - unset (_${_PYTHON_PREFIX}_FIND_ABI) - unset (_${_PYTHON_PREFIX}_ABIFLAGS) - if (DEFINED ${_PYTHON_PREFIX}_FIND_ABI) - # normalization - string (TOUPPER "${${_PYTHON_PREFIX}_FIND_ABI}" _${_PYTHON_PREFIX}_FIND_ABI) - list (TRANSFORM _${_PYTHON_PREFIX}_FIND_ABI REPLACE "^(TRUE|Y(ES)?|1)$" "ON") - list (TRANSFORM _${_PYTHON_PREFIX}_FIND_ABI REPLACE "^(FALSE|N(O)?|0)$" "OFF") - if (NOT _${_PYTHON_PREFIX}_FIND_ABI MATCHES "^(ON|OFF|ANY);(ON|OFF|ANY);(ON|OFF|ANY)$") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_ABI}: invalid value for '${_PYTHON_PREFIX}_FIND_ABI'. Ignore it") - unset (_${_PYTHON_PREFIX}_FIND_ABI) - endif() - _python_get_abiflags (_${_PYTHON_PREFIX}_ABIFLAGS) - endif() -endif() -unset (${_PYTHON_PREFIX}_SOABI) -unset (${_PYTHON_PREFIX}_SOSABI) - -# Define lookup strategy -cmake_policy (GET CMP0094 _${_PYTHON_PREFIX}_LOOKUP_POLICY) -if (_${_PYTHON_PREFIX}_LOOKUP_POLICY STREQUAL "NEW") - set (_${_PYTHON_PREFIX}_FIND_STRATEGY "LOCATION") -else() - set (_${_PYTHON_PREFIX}_FIND_STRATEGY "VERSION") -endif() -if (DEFINED ${_PYTHON_PREFIX}_FIND_STRATEGY) - if (NOT ${_PYTHON_PREFIX}_FIND_STRATEGY MATCHES "^(VERSION|LOCATION)$") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_STRATEGY}: invalid value for '${_PYTHON_PREFIX}_FIND_STRATEGY'. 'VERSION' or 'LOCATION' expected.") - set (_${_PYTHON_PREFIX}_FIND_STRATEGY "VERSION") - else() - set (_${_PYTHON_PREFIX}_FIND_STRATEGY "${${_PYTHON_PREFIX}_FIND_STRATEGY}") - endif() -endif() - -# Python and Anaconda distributions: define which architectures can be used -unset (_${_PYTHON_PREFIX}_REGISTRY_VIEW) -if (CMAKE_SIZEOF_VOID_P) - math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8") - if ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - OR "Development.SABIModule" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - # In this case, search only for 64bit or 32bit - set (_${_PYTHON_PREFIX}_REGISTRY_VIEW REGISTRY_VIEW ${_${_PYTHON_PREFIX}_ARCH}) - if (WIN32 AND (NOT CMAKE_GENERATOR_PLATFORM AND CMAKE_SYSTEM_PROCESSOR MATCHES "ARM" - OR CMAKE_GENERATOR_PLATFORM MATCHES "ARM")) - # search exclusively ARM architecture: 64bit or 32bit - if (_${_PYTHON_PREFIX}_ARCH EQUAL 64) - set (_${_PYTHON_PREFIX}_ARCH ARM64) - else() - set (_${_PYTHON_PREFIX}_ARCH ARM) - endif() - endif() - else() - if (_${_PYTHON_PREFIX}_ARCH EQUAL "32") - if (CMAKE_SYSTEM_PROCESSOR MATCHES "ARM") - # search first ARM architectures: 32bit and then 64bit - list (PREPEND _${_PYTHON_PREFIX}_ARCH ARM ARM64) - endif() - list (APPEND _${_PYTHON_PREFIX}_ARCH 64) - else() - if (CMAKE_SYSTEM_PROCESSOR MATCHES "ARM") - # search first ARM architectures: 64bit and then 32bit - list (PREPEND _${_PYTHON_PREFIX}_ARCH ARM64 ARM) - endif() - list (APPEND _${_PYTHON_PREFIX}_ARCH 32) - endif() - endif() -else() - # architecture unknown, search for both 64bit and 32bit - set (_${_PYTHON_PREFIX}_ARCH 64 32) - if (CMAKE_SYSTEM_PROCESSOR MATCHES "ARM") - list (PREPEND _${_PYTHON_PREFIX}_ARCH ARM64 ARM) - endif() -endif() - -# IronPython support -unset (_${_PYTHON_PREFIX}_IRON_PYTHON_INTERPRETER_NAMES) -unset (_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_NAMES) -unset (_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_ARCH_FLAGS) -if (CMAKE_SIZEOF_VOID_P) - if (CMAKE_SIZEOF_VOID_P EQUAL "4") - set (_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_ARCH_FLAGS "/platform:x86") - else() - set (_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_ARCH_FLAGS "/platform:x64") - endif() -endif() -if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") - # Do not use wrapper script on Linux because it is buggy: -c interpreter option cannot be used - list (APPEND _${_PYTHON_PREFIX}_IRON_PYTHON_INTERPRETER_NAMES "ipy${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}" "ipy64" "ipy32" "ipy") - list (APPEND _${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_NAMES "ipyc") -endif() -list (APPEND _${_PYTHON_PREFIX}_IRON_PYTHON_INTERPRETER_NAMES "ipy.exe") -list (APPEND _${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_NAMES "ipyc.exe") -set (_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES net45 net40 bin) - -# PyPy support -if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL "3") - set (_${_PYTHON_PREFIX}_PYPY_NAMES pypy3) - set (_${_PYTHON_PREFIX}_PYPY_LIB_NAMES pypy3-c) - if (WIN32) - # special name for runtime part - list (APPEND _${_PYTHON_PREFIX}_PYPY_LIB_NAMES libpypy3-c) - endif() - set (_${_PYTHON_PREFIX}_PYPY_INCLUDE_PATH_SUFFIXES lib/pypy3/include pypy3/include) -else() - set (_${_PYTHON_PREFIX}_PYPY_NAMES pypy) - set (_${_PYTHON_PREFIX}_PYPY_LIB_NAMES pypy-c) - if (WIN32) - # special name for runtime part - list (APPEND _${_PYTHON_PREFIX}_PYPY_LIB_NAMES libpypy-c) - endif() - set (_${_PYTHON_PREFIX}_PYPY_INCLUDE_PATH_SUFFIXES lib/pypy/include pypy/include) -endif() -list (APPEND _${_PYTHON_PREFIX}_PYPY_INCLUDE_PATH_SUFFIXES libexec/include) -set (_${_PYTHON_PREFIX}_PYPY_EXECUTABLE_PATH_SUFFIXES bin) -set (_${_PYTHON_PREFIX}_PYPY_LIBRARY_PATH_SUFFIXES lib libs bin) -list (APPEND _${_PYTHON_PREFIX}_PYPY_INCLUDE_PATH_SUFFIXES include) - -# Python Implementations handling -unset (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS) -if (DEFINED ${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS) - foreach (_${_PYTHON_PREFIX}_IMPLEMENTATION IN LISTS ${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS) - if (NOT _${_PYTHON_PREFIX}_IMPLEMENTATION MATCHES "^(CPython|IronPython|PyPy)$") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${_${_PYTHON_PREFIX}_IMPLEMENTATION}: invalid value for '${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS'. 'CPython', 'IronPython' or 'PyPy' expected. Value will be ignored.") - else() - list (APPEND _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS ${_${_PYTHON_PREFIX}_IMPLEMENTATION}) - endif() - endforeach() -else() - if (WIN32) - set (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS CPython IronPython) - else() - set (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS CPython) - endif() -endif() - -# compute list of names for header file -unset (_${_PYTHON_PREFIX}_INCLUDE_NAMES) -foreach (_${_PYTHON_PREFIX}_IMPLEMENTATION IN LISTS _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS) - if (_${_PYTHON_PREFIX}_IMPLEMENTATION STREQUAL "CPython") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_NAMES "Python.h") - elseif (_${_PYTHON_PREFIX}_IMPLEMENTATION STREQUAL "PyPy") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_NAMES "PyPy.h" "pypy_decl.h") - endif() -endforeach() - - -# Apple frameworks handling -_python_find_frameworks () - -set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK "FIRST") - -if (DEFINED ${_PYTHON_PREFIX}_FIND_FRAMEWORK) - if (NOT ${_PYTHON_PREFIX}_FIND_FRAMEWORK MATCHES "^(FIRST|LAST|NEVER)$") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_FRAMEWORK}: invalid value for '${_PYTHON_PREFIX}_FIND_FRAMEWORK'. 'FIRST', 'LAST' or 'NEVER' expected. 'FIRST' will be used instead.") - else() - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK ${${_PYTHON_PREFIX}_FIND_FRAMEWORK}) - endif() -elseif (DEFINED CMAKE_FIND_FRAMEWORK) - if (CMAKE_FIND_FRAMEWORK STREQUAL "ONLY") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: CMAKE_FIND_FRAMEWORK: 'ONLY' value is not supported. 'FIRST' will be used instead.") - elseif (NOT CMAKE_FIND_FRAMEWORK MATCHES "^(FIRST|LAST|NEVER)$") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${CMAKE_FIND_FRAMEWORK}: invalid value for 'CMAKE_FIND_FRAMEWORK'. 'FIRST', 'LAST' or 'NEVER' expected. 'FIRST' will be used instead.") - else() - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) - endif() -endif() - -# Save CMAKE_FIND_APPBUNDLE -if (DEFINED CMAKE_FIND_APPBUNDLE) - set (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE ${CMAKE_FIND_APPBUNDLE}) -else() - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) -endif() -# To avoid app bundle lookup -set (CMAKE_FIND_APPBUNDLE "NEVER") - -# Save CMAKE_FIND_FRAMEWORK -if (DEFINED CMAKE_FIND_FRAMEWORK) - set (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) -else() - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) -endif() -# To avoid framework lookup -set (CMAKE_FIND_FRAMEWORK "NEVER") - -# Windows Registry handling -if (DEFINED ${_PYTHON_PREFIX}_FIND_REGISTRY) - if (NOT ${_PYTHON_PREFIX}_FIND_REGISTRY MATCHES "^(FIRST|LAST|NEVER)$") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_REGISTRY}: invalid value for '${_PYTHON_PREFIX}_FIND_REGISTRY'. 'FIRST', 'LAST' or 'NEVER' expected. 'FIRST' will be used instead.") - set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") - else() - set (_${_PYTHON_PREFIX}_FIND_REGISTRY ${${_PYTHON_PREFIX}_FIND_REGISTRY}) - endif() -else() - set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") -endif() - -# virtual environments recognition -if (DEFINED ENV{VIRTUAL_ENV} OR DEFINED ENV{CONDA_PREFIX}) - if (DEFINED ${_PYTHON_PREFIX}_FIND_VIRTUALENV) - if (NOT ${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY|STANDARD)$") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_VIRTUALENV}: invalid value for '${_PYTHON_PREFIX}_FIND_VIRTUALENV'. 'FIRST', 'ONLY' or 'STANDARD' expected. 'FIRST' will be used instead.") - set (_${_PYTHON_PREFIX}_FIND_VIRTUALENV "FIRST") - else() - set (_${_PYTHON_PREFIX}_FIND_VIRTUALENV ${${_PYTHON_PREFIX}_FIND_VIRTUALENV}) - endif() - else() - set (_${_PYTHON_PREFIX}_FIND_VIRTUALENV FIRST) - endif() -else() - set (_${_PYTHON_PREFIX}_FIND_VIRTUALENV STANDARD) -endif() - - -# Python naming handling -if (DEFINED ${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES) - if (NOT ${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES MATCHES "^(FIRST|LAST|NEVER)$") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${_${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES}: invalid value for '${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES'. 'FIRST', 'LAST' or 'NEVER' expected. 'LAST' will be used instead.") - set (_${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES LAST) - else() - set (_${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES ${${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES}) - endif() -else() - set (_${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES LAST) -endif() - - -# Compute search signature -# This signature will be used to check validity of cached variables on new search -set (_${_PYTHON_PREFIX}_SIGNATURE "${${_PYTHON_PREFIX}_ROOT_DIR}:${_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS}:${_${_PYTHON_PREFIX}_FIND_STRATEGY}:${${_PYTHON_PREFIX}_FIND_VIRTUALENV}${_${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES}") -if (NOT WIN32) - string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${${_PYTHON_PREFIX}_USE_STATIC_LIBS}:") -endif() -if (CMAKE_HOST_APPLE) - string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${_${_PYTHON_PREFIX}_FIND_FRAMEWORK}") -endif() -if (CMAKE_HOST_WIN32) - string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${_${_PYTHON_PREFIX}_FIND_REGISTRY}") -endif() - -function (_PYTHON_CHECK_DEVELOPMENT_SIGNATURE module) - if ("Development.${module}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - string (TOUPPER "${module}" id) - set (signature "${_${_PYTHON_PREFIX}_SIGNATURE}:") - if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) - list (APPEND signature "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:") - endif() - if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) - list (APPEND signature "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}:") - endif() - if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) - list (APPEND signature "${_${_PYTHON_PREFIX}_INCLUDE_DIR}:") - endif() - string (MD5 signature "${signature}") - if (signature STREQUAL _${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE) - if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - _python_validate_library (VERSION ${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS) - elseif (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) - _python_validate_library (IN_RANGE CHECK_EXISTS) - elseif (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION) - _python_validate_library (VERSION ${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS) - else() - _python_validate_library (CHECK_EXISTS) - endif() - endif() - if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) - _python_validate_sabi_library (CHECK_EXISTS) - endif() - if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - _python_validate_include_dir (VERSION ${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS) - elseif (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) - _python_validate_include_dir (IN_RANGE CHECK_EXISTS) - elseif (${_PYTHON_PREFIX}_FIND_VERSION) - _python_validate_include_dir (VERSION ${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS) - else() - _python_validate_include_dir (CHECK_EXISTS) - endif() - endif() - else() - if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) - unset (_${_PYTHON_PREFIX}_LIBRARY_RELEASE CACHE) - unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG CACHE) - endif() - if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) - unset (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE CACHE) - unset (_${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG CACHE) - endif() - if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) - unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE) - endif() - endif() - if (("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS - AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE) - OR ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS - AND NOT _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) - OR ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS - AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)) - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - unset (_${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE CACHE) - endif() - endif() -endfunction() - -function (_PYTHON_COMPUTE_DEVELOPMENT_SIGNATURE module) - string (TOUPPER "${module}" id) - if (${_PYTHON_PREFIX}_Development.${module}_FOUND) - set (signature "${_${_PYTHON_PREFIX}_SIGNATURE}:") - if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) - list (APPEND signature "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:") - endif() - if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) - list (APPEND signature "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}:") - endif() - if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) - list (APPEND signature "${_${_PYTHON_PREFIX}_INCLUDE_DIR}:") - endif() - string (MD5 signature "${signature}") - set (_${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE "${signature}" CACHE INTERNAL "") - else() - unset (_${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE CACHE) - endif() -endfunction() - -unset (_${_PYTHON_PREFIX}_REQUIRED_VARS) -unset (_${_PYTHON_PREFIX}_CACHED_VARS) -unset (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE) -set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE CACHE INTERNAL "Interpreter reason failure") -unset (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE) -set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE CACHE INTERNAL "Compiler reason failure") -foreach (artifact IN LISTS _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) - unset (_${_PYTHON_PREFIX}_Development_${artifact}_REASON_FAILURE) - set (_${_PYTHON_PREFIX}_Development_${artifact}_REASON_FAILURE CACHE INTERNAL "Development ${artifact} reason failure") -endforeach() -unset (_${_PYTHON_PREFIX}_Development_REASON_FAILURE) -set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE CACHE INTERNAL "Development reason failure") -unset (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE) -set (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE CACHE INTERNAL "NumPy reason failure") - - -# preamble -## For IronPython on platforms other than Windows, search for the .Net interpreter -if ("IronPython" IN_LIST _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS - AND NOT WIN32) - find_program (${_PYTHON_PREFIX}_DOTNET_LAUNCHER - NAMES "mono") -endif() - - -# first step, search for the interpreter -if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_EXECUTABLE - _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES) - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) - endif() - - if (DEFINED ${_PYTHON_PREFIX}_EXECUTABLE - AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_EXECUTABLE}") - if (NOT ${_PYTHON_PREFIX}_EXECUTABLE STREQUAL _${_PYTHON_PREFIX}_EXECUTABLE) - # invalidate cache properties - unset (_${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES CACHE) - endif() - set (_${_PYTHON_PREFIX}_EXECUTABLE "${${_PYTHON_PREFIX}_EXECUTABLE}" CACHE INTERNAL "") - elseif (DEFINED _${_PYTHON_PREFIX}_EXECUTABLE) - # compute interpreter signature and check validity of definition - string (MD5 __${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_EXECUTABLE}") - if (__${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE) - # check version validity - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - _python_validate_interpreter (VERSION ${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS) - elseif (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) - _python_validate_interpreter (IN_RANGE CHECK_EXISTS) - elseif (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION) - _python_validate_interpreter (VERSION ${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS) - else() - _python_validate_interpreter (CHECK_EXISTS) - endif() - else() - unset (_${_PYTHON_PREFIX}_EXECUTABLE CACHE) - endif() - if (NOT _${_PYTHON_PREFIX}_EXECUTABLE) - unset (_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE CACHE) - unset (_${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES CACHE) - endif() - endif() - - if (NOT _${_PYTHON_PREFIX}_EXECUTABLE) - set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION") - # build all executable names - _python_get_names (_${_PYTHON_PREFIX}_NAMES VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} POSIX INTERPRETER) - _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} INTERPRETER) - - # Framework Paths - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS}) - # Registry Paths - _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS}) - - set (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT}) - if (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) - list (APPEND _${_PYTHON_PREFIX}_VALIDATE_OPTIONS IN_RANGE) - elseif (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION) - list (APPEND _${_PYTHON_PREFIX}_VALIDATE_OPTIONS VERSION ${${_PYTHON_PREFIX}_FIND_VERSION}) - endif() - - while (TRUE) - # Virtual environments handling - if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH - VALIDATOR _python_validate_find_interpreter) - if (_${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "ONLY") - break() - endif() - endif() - - # Apple frameworks handling - if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH - VALIDATOR _python_validate_find_interpreter) - if (_${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - endif() - # Windows registry - if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - ${_${_PYTHON_PREFIX}_REGISTRY_VIEW} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH - VALIDATOR _python_validate_find_interpreter) - if (_${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - endif() - - # try using HINTS - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH - VALIDATOR _python_validate_find_interpreter) - if (_${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - # try using standard paths - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - VALIDATOR _python_validate_find_interpreter) - if (_${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - - # Apple frameworks handling - if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_DEFAULT_PATH - VALIDATOR _python_validate_find_interpreter) - if (_${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - endif() - # Windows registry - if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - ${_${_PYTHON_PREFIX}_REGISTRY_VIEW} - NO_DEFAULT_PATH - VALIDATOR _python_validate_find_interpreter) - if (_${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - endif() - - break() - endwhile() - else() - # look-up for various versions and locations - set (_${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS EXACT) - if (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) - list (APPEND _${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS IN_RANGE) - endif() - - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - _python_get_names (_${_PYTHON_PREFIX}_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX INTERPRETER) - _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} INTERPRETER) - - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION}) - _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION}) - set (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS}) - - # Virtual environments handling - if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH - VALIDATOR _python_validate_find_interpreter) - if (_${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "ONLY") - continue() - endif() - endif() - - # Apple frameworks handling - if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH - VALIDATOR _python_validate_find_interpreter) - endif() - - # Windows registry - if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - ${_${_PYTHON_PREFIX}_REGISTRY_VIEW} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH - VALIDATOR _python_validate_find_interpreter) - endif() - - if (_${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - - # try using HINTS - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH - VALIDATOR _python_validate_find_interpreter) - if (_${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - - # try using standard paths. - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - VALIDATOR _python_validate_find_interpreter) - if (_${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - - # Apple frameworks handling - if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_DEFAULT_PATH - VALIDATOR _python_validate_find_interpreter) - endif() - - # Windows registry - if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - ${_${_PYTHON_PREFIX}_REGISTRY_VIEW} - NO_DEFAULT_PATH - VALIDATOR _python_validate_find_interpreter) - endif() - - if (_${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - endforeach() - - if (NOT _${_PYTHON_PREFIX}_EXECUTABLE AND - NOT _${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "ONLY") - # No specific version found. Retry with generic names and standard paths. - _python_get_names (_${_PYTHON_PREFIX}_NAMES POSIX INTERPRETER) - unset (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS) - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - VALIDATOR _python_validate_find_interpreter) - endif() - endif() - endif() - - set (${_PYTHON_PREFIX}_EXECUTABLE "${_${_PYTHON_PREFIX}_EXECUTABLE}") - _python_get_launcher (_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER INTERPRETER) - - # retrieve exact version of executable found - if (_${_PYTHON_PREFIX}_EXECUTABLE) - execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_VERSION - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - set (_${_PYTHON_PREFIX}_EXECUTABLE_USABLE TRUE) - else() - # Interpreter is not usable - set (_${_PYTHON_PREFIX}_EXECUTABLE_USABLE FALSE) - unset (${_PYTHON_PREFIX}_VERSION) - set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Cannot run the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") - endif() - endif() - - if (_${_PYTHON_PREFIX}_EXECUTABLE AND _${_PYTHON_PREFIX}_EXECUTABLE_USABLE) - list (LENGTH _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES _properties_length) - if (NOT _properties_length EQUAL "12") - # cache variable comes from some older Python module version: not usable - unset (_${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES CACHE) - endif() - unset (_properties_length) - - if (_${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES) - set (${_PYTHON_PREFIX}_Interpreter_FOUND TRUE) - - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 0 ${_PYTHON_PREFIX}_INTERPRETER_ID) - - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 1 ${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 2 ${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 3 ${_PYTHON_PREFIX}_VERSION_PATCH) - - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 4 _${_PYTHON_PREFIX}_ARCH) - - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 5 _${_PYTHON_PREFIX}_ABIFLAGS) - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 6 ${_PYTHON_PREFIX}_SOABI) - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 7 ${_PYTHON_PREFIX}_SOSABI) - - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 8 ${_PYTHON_PREFIX}_STDLIB) - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 9 ${_PYTHON_PREFIX}_STDARCH) - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 10 ${_PYTHON_PREFIX}_SITELIB) - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 11 ${_PYTHON_PREFIX}_SITEARCH) - else() - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 ${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 ${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 ${_PYTHON_PREFIX}_VERSION_PATCH) - - if (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Interpreter_FOUND TRUE) - - # Use interpreter version and ABI for future searches to ensure consistency - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write(sys.abiflags)" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_ABIFLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - # assunme ABI is not supported - set (_${_PYTHON_PREFIX}_ABIFLAGS "") - endif() - endif() - - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - unset (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE CACHE) - - # compute and save interpreter signature - string (MD5 __${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_EXECUTABLE}") - set (_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE "${__${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}" CACHE INTERNAL "") - - if (NOT CMAKE_SIZEOF_VOID_P) - # determine interpreter architecture - execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write(str(sys.maxsize > 2**32))" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_IS64BIT - ERROR_VARIABLE ${_PYTHON_PREFIX}_IS64BIT) - if (NOT _${_PYTHON_PREFIX}_RESULT) - if (${_PYTHON_PREFIX}_IS64BIT) - set (_${_PYTHON_PREFIX}_ARCH 64) - else() - set (_${_PYTHON_PREFIX}_ARCH 32) - endif() - endif() - - if (WIN32) - # check if architecture is Intel or ARM - execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; import sysconfig; sys.stdout.write(sysconfig.get_platform())" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PLATFORM - ERROR_VARIABLE ${_PYTHON_PREFIX}_PLATFORM) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string(TOUPPER "${_${_PYTHON_PREFIX}_PLATFORM}" _${_PYTHON_PREFIX}_PLATFORM) - if (_${_PYTHON_PREFIX}_PLATFORM MATCHES "ARM") - if (${_PYTHON_PREFIX}_IS64BIT) - set (_${_PYTHON_PREFIX}_ARCH ARM64) - else() - set (_${_PYTHON_PREFIX}_ARCH ARM) - endif() - endif() - endif() - endif() - endif() - - # retrieve interpreter identity - execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -V - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID - ERROR_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID) - if (NOT _${_PYTHON_PREFIX}_RESULT) - if (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Anaconda") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "Anaconda") - elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Enthought") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "Canopy") - elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "PyPy ([0-9.]+)") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "PyPy") - set (${_PYTHON_PREFIX}_PyPy_VERSION "${CMAKE_MATCH_1}") - else() - string (REGEX REPLACE "^([^ ]+).*" "\\1" ${_PYTHON_PREFIX}_INTERPRETER_ID "${${_PYTHON_PREFIX}_INTERPRETER_ID}") - if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "Python") - # try to get a more precise ID - execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write(sys.copyright)" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_COPYRIGHT - ERROR_QUIET) - if (${_PYTHON_PREFIX}_COPYRIGHT MATCHES "ActiveState") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "ActivePython") - endif() - endif() - endif() - else() - set (${_PYTHON_PREFIX}_INTERPRETER_ID Python) - endif() - - # retrieve various package installation directories - execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys\nif sys.version_info >= (3,10):\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_path('stdlib'),sysconfig.get_path('platstdlib'),sysconfig.get_path('purelib'),sysconfig.get_path('platlib')]))\nelse:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS - ERROR_QUIET) - if (NOT _${_PYTHON_PREFIX}_RESULT) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 0 ${_PYTHON_PREFIX}_STDLIB) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 1 ${_PYTHON_PREFIX}_STDARCH) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 2 ${_PYTHON_PREFIX}_SITELIB) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 3 ${_PYTHON_PREFIX}_SITEARCH) - else() - unset (${_PYTHON_PREFIX}_STDLIB) - unset (${_PYTHON_PREFIX}_STDARCH) - unset (${_PYTHON_PREFIX}_SITELIB) - unset (${_PYTHON_PREFIX}_SITEARCH) - endif() - - _python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI) - _python_get_config_var (${_PYTHON_PREFIX}_SOSABI SOSABI) - - # store properties in the cache to speed-up future searches - set (_${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES - "${${_PYTHON_PREFIX}_INTERPRETER_ID};${${_PYTHON_PREFIX}_VERSION_MAJOR};${${_PYTHON_PREFIX}_VERSION_MINOR};${${_PYTHON_PREFIX}_VERSION_PATCH};${_${_PYTHON_PREFIX}_ARCH};${_${_PYTHON_PREFIX}_ABIFLAGS};${${_PYTHON_PREFIX}_SOABI};${${_PYTHON_PREFIX}_SOSABI};${${_PYTHON_PREFIX}_STDLIB};${${_PYTHON_PREFIX}_STDARCH};${${_PYTHON_PREFIX}_SITELIB};${${_PYTHON_PREFIX}_SITEARCH}" CACHE INTERNAL "${_PYTHON_PREFIX} Properties") - else() - unset (_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE CACHE) - unset (${_PYTHON_PREFIX}_INTERPRETER_ID) - endif() - endif() - endif() - - if (${_PYTHON_PREFIX}_ARTIFACTS_INTERACTIVE) - set (${_PYTHON_PREFIX}_EXECUTABLE "${_${_PYTHON_PREFIX}_EXECUTABLE}" CACHE FILEPATH "${_PYTHON_PREFIX} Interpreter") - endif() - - _python_mark_as_internal (_${_PYTHON_PREFIX}_EXECUTABLE - _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES - _${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE) -endif() - - -# second step, search for compiler (IronPython) -if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_COMPILER) - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Compiler) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_COMPILER) - endif() - - if (NOT "IronPython" IN_LIST _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS) - unset (_${_PYTHON_PREFIX}_COMPILER CACHE) - unset (_${_PYTHON_PREFIX}_COMPILER_SIGNATURE CACHE) - elseif (DEFINED ${_PYTHON_PREFIX}_COMPILER - AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_COMPILER}") - set (_${_PYTHON_PREFIX}_COMPILER "${${_PYTHON_PREFIX}_COMPILER}" CACHE INTERNAL "") - elseif (DEFINED _${_PYTHON_PREFIX}_COMPILER) - # compute compiler signature and check validity of definition - string (MD5 __${_PYTHON_PREFIX}_COMPILER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_COMPILER}") - if (__${_PYTHON_PREFIX}_COMPILER_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_COMPILER_SIGNATURE) - # check version validity - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - _python_validate_compiler (VERSION ${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS) - elseif (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) - _python_validate_compiler (IN_RANGE CHECK_EXISTS) - elseif (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION) - _python_validate_compiler (VERSION ${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS) - else() - _python_validate_compiler (CHECK_EXISTS) - endif() - else() - unset (_${_PYTHON_PREFIX}_COMPILER CACHE) - unset (_${_PYTHON_PREFIX}_COMPILER_SIGNATURE CACHE) - endif() - endif() - - if ("IronPython" IN_LIST _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS - AND NOT _${_PYTHON_PREFIX}_COMPILER) - # IronPython specific artifacts - # If IronPython interpreter is found, use its path - unset (_${_PYTHON_PREFIX}_IRON_ROOT) - if (${_PYTHON_PREFIX}_Interpreter_FOUND AND ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") - get_filename_component (_${_PYTHON_PREFIX}_IRON_ROOT "${${_PYTHON_PREFIX}_EXECUTABLE}" DIRECTORY) - endif() - - if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION") - _python_get_names (_${_PYTHON_PREFIX}_COMPILER_NAMES - IMPLEMENTATIONS IronPython - VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} - COMPILER) - - _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES - IMPLEMENTATIONS IronPython - VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} - COMPILER) - - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS - IMPLEMENTATIONS IronPython - VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS}) - _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS - IMPLEMENTATIONS IronPython - VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS}) - - set (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT}) - if (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) - list (APPEND _${_PYTHON_PREFIX}_VALIDATE_OPTIONS IN_RANGE) - elseif (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION) - list (APPEND _${_PYTHON_PREFIX}_VALIDATE_OPTIONS VERSION ${${_PYTHON_PREFIX}_FIND_VERSION}) - endif() - - while (TRUE) - # Apple frameworks handling - if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_program (_${_PYTHON_PREFIX}_COMPILER - NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH - VALIDATOR _python_validate_find_compiler) - if (_${_PYTHON_PREFIX}_COMPILER) - break() - endif() - endif() - # Windows registry - if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (_${_PYTHON_PREFIX}_COMPILER - NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - ${_${_PYTHON_PREFIX}_REGISTRY_VIEW} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH - VALIDATOR _python_validate_find_compiler) - if (_${_PYTHON_PREFIX}_COMPILER) - break() - endif() - endif() - - # try using HINTS - find_program (_${_PYTHON_PREFIX}_COMPILER - NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH - VALIDATOR _python_validate_find_compiler) - if (_${_PYTHON_PREFIX}_COMPILER) - break() - endif() - - # try using standard paths - find_program (_${_PYTHON_PREFIX}_COMPILER - NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES} - NAMES_PER_DIR - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - VALIDATOR _python_validate_find_compiler) - if (_${_PYTHON_PREFIX}_COMPILER) - break() - endif() - - # Apple frameworks handling - if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_COMPILER - NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_DEFAULT_PATH - VALIDATOR _python_validate_find_compiler) - if (_${_PYTHON_PREFIX}_COMPILER) - break() - endif() - endif() - - # Windows registry - if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_COMPILER - NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - ${_${_PYTHON_PREFIX}_REGISTRY_VIEW} - NO_DEFAULT_PATH - VALIDATOR _python_validate_find_compiler) - if (_${_PYTHON_PREFIX}_COMPILER) - break() - endif() - endif() - - break() - endwhile() - else() - # try using root dir and registry - set (_${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS EXACT) - if (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) - list (APPEND _${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS IN_RANGE) - endif() - - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - _python_get_names (_${_PYTHON_PREFIX}_COMPILER_NAMES - IMPLEMENTATIONS IronPython - VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} - COMPILER) - - _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES - IMPLEMENTATIONS IronPython - VERSION ${_${_PYTHON_PREFIX}_FIND_VERSION} - COMPILER) - - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS - IMPLEMENTATIONS IronPython - VERSION ${_${_PYTHON_PREFIX}_VERSION}) - _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS - IMPLEMENTATIONS IronPython - VERSION ${_${_PYTHON_PREFIX}_VERSION}) - - set (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS}) - - # Apple frameworks handling - if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_program (_${_PYTHON_PREFIX}_COMPILER - NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH - VALIDATOR _python_validate_find_compiler) - if (_${_PYTHON_PREFIX}_COMPILER) - break() - endif() - endif() - # Windows registry - if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (_${_PYTHON_PREFIX}_COMPILER - NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - ${_${_PYTHON_PREFIX}_REGISTRY_VIEW} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH - VALIDATOR _python_validate_find_compiler) - if (_${_PYTHON_PREFIX}_COMPILER) - break() - endif() - endif() - - # try using HINTS - find_program (_${_PYTHON_PREFIX}_COMPILER - NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH - VALIDATOR _python_validate_find_compiler) - if (_${_PYTHON_PREFIX}_COMPILER) - break() - endif() - - # Apple frameworks handling - if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_COMPILER - NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_DEFAULT_PATH - VALIDATOR _python_validate_find_compiler) - if (_${_PYTHON_PREFIX}_COMPILER) - break() - endif() - endif() - # Windows registry - if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_COMPILER - NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - ${_${_PYTHON_PREFIX}_REGISTRY_VIEW} - NO_DEFAULT_PATH - VALIDATOR _python_validate_find_compiler) - if (_${_PYTHON_PREFIX}_COMPILER) - break() - endif() - endif() - endforeach() - - # no specific version found, re-try in standard paths - _python_get_names (_${_PYTHON_PREFIX}_COMPILER_NAMES - IMPLEMENTATIONS IronPython - VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} - COMPILER) - _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES - IMPLEMENTATIONS IronPython - VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} - COMPILER) - unset (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS) - find_program (_${_PYTHON_PREFIX}_COMPILER - NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - VALIDATOR _python_validate_find_compiler) - endif() - endif() - - set (${_PYTHON_PREFIX}_COMPILER "${_${_PYTHON_PREFIX}_COMPILER}") - - if (_${_PYTHON_PREFIX}_COMPILER) - # retrieve python environment version from compiler - _python_get_launcher (_${_PYTHON_PREFIX}_COMPILER_LAUNCHER COMPILER) - set (_${_PYTHON_PREFIX}_VERSION_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") - file (WRITE "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]])); sys.stdout.flush()\n") - execute_process (COMMAND ${_${_PYTHON_PREFIX}_COMPILER_LAUNCHER} "${_${_PYTHON_PREFIX}_COMPILER}" - ${_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_ARCH_FLAGS} - /target:exe /embed "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" - WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}" - OUTPUT_QUIET - ERROR_QUIET) - get_filename_component (_${_PYTHON_PREFIX}_IR_DIR "${_${_PYTHON_PREFIX}_COMPILER}" DIRECTORY) - execute_process (COMMAND "${CMAKE_COMMAND}" -E env "MONO_PATH=${_${_PYTHON_PREFIX}_IR_DIR}" - ${${_PYTHON_PREFIX}_DOTNET_LAUNCHER} "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.exe" - WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_VERSION - ERROR_QUIET) - if (NOT _${_PYTHON_PREFIX}_RESULT) - set (_${_PYTHON_PREFIX}_COMPILER_USABLE TRUE) - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH) - - if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND) - # set public version information - set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION}) - set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR}) - set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH}) - endif() - else() - # compiler not usable - set (_${_PYTHON_PREFIX}_COMPILER_USABLE FALSE) - set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Cannot run the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"") - endif() - file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") - endif() - - if (_${_PYTHON_PREFIX}_COMPILER AND _${_PYTHON_PREFIX}_COMPILER_USABLE) - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - # Compiler must be compatible with interpreter - if ("${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}" VERSION_EQUAL "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}") - set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) - endif() - elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) - # Use compiler version for future searches to ensure consistency - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - endif() - endif() - - if (${_PYTHON_PREFIX}_Compiler_FOUND) - unset (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE CACHE) - - # compute and save compiler signature - string (MD5 __${_PYTHON_PREFIX}_COMPILER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_COMPILER}") - set (_${_PYTHON_PREFIX}_COMPILER_SIGNATURE "${__${_PYTHON_PREFIX}_COMPILER_SIGNATURE}" CACHE INTERNAL "") - - set (${_PYTHON_PREFIX}_COMPILER_ID IronPython) - else() - unset (_${_PYTHON_PREFIX}_COMPILER_SIGNATURE CACHE) - unset (${_PYTHON_PREFIX}_COMPILER_ID) - endif() - - if (${_PYTHON_PREFIX}_ARTIFACTS_INTERACTIVE) - set (${_PYTHON_PREFIX}_COMPILER "${_${_PYTHON_PREFIX}_COMPILER}" CACHE FILEPATH "${_PYTHON_PREFIX} Compiler") - endif() - - _python_mark_as_internal (_${_PYTHON_PREFIX}_COMPILER - _${_PYTHON_PREFIX}_COMPILER_SIGNATURE) -endif() - -# third step, search for the development artifacts -if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Module) - if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES) - endif() - if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_INCLUDE_DIRS) - endif() -endif() -if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.SABIModule) - if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_SABI_LIBRARIES) - endif() - if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_INCLUDE_DIRS) - endif() -endif() -if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Embed) - if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES) - endif() - if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_INCLUDE_DIRS) - endif() -endif() -list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_REQUIRED_VARS) -## Development environment is not compatible with IronPython interpreter -if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - OR "Development.SABIModule" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - AND ((${_PYTHON_PREFIX}_Interpreter_FOUND - AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") - OR NOT ${_PYTHON_PREFIX}_Interpreter_FOUND)) - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - # reduce possible implementations to the interpreter one - if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "PyPy") - set (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS "PyPy") - else() - set (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS "CPython") - endif() - else() - list (REMOVE_ITEM _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS "IronPython") - endif() - if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_LIBRARY_RELEASE - _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - _${_PYTHON_PREFIX}_LIBRARY_DEBUG - _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - endif() - if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE - _${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_RELEASE - _${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG - _${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DEBUG) - endif() - if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_INCLUDE_DIR) - endif() - - _python_check_development_signature (Module) - _python_check_development_signature (SABIModule) - _python_check_development_signature (Embed) - - if (DEFINED ${_PYTHON_PREFIX}_LIBRARY - AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_LIBRARY}") - set (_${_PYTHON_PREFIX}_LIBRARY_RELEASE "${${_PYTHON_PREFIX}_LIBRARY}" CACHE INTERNAL "") - unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG CACHE) - unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE) - endif() - if (DEFINED ${_PYTHON_PREFIX}_SABI_LIBRARY - AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_SABI_LIBRARY}") - set (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE "${${_PYTHON_PREFIX}_SABI_LIBRARY}" CACHE INTERNAL "") - unset (_${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG CACHE) - unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE) - endif() - if (DEFINED ${_PYTHON_PREFIX}_INCLUDE_DIR - AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_INCLUDE_DIR}") - set (_${_PYTHON_PREFIX}_INCLUDE_DIR "${${_PYTHON_PREFIX}_INCLUDE_DIR}" CACHE INTERNAL "") - endif() - - # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES) - if (DEFINED ${_PYTHON_PREFIX}_USE_STATIC_LIBS AND NOT WIN32) - set(_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - if(${_PYTHON_PREFIX}_USE_STATIC_LIBS) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) - else() - list (REMOVE_ITEM CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) - endif() - endif() - - if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE OR NOT _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE - OR NOT _${_PYTHON_PREFIX}_INCLUDE_DIR) - # if python interpreter is found, use it to look-up for artifacts - # to ensure consistency between interpreter and development environments. - # If not, try to locate a compatible config tool - if ((NOT ${_PYTHON_PREFIX}_Interpreter_FOUND OR CMAKE_CROSSCOMPILING) - AND "CPython" IN_LIST _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS) - set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS) - if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") - set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX) - endif() - - if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION") - _python_get_names (_${_PYTHON_PREFIX}_CONFIG_NAMES VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} POSIX CONFIG) - # Framework Paths - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS}) - - # Apple frameworks handling - if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_program (_${_PYTHON_PREFIX}_CONFIG - NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - find_program (_${_PYTHON_PREFIX}_CONFIG - NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - PATH_SUFFIXES bin) - - # Apple frameworks handling - if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_CONFIG - NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_DEFAULT_PATH) - endif() - - _python_get_launcher (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER CONFIG "${_${_PYTHON_PREFIX}_CONFIG}") - - if (_${_PYTHON_PREFIX}_CONFIG) - execute_process (COMMAND ${_${_PYTHON_PREFIX}_CONFIG_LAUNCHER} --prefix - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE __${_PYTHON_PREFIX}_HELP - ERROR_VARIABLE __${_PYTHON_PREFIX}_HELP - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - # assume config tool is not usable - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - unset (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER) - endif() - endif() - - if (_${_PYTHON_PREFIX}_CONFIG) - execute_process (COMMAND ${_${_PYTHON_PREFIX}_CONFIG_LAUNCHER} --abiflags - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE __${_PYTHON_PREFIX}_ABIFLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - # assume ABI is not supported - set (__${_PYTHON_PREFIX}_ABIFLAGS "") - endif() - if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT __${_PYTHON_PREFIX}_ABIFLAGS IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS) - # Wrong ABI - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - unset (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER) - endif() - endif() - - if (_${_PYTHON_PREFIX}_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE) - # check that config tool match library architecture - execute_process (COMMAND ${_${_PYTHON_PREFIX}_CONFIG_LAUNCHER} --configdir - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_CONFIGDIR - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - unset (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER) - else() - string(FIND "${_${_PYTHON_PREFIX}_CONFIGDIR}" "${CMAKE_LIBRARY_ARCHITECTURE}" _${_PYTHON_PREFIX}_RESULT) - if (_${_PYTHON_PREFIX}_RESULT EQUAL -1) - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - unset (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER) - endif() - endif() - endif() - else() - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - # try to use pythonX.Y-config tool - _python_get_names (_${_PYTHON_PREFIX}_CONFIG_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX CONFIG) - - # Framework Paths - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION}) - - # Apple frameworks handling - if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_program (_${_PYTHON_PREFIX}_CONFIG - NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - find_program (_${_PYTHON_PREFIX}_CONFIG - NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - PATH_SUFFIXES bin) - - # Apple frameworks handling - if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_CONFIG - NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_DEFAULT_PATH) - endif() - - unset (_${_PYTHON_PREFIX}_CONFIG_NAMES) - - _python_get_launcher (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER CONFIG "${_${_PYTHON_PREFIX}_CONFIG}") - - if (_${_PYTHON_PREFIX}_CONFIG) - execute_process (COMMAND ${_${_PYTHON_PREFIX}_CONFIG_LAUNCHER} --prefix - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE __${_PYTHON_PREFIX}_HELP - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - # assume config tool is not usable - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - unset (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER) - endif() - endif() - - if (NOT _${_PYTHON_PREFIX}_CONFIG) - continue() - endif() - - execute_process (COMMAND ${_${_PYTHON_PREFIX}_CONFIG_LAUNCHER} --abiflags - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE __${_PYTHON_PREFIX}_ABIFLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - # assume ABI is not supported - set (__${_PYTHON_PREFIX}_ABIFLAGS "") - endif() - if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT __${_PYTHON_PREFIX}_ABIFLAGS IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS) - # Wrong ABI - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - unset (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER) - continue() - endif() - - if (_${_PYTHON_PREFIX}_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE) - # check that config tool match library architecture - execute_process (COMMAND ${_${_PYTHON_PREFIX}_CONFIG_LAUNCHER} --configdir - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_CONFIGDIR - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - unset (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER) - continue() - endif() - string (FIND "${_${_PYTHON_PREFIX}_CONFIGDIR}" "${CMAKE_LIBRARY_ARCHITECTURE}" _${_PYTHON_PREFIX}_RESULT) - if (_${_PYTHON_PREFIX}_RESULT EQUAL -1) - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - unset (_${_PYTHON_PREFIX}_CONFIG_LAUNCHER) - continue() - endif() - endif() - - if (_${_PYTHON_PREFIX}_CONFIG) - break() - endif() - endforeach() - endif() - endif() - endif() - - if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) - if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE) - if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG) - # retrieve root install directory - _python_get_config_var (_${_PYTHON_PREFIX}_PREFIX PREFIX) - - # enforce current ABI - _python_get_config_var (_${_PYTHON_PREFIX}_ABIFLAGS ABIFLAGS) - - set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}") - - # retrieve library - ## compute some paths and artifact names - if (_${_PYTHON_PREFIX}_CONFIG) - string (REGEX REPLACE "^.+python([0-9.]+)[a-z]*-config" "\\1" _${_PYTHON_PREFIX}_VERSION "${_${_PYTHON_PREFIX}_CONFIG}") - else() - set (_${_PYTHON_PREFIX}_VERSION "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}") - endif() - _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} LIBRARY) - _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 POSIX LIBRARY) - - _python_get_config_var (_${_PYTHON_PREFIX}_CONFIGDIR CONFIGDIR) - list (APPEND _${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_CONFIGDIR}") - - list (APPEND _${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # Rely on HINTS and standard paths if interpreter or config tool failed to locate artifacts - if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE) - set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS) - if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") - set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX) - endif() - - if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION") - # library names - _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} WIN32 POSIX LIBRARY) - _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} WIN32 DEBUG) - # Paths suffixes - _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} LIBRARY) - - # Framework Paths - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_FIND_VERSIONS}) - # Registry Paths - _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} ) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # search in HINTS locations - find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) - endif() - - # search in all default paths - find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}) - else() - foreach (_${_PYTHON_PREFIX}_LIB_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 POSIX LIBRARY) - _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 DEBUG) - - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION}) - _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION}) - - _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} LIBRARY) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # search in HINTS locations - find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) - endif() - - # search in all default paths - find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}) - - if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE) - break() - endif() - endforeach() - endif() - endif() - endif() - - # finalize library version information - _python_get_version (LIBRARY PREFIX _${_PYTHON_PREFIX}_) - if (_${_PYTHON_PREFIX}_VERSION EQUAL "${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}") - # not able to extract full version from library name - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - # update from interpreter - set (_${_PYTHON_PREFIX}_VERSION ${${_PYTHON_PREFIX}_VERSION}) - set (_${_PYTHON_PREFIX}_VERSION_MAJOR ${${_PYTHON_PREFIX}_VERSION_MAJOR}) - set (_${_PYTHON_PREFIX}_VERSION_MINOR ${${_PYTHON_PREFIX}_VERSION_MINOR}) - set (_${_PYTHON_PREFIX}_VERSION_PATCH ${${_PYTHON_PREFIX}_VERSION_PATCH}) - endif() - endif() - - set (${_PYTHON_PREFIX}_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}") - - if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND NOT EXISTS "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}") - set_property (CACHE _${_PYTHON_PREFIX}_Development_LIBRARY_REASON_FAILURE PROPERTY VALUE "Cannot find the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"") - set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND") - else() - unset (_${_PYTHON_PREFIX}_Development_LIBRARY_REASON_FAILURE CACHE) - endif() - - set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - if (WIN32 AND _${_PYTHON_PREFIX}_LIBRARY_RELEASE) - # search for debug library - # use release library location as a hint - _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 DEBUG) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - find_library (_${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG} - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - NO_DEFAULT_PATH) - # second try including CMAKE variables to catch-up non conventional layouts - find_library (_${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG} - NAMES_PER_DIR - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # retrieve runtime libraries - if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE) - _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 POSIX LIBRARY) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY) - _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" - "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - endif() - if (_${_PYTHON_PREFIX}_LIBRARY_DEBUG) - _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 DEBUG) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY) - get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY) - _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG} - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" - "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - endif() - endif() - - if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) - if (NOT _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) - ## compute artifact names - _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} WIN32 POSIX LIBRARY) - _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} WIN32 DEBUG) - - if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS - AND _${_PYTHON_PREFIX}_LIBRARY_RELEASE) - # SABI_LIBRARY_RELEASE search is based on LIBRARY_RELEASE - set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - - find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - NO_DEFAULT_PATH) - else() - if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG) - # retrieve root install directory - _python_get_config_var (_${_PYTHON_PREFIX}_PREFIX PREFIX) - - # enforce current ABI - _python_get_config_var (_${_PYTHON_PREFIX}_ABIFLAGS ABIFLAGS) - - set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}") - - # retrieve SABI library - ## compute some paths - if (_${_PYTHON_PREFIX}_CONFIG) - string (REGEX REPLACE "^.+python([0-9.]+)[a-z]*-config" "\\1" _${_PYTHON_PREFIX}_VERSION "${_${_PYTHON_PREFIX}_CONFIG}") - else() - set (_${_PYTHON_PREFIX}_VERSION "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}") - endif() - _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} LIBRARY) - - _python_get_config_var (_${_PYTHON_PREFIX}_CONFIGDIR CONFIGDIR) - list (APPEND _${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_CONFIGDIR}") - - list (APPEND _${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # Rely on HINTS and standard paths if interpreter or config tool failed to locate artifacts - if (NOT _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) - set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS) - if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") - set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX) - endif() - - if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION") - # Paths suffixes - _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} LIBRARY) - - # Framework Paths - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_FIND_VERSIONS}) - # Registry Paths - _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} ) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # search in HINTS locations - find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) - endif() - - # search in all default paths - find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}) - else() - foreach (_${_PYTHON_PREFIX}_LIB_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION}) - _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION}) - - _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} LIBRARY) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # search in HINTS locations - find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) - endif() - - # search in all default paths - find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}) - - if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE) - break() - endif() - endforeach() - endif() - endif() - endif() - endif() - - # finalize library version information - _python_get_version (SABI_LIBRARY PREFIX _${_PYTHON_PREFIX}_) - # ABI library does not have the full version information - if (${_PYTHON_PREFIX}_Interpreter_FOUND OR _${_PYTHON_PREFIX}_LIBRARY_RELEASE) - # update from interpreter or library - set (_${_PYTHON_PREFIX}_VERSION ${${_PYTHON_PREFIX}_VERSION}) - set (_${_PYTHON_PREFIX}_VERSION_MAJOR ${${_PYTHON_PREFIX}_VERSION_MAJOR}) - set (_${_PYTHON_PREFIX}_VERSION_MINOR ${${_PYTHON_PREFIX}_VERSION_MINOR}) - set (_${_PYTHON_PREFIX}_VERSION_PATCH ${${_PYTHON_PREFIX}_VERSION_PATCH}) - endif() - - set (${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}") - - if (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE AND NOT EXISTS "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}") - set_property (CACHE _${_PYTHON_PREFIX}_Development_SABI_LIBRARY_REASON_FAILURE PROPERTY VALUE "Cannot find the library \"${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}\"") - set_property (CACHE _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE-NOTFOUND") - else() - unset (_${_PYTHON_PREFIX}_Development_SABI_LIBRARY_REASON_FAILURE CACHE) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) - # search for debug library - get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}" DIRECTORY) - find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG} - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - NO_DEFAULT_PATH) - # second try including CMAKE variables to catch-up non conventional layouts - find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG} - NAMES_PER_DIR - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # retrieve runtime libraries - if (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}" DIRECTORY) - get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY) - _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" - "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - endif() - - if (_${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG}" DIRECTORY) - get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY) - _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DEBUG - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG} - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" - "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - endif() - endif() - - if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) - while (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR) - set (_${_PYTHON_PREFIX}_LIBRARY_REQUIRED FALSE) - set (_${_PYTHON_PREFIX}_SABI_LIBRARY_REQUIRED FALSE) - foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Module SABIModule Embed) - string (TOUPPER "${_${_PYTHON_PREFIX}_COMPONENT}" _${_PYTHON_PREFIX}_ID) - if ("Development.${_${_PYTHON_PREFIX}_COMPONENT}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND "LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${_${_PYTHON_PREFIX}_ID}_ARTIFACTS) - set (_${_PYTHON_PREFIX}_LIBRARY_REQUIRED TRUE) - endif() - if ("Development.${_${_PYTHON_PREFIX}_COMPONENT}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND "SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${_${_PYTHON_PREFIX}_ID}_ARTIFACTS) - set (_${_PYTHON_PREFIX}_SABI_LIBRARY_REQUIRED TRUE) - endif() - endforeach() - if ((_${_PYTHON_PREFIX}_LIBRARY_REQUIRED - AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE) - AND (_${_PYTHON_PREFIX}_SABI_LIBRARY_REQUIRED - AND NOT _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE)) - # Don't search for include dir if no library was founded - break() - endif() - - if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG) - _python_get_config_var (_${_PYTHON_PREFIX}_INCLUDE_DIRS INCLUDES) - - find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES ${_${_PYTHON_PREFIX}_INCLUDE_NAMES} - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # Rely on HINTS and standard paths if interpreter or config tool failed to locate artifacts - if (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR) - unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS) - if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") - set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX) - endif() - unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS) - - if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS - AND _${_PYTHON_PREFIX}_LIBRARY_RELEASE) - # Use the library's install prefix as a hint - if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - elseif (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - elseif (DEFINED CMAKE_LIBRARY_ARCHITECTURE AND ${_${_PYTHON_PREFIX}_LIBRARY_RELEASE} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - else() - # assume library is in a directory under root - get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY) - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}") - endif() - elseif ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS - AND _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) - # Use the library's install prefix as a hint - if (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - elseif (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - elseif (DEFINED CMAKE_LIBRARY_ARCHITECTURE AND ${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - else() - # assume library is in a directory under root - get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}" DIRECTORY) - get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY) - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}") - endif() - endif() - - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION}) - _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION}) - _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} INCLUDE) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES ${_${_PYTHON_PREFIX}_INCLUDE_NAMES} - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES ${_${_PYTHON_PREFIX}_INCLUDE_NAMES} - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) - endif() - - find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES ${_${_PYTHON_PREFIX}_INCLUDE_NAMES} - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # search header file in standard locations - find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES ${_${_PYTHON_PREFIX}_INCLUDE_NAMES}) - - break() - endwhile() - - set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}") - - if (_${_PYTHON_PREFIX}_INCLUDE_DIR AND NOT EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}") - set_property (CACHE _${_PYTHON_PREFIX}_Development_INCLUDE_DIR_REASON_FAILURE PROPERTY VALUE "Cannot find the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"") - set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") - else() - unset (_${_PYTHON_PREFIX}_Development_INCLUDE_DIR_REASON_FAILURE CACHE) - endif() - - if (_${_PYTHON_PREFIX}_INCLUDE_DIR) - # retrieve version from header file - _python_get_version (INCLUDE PREFIX _${_PYTHON_PREFIX}_INC_) - if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS - AND _${_PYTHON_PREFIX}_LIBRARY_RELEASE) - if ("${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" - VERSION_EQUAL _${_PYTHON_PREFIX}_VERSION) - # update versioning - set (_${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_INC_VERSION}) - set (_${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_INC_VERSION_PATCH}) - elseif (_${_PYTHON_PREFIX}_VERSION VERSION_EQUAL _${_PYTHON_PREFIX}_INC_VERSION_MAJOR) - # library specify only major version, use include file for full version information - set (_${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_INC_VERSION}) - set (_${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}) - set (_${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_INC_VERSION_PATCH}) - endif() - else() - set (_${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_INC_VERSION}) - set (_${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}) - set (_${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}) - set (_${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_INC_VERSION_PATCH}) - endif() - endif() - endif() - - if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT ${_PYTHON_PREFIX}_Compiler_FOUND) - # set public version information - set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION}) - set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR}) - set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH}) - endif() - - # define public variables - if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) - set (${_PYTHON_PREFIX}_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_LIBRARY_DEBUG}") - _python_select_library_configurations (${_PYTHON_PREFIX}) - - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") - - if (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") - elseif (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") - else() - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${_PYTHON_PREFIX}_RUNTIME_LIBRARY-NOTFOUND") - endif() - - _python_set_library_dirs (${_PYTHON_PREFIX}_LIBRARY_DIRS - _${_PYTHON_PREFIX}_LIBRARY_RELEASE - _${_PYTHON_PREFIX}_LIBRARY_DEBUG) - if (UNIX) - if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$") - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS ${${_PYTHON_PREFIX}_LIBRARY_DIRS}) - endif() - else() - _python_set_library_dirs (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS - _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - endif() - endif() - - if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) - set (${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG}") - _python_select_library_configurations (${_PYTHON_PREFIX}_SABI) - - set (${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_RELEASE}") - set (${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DEBUG}") - - if (_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_RELEASE) - set (${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY "${_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_RELEASE}") - elseif (_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DEBUG) - set (${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY "${_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DEBUG}") - else() - set (${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY "${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY-NOTFOUND") - endif() - - _python_set_library_dirs (${_PYTHON_PREFIX}_SABI_LIBRARY_DIRS - _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE - _${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG) - if (UNIX) - if (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$") - set (${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DIRS ${${_PYTHON_PREFIX}_LIBRARY_DIRS}) - endif() - else() - _python_set_library_dirs (${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DIRS - _${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_RELEASE - _${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DEBUG) - endif() - endif() - - if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE OR _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE OR _${_PYTHON_PREFIX}_INCLUDE_DIR) - if (${_PYTHON_PREFIX}_Interpreter_FOUND OR ${_PYTHON_PREFIX}_Compiler_FOUND) - # development environment must be compatible with interpreter/compiler - if ("${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}" VERSION_EQUAL "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}" - AND "${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}") - _python_set_development_module_found (Module) - _python_set_development_module_found (SABIModule) - _python_set_development_module_found (Embed) - endif() - elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR - AND "${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}") - _python_set_development_module_found (Module) - _python_set_development_module_found (SABIModule) - _python_set_development_module_found (Embed) - endif() - if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND - (NOT _${_PYTHON_PREFIX}_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS - OR NOT _${_PYTHON_PREFIX}_INC_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)) - set (${_PYTHON_PREFIX}_Development.Module_FOUND FALSE) - set (${_PYTHON_PREFIX}_Development.SABIModule_FOUND FALSE) - set (${_PYTHON_PREFIX}_Development.Embed_FOUND FALSE) - endif() - endif() - - if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Development.Module_FOUND - AND ${_PYTHON_PREFIX}_Development.Embed_FOUND) - set (${_PYTHON_PREFIX}_Development_FOUND TRUE) - endif() - - if ((${_PYTHON_PREFIX}_Development.Module_FOUND - OR ${_PYTHON_PREFIX}_Development.SABIModule_FOUND - OR ${_PYTHON_PREFIX}_Development.Embed_FOUND) - AND EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/PyPy.h") - # retrieve PyPy version - file (STRINGS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/patchlevel.h" ${_PYTHON_PREFIX}_PyPy_VERSION - REGEX "^#define[ \t]+PYPY_VERSION[ \t]+\"[^\"]+\"") - string (REGEX REPLACE "^#define[ \t]+PYPY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" - ${_PYTHON_PREFIX}_PyPy_VERSION "${${_PYTHON_PREFIX}_PyPy_VERSION}") - endif() - - unset(${_PYTHON_PREFIX}_LINK_OPTIONS) - if (${_PYTHON_PREFIX}_Development.Embed_FOUND AND APPLE - AND ${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$") - # rpath must be specified if python is part of a framework - unset(_${_PYTHON_PREFIX}_is_prefix) - foreach (_${_PYTHON_PREFIX}_implementation IN LISTS _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS) - foreach (_${_PYTHON_PREFIX}_framework IN LISTS _${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_implementation}_FRAMEWORKS) - cmake_path (IS_PREFIX _${_PYTHON_PREFIX}_framework "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" _${_PYTHON_PREFIX}_is_prefix) - if (_${_PYTHON_PREFIX}_is_prefix) - cmake_path (GET _${_PYTHON_PREFIX}_framework PARENT_PATH _${_PYTHON_PREFIX}_framework) - set (${_PYTHON_PREFIX}_LINK_OPTIONS "LINKER:-rpath,${_${_PYTHON_PREFIX}_framework}") - break() - endif() - endforeach() - if (_${_PYTHON_PREFIX}_is_prefix) - break() - endif() - endforeach() - unset(_${_PYTHON_PREFIX}_implementation) - unset(_${_PYTHON_PREFIX}_framework) - unset(_${_PYTHON_PREFIX}_is_prefix) - endif() - - if (NOT DEFINED ${_PYTHON_PREFIX}_SOABI) - _python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI) - endif() - - if (NOT DEFINED ${_PYTHON_PREFIX}_SOSABI) - _python_get_config_var (${_PYTHON_PREFIX}_SOSABI SOSABI) - endif() - - _python_compute_development_signature (Module) - _python_compute_development_signature (SABIModule) - _python_compute_development_signature (Embed) - - # Restore the original find library ordering - if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES}) - endif() - - if (${_PYTHON_PREFIX}_ARTIFACTS_INTERACTIVE) - if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) - set (${_PYTHON_PREFIX}_LIBRARY "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" CACHE FILEPATH "${_PYTHON_PREFIX} Library") - endif() - if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) - set (${_PYTHON_PREFIX}_SABI_LIBRARY "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}" CACHE FILEPATH "${_PYTHON_PREFIX} ABI Library") - endif() - if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) - set (${_PYTHON_PREFIX}_INCLUDE_DIR "${_${_PYTHON_PREFIX}_INCLUDE_DIR}" CACHE FILEPATH "${_PYTHON_PREFIX} Include Directory") - endif() - endif() - - _python_mark_as_internal (_${_PYTHON_PREFIX}_LIBRARY_RELEASE - _${_PYTHON_PREFIX}_LIBRARY_DEBUG - _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE - _${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG - _${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_RELEASE - _${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DEBUG - _${_PYTHON_PREFIX}_INCLUDE_DIR - _${_PYTHON_PREFIX}_CONFIG - _${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE - _${_PYTHON_PREFIX}_DEVELOPMENT_EMBED_SIGNATURE) -endif() - -if (${_PYTHON_PREFIX}_FIND_REQUIRED_NumPy) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS) -endif() -if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Interpreter_FOUND) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR) - - if (DEFINED ${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR - AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") - set (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}" CACHE INTERNAL "") - elseif (DEFINED _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR) - # compute numpy signature. Depends on interpreter and development signatures - string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}:${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") - if (NOT __${_PYTHON_PREFIX}_NUMPY_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_NUMPY_SIGNATURE - OR NOT EXISTS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") - unset (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR CACHE) - unset (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE CACHE) - endif() - endif() - - if (NOT _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR) - execute_process(COMMAND ${${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys\ntry: import numpy; sys.stdout.write(numpy.get_include())\nexcept:pass\n" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_NumPy_PATH - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - - if (NOT _${_PYTHON_PREFIX}_RESULT) - find_path (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR - NAMES "numpy/arrayobject.h" "numpy/numpyconfig.h" - HINTS "${_${_PYTHON_PREFIX}_NumPy_PATH}" - NO_DEFAULT_PATH) - endif() - endif() - - set (${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") - - if(_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR AND NOT EXISTS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") - set_property (CACHE _${_PYTHON_PREFIX}_NumPy_REASON_FAILURE PROPERTY VALUE "Cannot find the directory \"${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}\"") - set_property (CACHE _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR-NOTFOUND") - endif() - - if (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR) - execute_process (COMMAND ${${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys\ntry: import numpy; sys.stdout.write(numpy.__version__)\nexcept:pass\n" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_NumPy_VERSION) - if (NOT _${_PYTHON_PREFIX}_RESULT) - set (${_PYTHON_PREFIX}_NumPy_VERSION "${_${_PYTHON_PREFIX}_NumPy_VERSION}") - else() - unset (${_PYTHON_PREFIX}_NumPy_VERSION) - endif() - - # final step: set NumPy founded only if Development.Module component is founded as well - set(${_PYTHON_PREFIX}_NumPy_FOUND ${${_PYTHON_PREFIX}_Development.Module_FOUND}) - else() - set (${_PYTHON_PREFIX}_NumPy_FOUND FALSE) - endif() - - if (${_PYTHON_PREFIX}_NumPy_FOUND) - unset (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE CACHE) - - # compute and save numpy signature - string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}:${${_PYTHON_PREFIX}_NumPyINCLUDE_DIR}") - set (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${__${_PYTHON_PREFIX}_NUMPY_SIGNATURE}" CACHE INTERNAL "") - else() - unset (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE CACHE) - endif() - - if (${_PYTHON_PREFIX}_ARTIFACTS_INTERACTIVE) - set (${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}" CACHE FILEPATH "${_PYTHON_PREFIX} NumPy Include Directory") - endif() - - _python_mark_as_internal (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR - _${_PYTHON_PREFIX}_NUMPY_SIGNATURE) -endif() - -# final validation -if (${_PYTHON_PREFIX}_VERSION_MAJOR AND - NOT ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Found unsuitable major version \"${${_PYTHON_PREFIX}_VERSION_MAJOR}\", but required major version is exact version \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") - - cmake_policy(POP) - return() -endif() - -unset (_${_PYTHON_PREFIX}_REASON_FAILURE) -foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development NumPy) - if (_${_PYTHON_PREFIX}_COMPONENT STREQUAL "Development") - foreach (artifact IN LISTS _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) - if (_${_PYTHON_PREFIX}_Development_${artifact}_REASON_FAILURE) - _python_add_reason_failure ("Development" "${_${_PYTHON_PREFIX}_Development_${artifact}_REASON_FAILURE}") - endif() - endforeach() - endif() - if (_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE) - string (APPEND _${_PYTHON_PREFIX}_REASON_FAILURE "\n ${_${_PYTHON_PREFIX}_COMPONENT}: ${_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE}") - unset (_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE CACHE) - endif() -endforeach() - -find_package_handle_standard_args (${_PYTHON_PREFIX} - REQUIRED_VARS ${_${_PYTHON_PREFIX}_REQUIRED_VARS} - VERSION_VAR ${_PYTHON_PREFIX}_VERSION - HANDLE_COMPONENTS - REASON_FAILURE_MESSAGE "${_${_PYTHON_PREFIX}_REASON_FAILURE}") - -# Create imported targets and helper functions -if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") - if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Interpreter_FOUND - AND NOT TARGET ${_PYTHON_PREFIX}::Interpreter) - add_executable (${_PYTHON_PREFIX}::Interpreter IMPORTED) - set_property (TARGET ${_PYTHON_PREFIX}::Interpreter - PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_EXECUTABLE}") - endif() - - if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Compiler_FOUND - AND NOT TARGET ${_PYTHON_PREFIX}::Compiler) - add_executable (${_PYTHON_PREFIX}::Compiler IMPORTED) - set_property (TARGET ${_PYTHON_PREFIX}::Compiler - PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_COMPILER}") - endif() - - if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Development.Module_FOUND) - OR ("Development.SABIModule" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Development.SABIModule_FOUND) - OR ("Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Development.Embed_FOUND)) - - macro (__PYTHON_IMPORT_LIBRARY __name) - if (${ARGC} GREATER 1) - set (_PREFIX "${ARGV1}_") - else() - set (_PREFIX "") - endif() - if (${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_RUNTIME_${_PREFIX}LIBRARY_RELEASE) - set (_${_PYTHON_PREFIX}_LIBRARY_TYPE SHARED) - else() - set (_${_PYTHON_PREFIX}_LIBRARY_TYPE STATIC) - endif() - - if (NOT TARGET ${__name}) - add_library (${__name} ${_${_PYTHON_PREFIX}_LIBRARY_TYPE} IMPORTED) - endif() - - set_property (TARGET ${__name} - PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIRS}") - - if (${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_RUNTIME_${_PREFIX}LIBRARY_RELEASE) - # System manage shared libraries in two parts: import and runtime - if (${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_DEBUG) - set_property (TARGET ${__name} PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) - set_target_properties (${__name} - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" - IMPORTED_IMPLIB_RELEASE "${${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_RELEASE}" - IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_${_PREFIX}RUNTIME_LIBRARY_RELEASE}") - set_target_properties (${__name} - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" - IMPORTED_IMPLIB_DEBUG "${${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_DEBUG}" - IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_RUNTIME_${_PREFIX}LIBRARY_DEBUG}") - else() - set_target_properties (${__name} - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_${_PREFIX}LIBRARIES}" - IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_${_PREFIX}LIBRARY_RELEASE}") - endif() - else() - if (${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_DEBUG) - set_property (TARGET ${__name} PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) - set_target_properties (${__name} - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" - IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_RELEASE}") - set_target_properties (${__name} - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" - IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_DEBUG}") - else() - set_target_properties (${__name} - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_LOCATION "${${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_RELEASE}") - endif() - endif() - - if (_${_PYTHON_PREFIX}_LIBRARY_TYPE STREQUAL "STATIC") - # extend link information with dependent libraries - _python_get_config_var (_${_PYTHON_PREFIX}_LINK_LIBRARIES LIBS) - if (_${_PYTHON_PREFIX}_LINK_LIBRARIES) - set_property (TARGET ${__name} - PROPERTY INTERFACE_LINK_LIBRARIES ${_${_PYTHON_PREFIX}_LINK_LIBRARIES}) - endif() - endif() - - if (${_PYTHON_PREFIX}_LINK_OPTIONS - AND _${_PYTHON_PREFIX}_LIBRARY_TYPE STREQUAL "SHARED") - set_property (TARGET ${__name} PROPERTY INTERFACE_LINK_OPTIONS "${${_PYTHON_PREFIX}_LINK_OPTIONS}") - endif() - endmacro() - - macro (__PYTHON_IMPORT_MODULE __name) - if (NOT TARGET ${__name}) - add_library (${__name} INTERFACE IMPORTED) - endif() - set_property (TARGET ${__name} - PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIRS}") - - # When available, enforce shared library generation with undefined symbols - if (APPLE) - set_property (TARGET ${__name} - PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup") - endif() - if (CMAKE_SYSTEM_NAME STREQUAL "SunOS") - set_property (TARGET ${__name} - PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-z,nodefs") - endif() - if (CMAKE_SYSTEM_NAME STREQUAL "AIX") - set_property (TARGET ${__name} - PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-b,erok") - endif() - endmacro() - - if (${_PYTHON_PREFIX}_Development.Embed_FOUND) - __python_import_library (${_PYTHON_PREFIX}::Python) - endif() - - if (${_PYTHON_PREFIX}_Development.Module_FOUND) - if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS) - # On Windows/CYGWIN/MSYS, Python::Module is the same as Python::Python - # but ALIAS cannot be used because the imported library is not GLOBAL. - __python_import_library (${_PYTHON_PREFIX}::Module) - else() - __python_import_module (${_PYTHON_PREFIX}::Module) - endif() - endif() - - if (${_PYTHON_PREFIX}_Development.SABIModule_FOUND) - if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS) - __python_import_library (${_PYTHON_PREFIX}::SABIModule SABI) - else() - __python_import_module (${_PYTHON_PREFIX}::SABIModule) - endif() - endif() - - # - # PYTHON_ADD_LIBRARY ( [STATIC|SHARED|MODULE] src1 src2 ... srcN) - # It is used to build modules for python. - # - function (__${_PYTHON_PREFIX}_ADD_LIBRARY prefix name) - cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY "STATIC;SHARED;MODULE;WITH_SOABI" "USE_SABI" "") - - if (PYTHON_ADD_LIBRARY_STATIC) - set (type STATIC) - elseif (PYTHON_ADD_LIBRARY_SHARED) - set (type SHARED) - else() - set (type MODULE) - endif() - - if (PYTHON_ADD_LIBRARY_USE_SABI) - if (NOT type STREQUAL MODULE) - message (SEND_ERROR "${prefix}_ADD_LIBRARY: 'USE_SABI' option is only valid for 'MODULE' type.") - return() - endif() - if (NOT PYTHON_ADD_LIBRARY_USE_SABI MATCHES "^(3)(\\.([0-9]+))?$") - message (SEND_ERROR "${prefix}_ADD_LIBRARY: ${PYTHON_ADD_LIBRARY_USE_SABI}: wrong version specified for 'USE_SABI'.") - return() - endif() - # compute value for Py_LIMITED_API macro - set (major_version "${CMAKE_MATCH_1}") - unset (minor_version) - if (CMAKE_MATCH_3) - set (minor_version "${CMAKE_MATCH_3}") - endif() - if (major_version EQUAL "3" AND NOT minor_version) - set (Py_LIMITED_API "3") - elseif ("${major_version}.${minor_version}" VERSION_LESS "3.2") - message (SEND_ERROR "${prefix}_ADD_LIBRARY: ${PYTHON_ADD_LIBRARY_USE_SABI}: invalid version. Version must be '3.2' or upper.") - return() - else() - set (Py_LIMITED_API "0x0${major_version}") - if (NOT minor_version) - string (APPEND Py_LIMITED_API "00") - else() - if (minor_version LESS 16) - string (APPEND Py_LIMITED_API "0") - endif() - math (EXPR minor_version "${minor_version}" OUTPUT_FORMAT HEXADECIMAL) - string (REGEX REPLACE "^0x(.+)$" "\\1" minor_version "${minor_version}") - string (APPEND Py_LIMITED_API "${minor_version}") - endif() - string (APPEND Py_LIMITED_API "0000") - endif() - endif() - - if (type STREQUAL "MODULE") - if (PYTHON_ADD_LIBRARY_USE_SABI AND NOT TARGET ${prefix}::SABIModule) - message (SEND_ERROR "${prefix}_ADD_LIBRARY: dependent target '${prefix}::SABIModule' is not defined.\n Did you miss to request COMPONENT 'Development.SABIModule'?") - return() - endif() - if (NOT PYTHON_ADD_LIBRARY_USE_SABI AND NOT TARGET ${prefix}::Module) - message (SEND_ERROR "${prefix}_ADD_LIBRARY: dependent target '${prefix}::Module' is not defined.\n Did you miss to request COMPONENT 'Development.Module'?") - return() - endif() - endif() - if (NOT type STREQUAL "MODULE" AND NOT TARGET ${prefix}::Python) - message (SEND_ERROR "${prefix}_ADD_LIBRARY: dependent target '${prefix}::Python' is not defined.\n Did you miss to request COMPONENT 'Development.Embed'?") - return() - endif() - - add_library (${name} ${type} ${PYTHON_ADD_LIBRARY_UNPARSED_ARGUMENTS}) - - get_property (type TARGET ${name} PROPERTY TYPE) - - if (type STREQUAL "MODULE_LIBRARY") - if (PYTHON_ADD_LIBRARY_USE_SABI) - target_compile_definitions (${name} PRIVATE Py_LIMITED_API=${Py_LIMITED_API}) - target_link_libraries (${name} PRIVATE ${prefix}::SABIModule) - else() - target_link_libraries (${name} PRIVATE ${prefix}::Module) - endif() - # customize library name to follow module name rules - set_property (TARGET ${name} PROPERTY PREFIX "") - if(CMAKE_SYSTEM_NAME STREQUAL "Windows") - set_property (TARGET ${name} PROPERTY SUFFIX ".pyd") - endif() - - if (PYTHON_ADD_LIBRARY_WITH_SOABI) - if (NOT PYTHON_ADD_LIBRARY_USE_SABI AND ${prefix}_SOABI) - get_property (suffix TARGET ${name} PROPERTY SUFFIX) - if (NOT suffix) - set (suffix "${CMAKE_SHARED_MODULE_SUFFIX}") - endif() - set_property (TARGET ${name} PROPERTY SUFFIX ".${${prefix}_SOABI}${suffix}") - endif() - if (PYTHON_ADD_LIBRARY_USE_SABI AND ${prefix}_SOSABI) - get_property (suffix TARGET ${name} PROPERTY SUFFIX) - if (NOT suffix) - set (suffix "${CMAKE_SHARED_MODULE_SUFFIX}") - endif() - set_property (TARGET ${name} PROPERTY SUFFIX ".${${prefix}_SOSABI}${suffix}") - endif() - endif() - else() - if (PYTHON_ADD_LIBRARY_WITH_SOABI OR PYTHON_ADD_LIBRARY_USE_SABI) - message (AUTHOR_WARNING "Find${prefix}: Options 'WITH_SOABI' and 'USE_SABI' are only supported for `MODULE` library type.") - endif() - target_link_libraries (${name} PRIVATE ${prefix}::Python) - endif() - endfunction() - endif() - - if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_NumPy_FOUND - AND NOT TARGET ${_PYTHON_PREFIX}::NumPy AND TARGET ${_PYTHON_PREFIX}::Module) - add_library (${_PYTHON_PREFIX}::NumPy INTERFACE IMPORTED) - set_property (TARGET ${_PYTHON_PREFIX}::NumPy - PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS}") - target_link_libraries (${_PYTHON_PREFIX}::NumPy INTERFACE ${_PYTHON_PREFIX}::Module) - endif() -endif() - -# final clean-up - -# Restore CMAKE_FIND_APPBUNDLE -if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) - set (CMAKE_FIND_APPBUNDLE ${_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE}) - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) -else() - unset (CMAKE_FIND_APPBUNDLE) -endif() -# Restore CMAKE_FIND_FRAMEWORK -if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) - set (CMAKE_FIND_FRAMEWORK ${_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK}) - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) -else() - unset (CMAKE_FIND_FRAMEWORK) -endif() - -cmake_policy(POP) diff --git a/cmake/modules/FindPython3.cmake b/cmake/modules/FindPython3.cmake deleted file mode 100644 index 901565bdfac3..000000000000 --- a/cmake/modules/FindPython3.cmake +++ /dev/null @@ -1,553 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPython3 ------------ - -.. versionadded:: 3.12 - -Find Python 3 interpreter, compiler and development environment (include -directories and libraries). - -.. versionadded:: 3.19 - When a version is requested, it can be specified as a simple value or as a - range. For a detailed description of version range usage and capabilities, - refer to the :command:`find_package` command. - -The following components are supported: - -* ``Interpreter``: search for Python 3 interpreter -* ``Compiler``: search for Python 3 compiler. Only offered by IronPython. -* ``Development``: search for development artifacts (include directories and - libraries). - - .. versionadded:: 3.18 - This component includes two sub-components which can be specified - independently: - - * ``Development.Module``: search for artifacts for Python 3 module - developments. - * ``Development.Embed``: search for artifacts for Python 3 embedding - developments. - - .. versionadded:: 3.26 - - * ``Development.SABIModule``: search for artifacts for Python 3 module - developments using the - `Stable Application Binary Interface `_. - This component is available only for version ``3.2`` and upper. - -* ``NumPy``: search for NumPy include directories. - -.. versionadded:: 3.14 - Added the ``NumPy`` component. - -If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed. - -If component ``Development`` is specified, it implies sub-components -``Development.Module`` and ``Development.Embed``. - -To ensure consistent versions between components ``Interpreter``, ``Compiler``, -``Development`` (or one of its sub-components) and ``NumPy``, specify all -components at the same time:: - - find_package (Python3 COMPONENTS Interpreter Development) - -This module looks only for version 3 of Python. This module can be used -concurrently with :module:`FindPython2` module to use both Python versions. - -The :module:`FindPython` module can be used if Python version does not matter -for you. - -.. note:: - - If components ``Interpreter`` and ``Development`` (or one of its - sub-components) are both specified, this module search only for interpreter - with same platform architecture as the one defined by CMake - configuration. This constraint does not apply if only ``Interpreter`` - component is specified. - -Imported Targets -^^^^^^^^^^^^^^^^ - -This module defines the following :ref:`Imported Targets `: - -.. versionchanged:: 3.14 - :ref:`Imported Targets ` are only created when - :prop_gbl:`CMAKE_ROLE` is ``PROJECT``. - -``Python3::Interpreter`` - Python 3 interpreter. Target defined if component ``Interpreter`` is found. -``Python3::Compiler`` - Python 3 compiler. Target defined if component ``Compiler`` is found. - -``Python3::Module`` - .. versionadded:: 3.15 - - Python 3 library for Python module. Target defined if component - ``Development.Module`` is found. - -``Python3::SABIModule`` - .. versionadded:: 3.26 - - Python 3 library for Python module using the Stable Application Binary - Interface. Target defined if component ``Development.SABIModule`` is found. - -``Python3::Python`` - Python 3 library for Python embedding. Target defined if component - ``Development.Embed`` is found. - -``Python3::NumPy`` - .. versionadded:: 3.14 - - NumPy library for Python 3. Target defined if component ``NumPy`` is found. - -Result Variables -^^^^^^^^^^^^^^^^ - -This module will set the following variables in your project -(see :ref:`Standard Variable Names `): - -``Python3_FOUND`` - System has the Python 3 requested components. -``Python3_Interpreter_FOUND`` - System has the Python 3 interpreter. -``Python3_EXECUTABLE`` - Path to the Python 3 interpreter. -``Python3_INTERPRETER_ID`` - A short string unique to the interpreter. Possible values include: - * Python - * ActivePython - * Anaconda - * Canopy - * IronPython - * PyPy -``Python3_STDLIB`` - Standard platform independent installation directory. - - Information returned by ``sysconfig.get_path('stdlib')``. -``Python3_STDARCH`` - Standard platform dependent installation directory. - - Information returned by ``sysconfig.get_path('platstdlib')``. -``Python3_SITELIB`` - Third-party platform independent installation directory. - - Information returned by ``sysconfig.get_path('purelib')``. -``Python3_SITEARCH`` - Third-party platform dependent installation directory. - - Information returned by ``sysconfig.get_path('platlib')``. - -``Python3_SOABI`` - .. versionadded:: 3.17 - - Extension suffix for modules. - - Information computed from ``sysconfig.get_config_var('EXT_SUFFIX')`` or - ``sysconfig.get_config_var('SOABI')`` or - ``python3-config --extension-suffix``. - -``Python3_SOSABI`` - .. versionadded:: 3.26 - - Extension suffix for modules using the Stable Application Binary Interface. - - Information computed from ``importlib.machinery.EXTENSION_SUFFIXES`` if the - COMPONENT ``Interpreter`` was specified. Otherwise, the extension is ``abi3`` - except for ``Windows``, ``MSYS`` and ``CYGWIN`` for which this is an empty - string. - -``Python3_Compiler_FOUND`` - System has the Python 3 compiler. -``Python3_COMPILER`` - Path to the Python 3 compiler. Only offered by IronPython. -``Python3_COMPILER_ID`` - A short string unique to the compiler. Possible values include: - * IronPython - -``Python3_DOTNET_LAUNCHER`` - .. versionadded:: 3.18 - - The ``.Net`` interpreter. Only used by ``IronPython`` implementation. - -``Python3_Development_FOUND`` - - System has the Python 3 development artifacts. - -``Python3_Development.Module_FOUND`` - .. versionadded:: 3.18 - - System has the Python 3 development artifacts for Python module. - -``Python3_Development.SABIModule_FOUND`` - .. versionadded:: 3.26 - - System has the Python 3 development artifacts for Python module using the - Stable Application Binary Interface. - -``Python3_Development.Embed_FOUND`` - .. versionadded:: 3.18 - - System has the Python 3 development artifacts for Python embedding. - -``Python3_INCLUDE_DIRS`` - - The Python 3 include directories. - -``Python3_LINK_OPTIONS`` - .. versionadded:: 3.19 - - The Python 3 link options. Some configurations require specific link options - for a correct build and execution. - -``Python3_LIBRARIES`` - The Python 3 libraries. -``Python3_LIBRARY_DIRS`` - The Python 3 library directories. -``Python3_RUNTIME_LIBRARY_DIRS`` - The Python 3 runtime library directories. -``Python3_SABI_LIBRARIES`` - .. versionadded:: 3.26 - - The Python 3 libraries for the Stable Application Binary Interface. -``Python3_SABI_LIBRARY_DIRS`` - .. versionadded:: 3.26 - - The Python 3 ``SABI`` library directories. -``Python3_RUNTIME_SABI_LIBRARY_DIRS`` - .. versionadded:: 3.26 - - The Python 3 runtime ``SABI`` library directories. -``Python3_VERSION`` - Python 3 version. -``Python3_VERSION_MAJOR`` - Python 3 major version. -``Python3_VERSION_MINOR`` - Python 3 minor version. -``Python3_VERSION_PATCH`` - Python 3 patch version. - -``Python3_PyPy_VERSION`` - .. versionadded:: 3.18 - - Python 3 PyPy version. - -``Python3_NumPy_FOUND`` - .. versionadded:: 3.14 - - System has the NumPy. - -``Python3_NumPy_INCLUDE_DIRS`` - .. versionadded:: 3.14 - - The NumPy include directories. - -``Python3_NumPy_VERSION`` - .. versionadded:: 3.14 - - The NumPy version. - -Hints -^^^^^ - -``Python3_ROOT_DIR`` - Define the root directory of a Python 3 installation. - -``Python3_USE_STATIC_LIBS`` - * If not defined, search for shared libraries and static libraries in that - order. - * If set to TRUE, search **only** for static libraries. - * If set to FALSE, search **only** for shared libraries. - - .. note:: - - This hint will be ignored on ``Windows`` because static libraries are not - available on this platform. - -``Python3_FIND_ABI`` - .. versionadded:: 3.16 - - This variable defines which ABIs, as defined in :pep:`3149`, should be - searched. - - .. note:: - - If ``Python3_FIND_ABI`` is not defined, any ABI will be searched. - - The ``Python3_FIND_ABI`` variable is a 3-tuple specifying, in that order, - ``pydebug`` (``d``), ``pymalloc`` (``m``) and ``unicode`` (``u``) flags. - Each element can be set to one of the following: - - * ``ON``: Corresponding flag is selected. - * ``OFF``: Corresponding flag is not selected. - * ``ANY``: The two possibilities (``ON`` and ``OFF``) will be searched. - - From this 3-tuple, various ABIs will be searched starting from the most - specialized to the most general. Moreover, ``debug`` versions will be - searched **after** ``non-debug`` ones. - - For example, if we have:: - - set (Python3_FIND_ABI "ON" "ANY" "ANY") - - The following flags combinations will be appended, in that order, to the - artifact names: ``dmu``, ``dm``, ``du``, and ``d``. - - And to search any possible ABIs:: - - set (Python3_FIND_ABI "ANY" "ANY" "ANY") - - The following combinations, in that order, will be used: ``mu``, ``m``, - ``u``, ````, ``dmu``, ``dm``, ``du`` and ``d``. - - .. note:: - - This hint is useful only on ``POSIX`` systems. So, on ``Windows`` systems, - when ``Python3_FIND_ABI`` is defined, ``Python`` distributions from - `python.org `_ will be found only if value for - each flag is ``OFF`` or ``ANY``. - -``Python3_FIND_STRATEGY`` - .. versionadded:: 3.15 - - This variable defines how lookup will be done. - The ``Python3_FIND_STRATEGY`` variable can be set to one of the following: - - * ``VERSION``: Try to find the most recent version in all specified - locations. - This is the default if policy :policy:`CMP0094` is undefined or set to - ``OLD``. - * ``LOCATION``: Stops lookup as soon as a version satisfying version - constraints is founded. - This is the default if policy :policy:`CMP0094` is set to ``NEW``. - - See also ``Python3_FIND_UNVERSIONED_NAMES``. - -``Python3_FIND_REGISTRY`` - .. versionadded:: 3.13 - - On Windows the ``Python3_FIND_REGISTRY`` variable determine the order - of preference between registry and environment variables. - The ``Python3_FIND_REGISTRY`` variable can be set to one of the following: - - * ``FIRST``: Try to use registry before environment variables. - This is the default. - * ``LAST``: Try to use registry after environment variables. - * ``NEVER``: Never try to use registry. - -``Python3_FIND_FRAMEWORK`` - .. versionadded:: 3.15 - - On macOS the ``Python3_FIND_FRAMEWORK`` variable determine the order of - preference between Apple-style and unix-style package components. - This variable can take same values as :variable:`CMAKE_FIND_FRAMEWORK` - variable. - - .. note:: - - Value ``ONLY`` is not supported so ``FIRST`` will be used instead. - - If ``Python3_FIND_FRAMEWORK`` is not defined, :variable:`CMAKE_FIND_FRAMEWORK` - variable will be used, if any. - -``Python3_FIND_VIRTUALENV`` - .. versionadded:: 3.15 - - This variable defines the handling of virtual environments managed by - ``virtualenv`` or ``conda``. It is meaningful only when a virtual environment - is active (i.e. the ``activate`` script has been evaluated). In this case, it - takes precedence over ``Python3_FIND_REGISTRY`` and ``CMAKE_FIND_FRAMEWORK`` - variables. The ``Python3_FIND_VIRTUALENV`` variable can be set to one of the - following: - - * ``FIRST``: The virtual environment is used before any other standard - paths to look-up for the interpreter. This is the default. - * ``ONLY``: Only the virtual environment is used to look-up for the - interpreter. - * ``STANDARD``: The virtual environment is not used to look-up for the - interpreter but environment variable ``PATH`` is always considered. - In this case, variable ``Python3_FIND_REGISTRY`` (Windows) or - ``CMAKE_FIND_FRAMEWORK`` (macOS) can be set with value ``LAST`` or - ``NEVER`` to select preferably the interpreter from the virtual - environment. - - .. versionadded:: 3.17 - Added support for ``conda`` environments. - - .. note:: - - If the component ``Development`` is requested, it is **strongly** - recommended to also include the component ``Interpreter`` to get expected - result. - -``Python3_FIND_IMPLEMENTATIONS`` - .. versionadded:: 3.18 - - This variable defines, in an ordered list, the different implementations - which will be searched. The ``Python3_FIND_IMPLEMENTATIONS`` variable can - hold the following values: - - * ``CPython``: this is the standard implementation. Various products, like - ``Anaconda`` or ``ActivePython``, rely on this implementation. - * ``IronPython``: This implementation use the ``CSharp`` language for - ``.NET Framework`` on top of the `Dynamic Language Runtime` (``DLR``). - See `IronPython `_. - * ``PyPy``: This implementation use ``RPython`` language and - ``RPython translation toolchain`` to produce the python interpreter. - See `PyPy `_. - - The default value is: - - * Windows platform: ``CPython``, ``IronPython`` - * Other platforms: ``CPython`` - - .. note:: - - This hint has the lowest priority of all hints, so even if, for example, - you specify ``IronPython`` first and ``CPython`` in second, a python - product based on ``CPython`` can be selected because, for example with - ``Python3_FIND_STRATEGY=LOCATION``, each location will be search first for - ``IronPython`` and second for ``CPython``. - - .. note:: - - When ``IronPython`` is specified, on platforms other than ``Windows``, the - ``.Net`` interpreter (i.e. ``mono`` command) is expected to be available - through the ``PATH`` variable. - -``Python3_FIND_UNVERSIONED_NAMES`` - .. versionadded:: 3.20 - - This variable defines how the generic names will be searched. Currently, it - only applies to the generic names of the interpreter, namely, ``python3`` and - ``python``. - The ``Python3_FIND_UNVERSIONED_NAMES`` variable can be set to one of the - following values: - - * ``FIRST``: The generic names are searched before the more specialized ones - (such as ``python3.5`` for example). - * ``LAST``: The generic names are searched after the more specialized ones. - This is the default. - * ``NEVER``: The generic name are not searched at all. - - See also ``Python3_FIND_STRATEGY``. - -Artifacts Specification -^^^^^^^^^^^^^^^^^^^^^^^ - -.. versionadded:: 3.16 - -To solve special cases, it is possible to specify directly the artifacts by -setting the following variables: - -``Python3_EXECUTABLE`` - The path to the interpreter. - -``Python3_COMPILER`` - The path to the compiler. - -``Python3_DOTNET_LAUNCHER`` - .. versionadded:: 3.18 - - The ``.Net`` interpreter. Only used by ``IronPython`` implementation. - -``Python3_LIBRARY`` - The path to the library. It will be used to compute the - variables ``Python3_LIBRARIES``, ``Python3_LIBRARY_DIRS`` and - ``Python3_RUNTIME_LIBRARY_DIRS``. - -``Python3_SABI_LIBRARY`` - .. versionadded:: 3.26 - - The path to the library for Stable Application Binary Interface. It will be - used to compute the variables ``Python3_SABI_LIBRARIES``, - ``Python3_SABI_LIBRARY_DIRS`` and ``Python3_RUNTIME_SABI_LIBRARY_DIRS``. - -``Python3_INCLUDE_DIR`` - The path to the directory of the ``Python`` headers. It will be used to - compute the variable ``Python3_INCLUDE_DIRS``. - -``Python3_NumPy_INCLUDE_DIR`` - The path to the directory of the ``NumPy`` headers. It will be used to - compute the variable ``Python3_NumPy_INCLUDE_DIRS``. - -.. note:: - - All paths must be absolute. Any artifact specified with a relative path - will be ignored. - -.. note:: - - When an artifact is specified, all ``HINTS`` will be ignored and no search - will be performed for this artifact. - - If more than one artifact is specified, it is the user's responsibility to - ensure the consistency of the various artifacts. - -By default, this module supports multiple calls in different directories of a -project with different version/component requirements while providing correct -and consistent results for each call. To support this behavior, CMake cache -is not used in the traditional way which can be problematic for interactive -specification. So, to enable also interactive specification, module behavior -can be controlled with the following variable: - -``Python3_ARTIFACTS_INTERACTIVE`` - .. versionadded:: 3.18 - - Selects the behavior of the module. This is a boolean variable: - - * If set to ``TRUE``: Create CMake cache entries for the above artifact - specification variables so that users can edit them interactively. - This disables support for multiple version/component requirements. - * If set to ``FALSE`` or undefined: Enable multiple version/component - requirements. - -Commands -^^^^^^^^ - -This module defines the command ``Python3_add_library`` (when -:prop_gbl:`CMAKE_ROLE` is ``PROJECT``), which has the same semantics as -:command:`add_library` and adds a dependency to target ``Python3::Python`` or, -when library type is ``MODULE``, to target ``Python3::Module`` or -``Python3::SABIModule`` (when ``USE_SABI`` option is specified) and takes care -of Python module naming rules:: - - Python3_add_library ( [STATIC | SHARED | MODULE [USE_SABI ] [WITH_SOABI]] - [ ...]) - -If the library type is not specified, ``MODULE`` is assumed. - -.. versionadded:: 3.17 - For ``MODULE`` library type, if option ``WITH_SOABI`` is specified, the - module suffix will include the ``Python3_SOABI`` value, if any. - -.. versionadded:: 3.26 - For ``MODULE`` type, if the option ``USE_SABI`` is specified, the - preprocessor definition ``Py_LIMITED_API`` will be specified, as ``PRIVATE``, - for the target ```` with the value computed from ```` argument. - The expected format for ```` is ``major[.minor]``, where each - component is a numeric value. If ``minor`` component is specified, the - version should be, at least, ``3.2`` which is the version where the - `Stable Application Binary Interface `_ - was introduced. Specifying only major version ``3`` is equivalent to ``3.2``. - - When option ``WITH_SOABI`` is also specified, the module suffix will include - the ``Python3_SOSABI`` value, if any. -#]=======================================================================] - - -set (_PYTHON_PREFIX Python3) - -set (_Python3_REQUIRED_VERSION_MAJOR 3) - -include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake) - -if (COMMAND __Python3_add_library) - macro (Python3_add_library) - __Python3_add_library (Python3 ${ARGV}) - endmacro() -endif() - -unset (_PYTHON_PREFIX) diff --git a/cmake/modules/FindSanitizers.cmake b/cmake/modules/FindSanitizers.cmake index 1401ca2442bf..c3dcd85bfd7f 100644 --- a/cmake/modules/FindSanitizers.cmake +++ b/cmake/modules/FindSanitizers.cmake @@ -1,6 +1,6 @@ if(NOT Sanitizers_FIND_COMPONENTS) set(Sanitizers_FIND_COMPONENTS - address undefined_behavior) + address undefined_behavior vptr) endif() if(HAVE_JEMALLOC) message(WARNING "JeMalloc does not work well with sanitizers") @@ -23,7 +23,11 @@ foreach(component ${Sanitizers_FIND_COMPONENTS}) set(Sanitizers_thread_COMPILE_OPTIONS "-fsanitize=thread") elseif(component STREQUAL "undefined_behavior") # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88684 - set(Sanitizers_undefined_behavior_COMPILE_OPTIONS "-fsanitize=undefined;-fno-sanitize=vptr") + set(Sanitizers_undefined_behavior_COMPILE_OPTIONS "-fsanitize=undefined") + elseif (component STREQUAL "vptr") + # since Clang version 21, -fsanitize=undefined no longer implies vptr, + # so we enable it explicitly + set(Sanitizers_vptr_COMPILE_OPTIONS "-fno-sanitize=vptr") else() message(SEND_ERROR "Unsupported sanitizer: ${component}") endif() diff --git a/cmake/modules/Finddaxctl.cmake b/cmake/modules/Finddaxctl.cmake deleted file mode 100644 index fbe58042466a..000000000000 --- a/cmake/modules/Finddaxctl.cmake +++ /dev/null @@ -1,42 +0,0 @@ -# - Find libdaxctl -# Find the daxctl libraries and includes -# -# daxctl_INCLUDE_DIR - where to find libdaxctl.h etc. -# daxctl_LIBRARIES - List of libraries when using daxctl. -# daxctl_FOUND - True if daxctl found. - -find_path(daxctl_INCLUDE_DIR daxctl/libdaxctl.h) - -if(daxctl_INCLUDE_DIR AND EXISTS "${daxctl_INCLUDE_DIR}/libdaxctl.h") - foreach(ver "MAJOR" "MINOR" "RELEASE") - file(STRINGS "${daxctl_INCLUDE_DIR}/libdaxctl.h" daxctl_VER_${ver}_LINE - REGEX "^#define[ \t]+daxctl_VERSION_${ver}[ \t]+[0-9]+[ \t]+.*$") - string(REGEX REPLACE "^#define[ \t]+daxctl_VERSION_${ver}[ \t]+([0-9]+)[ \t]+.*$" - "\\1" daxctl_VERSION_${ver} "${daxctl_VER_${ver}_LINE}") - unset(${daxctl_VER_${ver}_LINE}) - endforeach() - set(daxctl_VERSION_STRING - "${daxctl_VERSION_MAJOR}.${daxctl_VERSION_MINOR}.${daxctl_VERSION_RELEASE}") -endif() - -find_library(daxctl_LIBRARY daxctl) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(daxctl - REQUIRED_VARS daxctl_LIBRARY daxctl_INCLUDE_DIR - VERSION_VAR daxctl_VERSION_STRING) - -mark_as_advanced(daxctl_INCLUDE_DIR daxctl_LIBRARY) - -if(daxctl_FOUND) - set(daxctl_INCLUDE_DIRS ${daxctl_INCLUDE_DIR}) - set(daxctl_LIBRARIES ${daxctl_LIBRARY}) - if(NOT (TARGET daxctl::daxctl)) - add_library(daxctl::daxctl UNKNOWN IMPORTED) - set_target_properties(daxctl::daxctl PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${daxctl_INCLUDE_DIRS}" - IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_LOCATION "${daxctl_LIBRARIES}" - VERSION "${daxctl_VERSION_STRING}") - endif() -endif() diff --git a/cmake/modules/Finddml.cmake b/cmake/modules/Finddml.cmake deleted file mode 100644 index 8e94ad26d6c3..000000000000 --- a/cmake/modules/Finddml.cmake +++ /dev/null @@ -1,58 +0,0 @@ -# - Find libdml -# Find the dml and dmlhl libraries and includes -# -# DML_INCLUDE_DIR - where to find dml.hpp etc. -# DML_LIBRARIES - List of libraries when using dml. -# DML_HL_LIBRARIES - List of libraries when using dmlhl. -# DML_FOUND - True if DML found. - - -find_path(DML_INCLUDE_DIR - dml/dml.hpp - PATHS - /usr/include - /usr/local/include) - -find_library(DML_LIBRARIES NAMES dml libdml PATHS - /usr/local/ - /usr/local/lib64 - /usr/lib64 - /usr/lib) - -find_library(DML_HL_LIBRARIES NAMES dmlhl libdmlhl PATHS - /usr/local/ - /usr/local/lib64 - /usr/lib64 - /usr/lib) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(dml DEFAULT_MSG - DML_LIBRARIES - DML_INCLUDE_DIR - DML_HL_LIBRARIES) - -mark_as_advanced( - DML_LIBRARIES - DML_INCLUDE_DIR - DML_HL_LIBRARIES) - -if(DML_FOUND) - if(NOT (TARGET dml::dml)) - add_library(dml::dml UNKNOWN IMPORTED) - set_target_properties(dml::dml PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${DML_INCLUDE_DIR}" - IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_LOCATION "${DML_LIBRARIES}") - endif() - - if(NOT (TARGET dml::dmlhl)) - add_library(dml::dmlhl UNKNOWN IMPORTED) - set_target_properties(dml::dmlhl PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${DML_INCLUDE_DIR}" - INTERFACE_LINK_LIBRARIES ${CMAKE_DL_LIBS} - INTERFACE_COMPILE_FEATURES cxx_std_17 - INTERFACE_COMPILE_DEFINITIONS "DML_HW" - IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" - IMPORTED_LOCATION "${DML_HL_LIBRARIES}") - endif() -endif() diff --git a/cmake/modules/Findndctl.cmake b/cmake/modules/Findndctl.cmake deleted file mode 100644 index 12afa1781f7c..000000000000 --- a/cmake/modules/Findndctl.cmake +++ /dev/null @@ -1,42 +0,0 @@ -# - Find libndctl -# Find the ndctl libraries and includes -# -# ndctl_INCLUDE_DIR - where to find libndctl.h etc. -# ndctl_LIBRARIES - List of libraries when using ndctl. -# ndctl_FOUND - True if ndctl found. - -find_path(ndctl_INCLUDE_DIR ndctl/libndctl.h) - -if(ndctl_INCLUDE_DIR AND EXISTS "${ndctl_INCLUDE_DIR}/libndctl.h") - foreach(ver "MAJOR" "MINOR" "RELEASE") - file(STRINGS "${ndctl_INCLUDE_DIR}/libndctl.h" ndctl_VER_${ver}_LINE - REGEX "^#define[ \t]+ndctl_VERSION_${ver}[ \t]+[0-9]+[ \t]+.*$") - string(REGEX REPLACE "^#define[ \t]+ndctl_VERSION_${ver}[ \t]+([0-9]+)[ \t]+.*$" - "\\1" ndctl_VERSION_${ver} "${ndctl_VER_${ver}_LINE}") - unset(${ndctl_VER_${ver}_LINE}) - endforeach() - set(ndctl_VERSION_STRING - "${ndctl_VERSION_MAJOR}.${ndctl_VERSION_MINOR}.${ndctl_VERSION_RELEASE}") -endif() - -find_library(ndctl_LIBRARY ndctl) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(ndctl - REQUIRED_VARS ndctl_LIBRARY ndctl_INCLUDE_DIR - VERSION_VAR ndctl_VERSION_STRING) - -mark_as_advanced(ndctl_INCLUDE_DIR ndctl_LIBRARY) - -if(ndctl_FOUND) - set(ndctl_INCLUDE_DIRS ${ndctl_INCLUDE_DIR}) - set(ndctl_LIBRARIES ${ndctl_LIBRARY}) - if(NOT (TARGET ndctl::ndctl)) - add_library(ndctl::ndctl UNKNOWN IMPORTED) - set_target_properties(ndctl::ndctl PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${ndctl_INCLUDE_DIRS}" - IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_LOCATION "${ndctl_LIBRARIES}" - VERSION "${ndctl_VERSION_STRING}") - endif() -endif() diff --git a/cmake/modules/Findspdk.cmake b/cmake/modules/Findspdk.cmake new file mode 100644 index 000000000000..eef8275798cd --- /dev/null +++ b/cmake/modules/Findspdk.cmake @@ -0,0 +1,26 @@ +# Findspdk.cmake -- locate a system-installed SPDK via pkg-config. +# +# Paired with WITH_SYSTEM_SPDK: link a distro-provided spdk-devel instead of +# building the bundled src/spdk fork. Modelled on Finddpdk.cmake. +# +# Provides: spdk::spdk, spdk_FOUND, SPDK_INCLUDE_DIRS + +find_package(PkgConfig REQUIRED QUIET) + +pkg_check_modules(SPDK IMPORTED_TARGET spdk_nvme spdk_env_dpdk) + +# spdk's .so leave ISA-L symbols (crc32_iscsi, xor_gen, ...) undefined for the +# final link and don't Require isa-l in their .pc; pull it in explicitly. +pkg_check_modules(ISAL REQUIRED IMPORTED_TARGET libisal) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(spdk + REQUIRED_VARS SPDK_FOUND SPDK_INCLUDE_DIRS) + +if(spdk_FOUND AND NOT TARGET spdk::spdk) + add_library(spdk::spdk INTERFACE IMPORTED) + # SPDK/DPDK register drivers via C constructors; keep the libs in DT_NEEDED + # (shared-lib equivalent of the bundled target's --whole-archive). + set_target_properties(spdk::spdk PROPERTIES + INTERFACE_LINK_LIBRARIES "-Wl,--no-as-needed;PkgConfig::SPDK;PkgConfig::ISAL") +endif() diff --git a/cmake/modules/PythonPackage.cmake b/cmake/modules/PythonPackage.cmake new file mode 100644 index 000000000000..7453edf875a6 --- /dev/null +++ b/cmake/modules/PythonPackage.cmake @@ -0,0 +1,84 @@ +find_package(Python3 ${WITH_PYTHON3} EXACT + QUIET + REQUIRED + COMPONENTS Interpreter) + +function(create_python_package pkgname) + set(options BUILD_ISOLATION) + set(oneValueArgs WHEELDIR) + cmake_parse_arguments(PARSE_ARGV 0 pypkg + "${options}" "${oneValueArgs}" "") + if(NOT "${pypkg_WHEELDIR}") + set(pypkg_WHEELDIR "${CMAKE_CURRENT_BINARY_DIR}/wheels/${pkgname}") + endif() + + python_package_build_pip_wheel( + "${pkgname}" "${pypkg_WHEELDIR}" "${pypkg_BUILD_ISOLATION}" + ) + python_package_install_pip_wheel("${pkgname}" "${pypkg_WHEELDIR}") +endfunction(create_python_package) + + +function( + python_package_build_pip_wheel + pkgname + wheeldir + build_isolation +) + list(APPEND build_args + --wheel-dir "${wheeldir}" + --no-deps + --use-pep517 + --disable-pip-version-check + --no-clean + --progress-bar=off + --verbose + ) + if(NOT "${build_isolation}") + list(APPEND build_args --no-build-isolation) + endif() + list(APPEND build_args "${CMAKE_CURRENT_SOURCE_DIR}") + + add_custom_command( + OUTPUT ${wheeldir} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/pyproject.toml + COMMAND ${Python3_EXECUTABLE} -m pip wheel ${build_args} + ) + if(NOT TARGET build-wheel-${pkgname}) + add_custom_target(build-wheel-${pkgname} ALL + DEPENDS ${wheeldir}) + endif() +endfunction(python_package_build_pip_wheel) + +function( + python_package_install_pip_wheel + pkgname + wheeldir +) + list(APPEND install_args + "--prefix=${CMAKE_INSTALL_PREFIX}" + --no-deps + --disable-pip-version-check + --progress-bar=off + --root-user-action=ignore + --verbose + --ignore-installed + --no-warn-script-location + --no-index + --no-cache-dir + --find-links "${wheeldir}" + "${pkgname}" + ) + + install(CODE " + set(args \"${install_args}\") + if(DEFINED ENV{DESTDIR}) + list(INSERT args 1 --root=\$ENV{DESTDIR}) + endif() + message(DEBUG PythonPackage.install_cmd= + \"${Python3_EXECUTABLE} -m pip install\" \"\${args}\") + execute_process( + COMMAND ${Python3_EXECUTABLE} -m pip install \${args} + WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\" + COMMAND_ERROR_IS_FATAL ANY)") +endfunction(python_package_install_pip_wheel) diff --git a/cmake/modules/SIMDExt.cmake b/cmake/modules/SIMDExt.cmake index 35b52e64200b..dfa7ffb7f0c6 100644 --- a/cmake/modules/SIMDExt.cmake +++ b/cmake/modules/SIMDExt.cmake @@ -109,6 +109,38 @@ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(powerpc|ppc)") if(HAVE_POWER8) message(STATUS " HAVE_POWER8 yes") endif() +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "riscv64|RISCV64") + set(HAVE_RISCV 1) + include(CheckCCompilerFlag) + + CHECK_C_COMPILER_FLAG("-march=rv64gc_zbc" HAVE_RISCV_ZBC) + if(HAVE_RISCV_ZBC) + set(HAVE_RISCV_ZBC TRUE) + message(STATUS " RISC-V Extension: Zbc detected (scalar crypto)") + endif() + + CHECK_C_COMPILER_FLAG("-march=rv64gcv_zbc_zvbc" HAVE_RISCV_ZVBC) + if(HAVE_RISCV_ZVBC) + set(HAVE_RISCV_RVV TRUE) + set(HAVE_RISCV_ZVBC TRUE) + message(STATUS " RISC-V Extension: Zvbc detected (vector crypto)") + else() + CHECK_C_COMPILER_FLAG("-march=rv64gcv" HAVE_RISCV_RVV_ONLY) + if(HAVE_RISCV_RVV_ONLY) + set(HAVE_RISCV_RVV TRUE) + message(STATUS " RISC-V Extension: Standard Vector (rv64gcv) detected") + endif() + endif() + + if(HAVE_RISCV_ZVBC) + set(SIMD_COMPILE_FLAGS "${SIMD_COMPILE_FLAGS} -march=rv64gcv_zbc_zvbc") + elseif(HAVE_RISCV_ZBC) + set(SIMD_COMPILE_FLAGS "${SIMD_COMPILE_FLAGS} -march=rv64gc_zbc") + elseif(HAVE_RISCV_RVV) + set(SIMD_COMPILE_FLAGS "${SIMD_COMPILE_FLAGS} -march=rv64gcv") + else() + message(WARNING " RISC-V crypto/vector extensions NOT detected by compiler.") + endif() elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(s390x|S390X|s390|S390)") set(HAVE_S390X 1) message(STATUS " we are s390x") diff --git a/container/Containerfile b/container/Containerfile index c01472523f5e..b847a1c5fbb0 100644 --- a/container/Containerfile +++ b/container/Containerfile @@ -1,4 +1,4 @@ -ARG FROM_IMAGE="quay.io/centos/centos:stream9" +ARG FROM_IMAGE="docker.io/rockylinux/rockylinux:10" FROM $FROM_IMAGE # allow FROM_IMAGE to be visible inside this stage @@ -14,7 +14,7 @@ ARG CEPH_SHA1 ARG CEPH_GIT_REPO # (optional) Define the baseurl= for the ganesha.repo -ARG GANESHA_REPO_BASEURL="https://buildlogs.centos.org/centos/\$releasever-stream/storage/\$basearch/nfsganesha-5/" +ARG GANESHA_REPO_BASEURL="https://buildlogs.centos.org/centos/\$releasever-stream/storage/\$basearch/nfsganesha-9/" # (optional) Set to "crimson" to install crimson packages. ARG OSD_FLAVOR="default" @@ -46,6 +46,23 @@ CEPH_GIT_REPO=${CEPH_GIT_REPO} \ GANESHA_REPO_BASEURL=${GANESHA_REPO_BASEURL} \ OSD_FLAVOR=${OSD_FLAVOR} +# Use bash so var setting works. +SHELL ["/bin/bash", "-c"] + +# Derive EL_VER (el9/el10) and DIST_PATH (centos/9|rocky/10|almalinux/X) +# from /etc/os-release for later use in repo URLs. +RUN set -euo pipefail; \ + source /etc/os-release; \ + MAJOR="${VERSION_ID%%.*}"; \ + case "${ID}" in \ + centos) DIST_PATH="centos/${MAJOR}" ;; \ + rocky) DIST_PATH="rocky/${MAJOR}" ;; \ + almalinux) DIST_PATH="almalinux/${MAJOR}" ;; \ + *) echo "Unsupported base: ID=${ID} VERSION_ID=${VERSION_ID}" >&2; exit 1 ;; \ + esac; \ + EL_VER="el${MAJOR}"; \ + printf 'EL_VER=%s\nDIST_PATH=%s\nID=%s\nVERSION_ID=%s\nMAJOR=%s\n' \ + "$EL_VER" "$DIST_PATH" "$ID" "$VERSION_ID" "$MAJOR" > /etc/ceph-distro.env #=================================================================================================== # Install ceph and dependencies, and clean up @@ -65,28 +82,32 @@ RUN \ # Pre-reqs RUN dnf install -y --setopt=install_weak_deps=False epel-release jq -# Add NFS-Ganesha repo -RUN \ - echo "[ganesha]" > /etc/yum.repos.d/ganesha.repo && \ - echo "name=ganesha" >> /etc/yum.repos.d/ganesha.repo && \ - echo "baseurl=${GANESHA_REPO_BASEURL}" >> /etc/yum.repos.d/ganesha.repo && \ - echo "gpgcheck=0" >> /etc/yum.repos.d/ganesha.repo && \ - echo "enabled=1" >> /etc/yum.repos.d/ganesha.repo +# NFS-Ganesha repo +RUN set -eux; \ + { \ + printf '%s\n' '[ganesha]'; \ + printf '%s\n' 'name=ganesha'; \ + printf '%s\n' "baseurl=${GANESHA_REPO_BASEURL}"; \ + printf '%s\n' 'gpgcheck=0'; \ + printf '%s\n' 'enabled=1'; \ + } > /etc/yum.repos.d/ganesha.repo # ISCSI repo -RUN set -ex && \ - curl -s -L https://shaman.ceph.com/api/repos/tcmu-runner/main/latest/centos/9/repo?arch=$(arch) -o /etc/yum.repos.d/tcmu-runner.repo && \ +RUN set -eux && \ + source /etc/ceph-distro.env && \ + curl -s -L https://shaman.ceph.com/api/repos/tcmu-runner/main/latest/${DIST_PATH}/repo?arch=$(arch) -o /etc/yum.repos.d/tcmu-runner.repo && \ case "${CEPH_REF}" in \ quincy|reef) \ - curl -fs -L https://download.ceph.com/ceph-iscsi/3/rpm/el9/ceph-iscsi.repo -o /etc/yum.repos.d/ceph-iscsi.repo ;\ + curl -fs -L https://download.ceph.com/ceph-iscsi/3/rpm/${EL_VER}/ceph-iscsi.repo -o /etc/yum.repos.d/ceph-iscsi.repo ;\ ;;\ main|*) \ - curl -fs -L https://shaman.ceph.com/api/repos/ceph-iscsi/main/latest/centos/9/repo -o /etc/yum.repos.d/ceph-iscsi.repo ;\ + curl -fs -L https://shaman.ceph.com/api/repos/ceph-iscsi/main/latest/${DIST_PATH}/repo -o /etc/yum.repos.d/ceph-iscsi.repo ;\ ;;\ esac # Ceph repo RUN --mount=type=secret,id=prerelease_creds set -ex && \ + source /etc/ceph-distro.env && \ if [ "$CUSTOM_CEPH_REPO_URL" ]; then \ curl -L -o /tmp/custom-ceph.repo "$CUSTOM_CEPH_REPO_URL" && \ mv /tmp/custom-ceph.repo /etc/yum.repos.d/custom-ceph.repo && \ @@ -97,13 +118,22 @@ RUN --mount=type=secret,id=prerelease_creds set -ex && \ IS_RELEASE=0 ;\ if [[ "${CI_CONTAINER}" == "true" ]] ; then \ # TODO: this can return different ceph builds (SHA1) for x86 vs. arm runs. is it important to fix? - REPO_URL=$(curl -fs "https://shaman.ceph.com/api/search/?project=ceph&distros=centos/9/${ARCH}&flavor=${OSD_FLAVOR}&ref=${CEPH_REF}&sha1=latest" | jq -r .[0].url) ;\ + REPO_URL=$(curl -fs "https://shaman.ceph.com/api/search/?project=ceph&distros=${DIST_PATH}/${ARCH}&flavor=${OSD_FLAVOR}&ref=${CEPH_REF}&sha1=latest" | jq -r .[0].url) ;\ else \ IS_RELEASE=1 ;\ source /run/secrets/prerelease_creds; \ - REPO_URL="https://${PRERELEASE_USERNAME}:${PRERELEASE_PASSWORD}@download.ceph.com/prerelease/ceph/rpm-${CEPH_REF}/el9/" ;\ + REPO_URL="https://${PRERELEASE_USERNAME}:${PRERELEASE_PASSWORD}@download.ceph.com/prerelease/ceph/rpm-${CEPH_REF}/${EL_VER}/" ;\ fi && \ - rpm -Uvh "$REPO_URL/noarch/ceph-release-1-${IS_RELEASE}.el9.noarch.rpm" ; \ + # Trim trailing slashes + REPO_URL="${REPO_URL%/}" && \ + if [[ "$REPO_URL" == */pulp/content/* ]] ; then \ + # Pulp nests packages under noarch/Packages// + CEPH_RELEASE_RPM="$REPO_URL/noarch/Packages/c/ceph-release-1-${IS_RELEASE}.${EL_VER}.noarch.rpm" ; \ + else \ + # chacra serves packages flat under noarch/ + CEPH_RELEASE_RPM="$REPO_URL/noarch/ceph-release-1-${IS_RELEASE}.${EL_VER}.noarch.rpm" ; \ + fi && \ + rpm -Uvh "$CEPH_RELEASE_RPM" ; \ if [[ "$IS_RELEASE" == 1 ]] ; then \ sed -i "s;http://download.ceph.com/;https://${PRERELEASE_USERNAME}:${PRERELEASE_PASSWORD}@download.ceph.com/prerelease/ceph/;" /etc/yum.repos.d/ceph.repo ; \ dnf clean expire-cache ; \ @@ -113,9 +143,12 @@ RUN --mount=type=secret,id=prerelease_creds set -ex && \ # Copr repos # scikit for mgr-diskprediction-local # ref: https://github.com/ceph/ceph-container/pull/1821 -RUN \ - dnf install -y --setopt=install_weak_deps=False dnf-plugins-core && \ - dnf copr enable -y tchaikov/python-scikit-learn +RUN set -euo pipefail; \ + source /etc/ceph-distro.env; \ + if [ "$MAJOR" -le 9 ]; then \ + dnf install -y --setopt=install_weak_deps=False dnf-plugins-core && \ + dnf copr enable -y tchaikov/python-scikit-learn; \ + fi # Update package mgr RUN dnf update -y --setopt=install_weak_deps=False @@ -136,6 +169,8 @@ ceph-mgr-cephadm \ ceph-mgr-dashboard \ ceph-mgr-diskprediction-local \ ceph-mgr-k8sevents \ +ceph-mgr-modules-core \ +ceph-mgr-modules-standard \ ceph-mgr-rook \ ceph-mgr \ ceph-mon \ @@ -150,13 +185,17 @@ libradosstriper1 \ rbd-mirror" \ >> packages.txt -# Optional crimson package(s) -RUN if [[ "${OSD_FLAVOR}" == "crimson-debug" || "${OSD_FLAVOR}" == "crimson-release" ]]; then \ - echo "ceph-osd-crimson" >> packages.txt ; \ -fi - # Ceph "Recommends" -RUN echo "nvme-cli python3-saml smartmontools" >> packages.txt +RUN set -euo pipefail; \ + echo "nvme-cli smartmontools" >> packages.txt; \ + source /etc/ceph-distro.env; \ + if [ "$MAJOR" -le 9 ]; then \ + echo "python3-saml" >> packages.txt; \ + fi ; \ + if [ "$MAJOR" -ge 10 ]; then \ + echo "python3-ceph-smb-ctl" >> packages.txt; \ + fi + # NFS-Ganesha RUN echo "\ dbus-daemon \ diff --git a/container/build.sh b/container/build.sh index ebfd2263a5a9..d3ce60576499 100755 --- a/container/build.sh +++ b/container/build.sh @@ -16,7 +16,7 @@ usage() { $0 [containerfile] (defaults to 'Containerfile') For a CI build (from ceph-ci.git, built and pushed to shaman): CI_CONTAINER: must be 'true' -FROM_IMAGE: defaults to quay.io/centos/centos9:stream +FROM_IMAGE: defaults to docker.io/rockylinux/rockylinux:10 FLAVOR (OSD flavor, default or crimson) BRANCH (of Ceph. /) CEPH_SHA1 (of Ceph) @@ -82,17 +82,24 @@ if [[ ${NO_PUSH} != "true" ]] ; then fi if [[ ${CI_CONTAINER} != "true" ]] ; then : "${VERSION:?}"; fi +# set container engine +CONTAINER_ENGINE=${CONTAINER_ENGINE:-podman} +if [[ ${CONTAINER_ENGINE} != "podman" && ${CONTAINER_ENGINE} != "docker" ]]; then + echo "CONTAINER_ENGINE must be 'podman' or 'docker', current: ${CONTAINER_ENGINE}" + exit 1 +fi + # check for valid repo auth (if pushing) repopath=${CONTAINER_REPO_HOSTNAME}/${CONTAINER_REPO_ORGANIZATION}/${CONTAINER_REPO} MINIMAL_IMAGE=${repopath}:minimal-test if [[ ${NO_PUSH} != "true" ]] ; then - podman rmi ${MINIMAL_IMAGE} || true - echo "FROM scratch" | podman build -f - -t ${MINIMAL_IMAGE} - if ! podman push ${MINIMAL_IMAGE} ; then + ${CONTAINER_ENGINE} rmi ${MINIMAL_IMAGE} || true + echo "FROM scratch" | ${CONTAINER_ENGINE} build -f - -t ${MINIMAL_IMAGE} + if ! ${CONTAINER_ENGINE} push ${MINIMAL_IMAGE} ; then echo "Not authenticated to ${repopath}; need docker/podman login?" exit 1 fi - podman rmi ${MINIMAL_IMAGE} | true + ${CONTAINER_ENGINE} rmi ${MINIMAL_IMAGE} | true fi if [[ -z "${CEPH_GIT_REPO}" ]] ; then @@ -106,28 +113,49 @@ fi # BRANCH will be, say, origin/main. remove / BRANCH=${BRANCH##*/} -# podman build only supports secret files. -# This must be removed after podman build +# podman/docker build only supports secret files. +# This must be removed after podman/docker build touch prerelease.secret.txt chmod 600 prerelease.secret.txt echo -e "\ PRERELEASE_USERNAME=${PRERELEASE_USERNAME}\n PRERELEASE_PASSWORD=${PRERELEASE_PASSWORD}\n " > prerelease.secret.txt -podman build --pull=newer --squash -f $CFILE -t build.sh.output \ - --build-arg FROM_IMAGE=${FROM_IMAGE:-quay.io/centos/centos:stream9} \ - --build-arg CEPH_SHA1=${CEPH_SHA1} \ - --build-arg CEPH_GIT_REPO=${CEPH_GIT_REPO} \ - --build-arg CEPH_REF=${BRANCH:-main} \ - --build-arg OSD_FLAVOR=${FLAVOR:-default} \ - --build-arg CI_CONTAINER=${CI_CONTAINER:-default} \ - --build-arg CUSTOM_CEPH_REPO_URL="${CUSTOM_CEPH_REPO_URL}" \ - --secret=id=prerelease_creds,src=./prerelease.secret.txt \ - 2>&1 +CONTAINER_BUILD_ARGS=( + --squash + -f "$CFILE" + -t build.sh.output + --build-arg FROM_IMAGE="${FROM_IMAGE:-docker.io/rockylinux/rockylinux:10}" + --build-arg CEPH_SHA1="${CEPH_SHA1}" + --build-arg CEPH_GIT_REPO="${CEPH_GIT_REPO}" + --build-arg CEPH_REF="${BRANCH:-main}" + --build-arg OSD_FLAVOR="${FLAVOR:-default}" + --build-arg CI_CONTAINER="${CI_CONTAINER:-default}" + --build-arg CUSTOM_CEPH_REPO_URL="${CUSTOM_CEPH_REPO_URL}" + "--secret=id=prerelease_creds,src=./prerelease.secret.txt" +) + +if [[ ${CONTAINER_ENGINE} == "podman" ]]; then + CMD=("${CONTAINER_ENGINE}" build --pull=newer "${CONTAINER_BUILD_ARGS[@]}") + echo "+ ${CMD[*]}" + "${CMD[@]}" 2>&1 +else + CMD=("${CONTAINER_ENGINE}" build --pull "${CONTAINER_BUILD_ARGS[@]}" .) + echo "+ DOCKER_BUILDKIT=1 ${CMD[*]}" + DOCKER_BUILDKIT=1 "${CMD[@]}" 2>&1 +fi rm ./prerelease.secret.txt -image_id=$(podman image ls localhost/build.sh.output --format '{{.ID}}') +# get image id +image_id=$(${CONTAINER_ENGINE} image ls build.sh.output --format '{{.ID}}') +if [[ -z "${image_id}" ]]; then + image_id=$(${CONTAINER_ENGINE} image ls localhost/build.sh.output --format '{{.ID}}' || true) +fi +if [[ -z "${image_id}" ]]; then + echo "ERROR: build.sh.output image not found!" + exit 1 +fi # grab useful image attributes for building the tag # @@ -146,8 +174,8 @@ image_id=$(podman image ls localhost/build.sh.output --format '{{.ID}}') # so that vars will get the output of the first command, newline, output # of the second command # -vars="$(podman inspect -f '{{printf "export CEPH_CONTAINER_ARCH=%v" .Architecture}}' ${image_id}) -$(podman inspect -f '{{range $index, $value := .Config.Env}}export CEPH_CONTAINER_{{$value}}{{println}}{{end}}' ${image_id})" +vars="$(${CONTAINER_ENGINE} inspect -f '{{printf "export CEPH_CONTAINER_ARCH=%v" .Architecture}}' ${image_id}) +$(${CONTAINER_ENGINE} inspect -f '{{range $index, $value := .Config.Env}}export CEPH_CONTAINER_{{$value}}{{println}}{{end}}' ${image_id})" vars="$(echo "${vars}" | grep -v PATH)" eval ${vars} @@ -163,18 +191,36 @@ repopath=${CONTAINER_REPO_HOSTNAME}/${CONTAINER_REPO_ORGANIZATION}/${CONTAINER_R if [[ ${CI_CONTAINER} == "true" ]] ; then # ceph-ci conventions for remote tags: # requires ARCH, BRANCH, CEPH_SHA1, FLAVOR - full_repo_tag=${repopath}:${BRANCH}-${fromtag}-${ARCH}-devel - branch_repo_tag=${repopath}:${BRANCH} - sha1_repo_tag=${repopath}:${CEPH_SHA1} - - # while we have more than just centos9 containers: - # anything that's not gets suffixed with its fromtag - # for the branch and sha1 tags (for example, -rocky-10). - # The default can change when it needs to. + if [[ ${FLAVOR} == "debug" ]]; then + # add -debug suffix to flavor debug builds + full_repo_tag=${repopath}:${BRANCH}-${fromtag}-${ARCH}-devel-${FLAVOR} + branch_repo_tag=${repopath}:${BRANCH}-${FLAVOR} + sha1_repo_tag=${repopath}:${CEPH_SHA1}-${FLAVOR} + else + full_repo_tag=${repopath}:${BRANCH}-${fromtag}-${ARCH}-devel + branch_repo_tag=${repopath}:${BRANCH} + sha1_repo_tag=${repopath}:${CEPH_SHA1} + fi + # The container build tooling is capable of using CentOS 9 and Rocky 10 + # as the FROM_IMAGE base container images. + # In Tentacle, the default/preferred FROM_IMAGE changed to rockylinux-10. + # So we want `podman pull quay.ceph.io/ceph-ci/ceph:tentacle` to get the + # FROM_IMAGE=rockylinux-10 container, NOT the CentOS 9 one. + # And vice versa for ceph:squid. - if [[ "${fromtag}" != "centos-stream9" ]] ; then + if [[ "$BRANCH" == "reef" || "$BRANCH" == "squid" ]]; then + default_fromtag="centos-stream9" + else + default_fromtag="rockylinux-10" + fi + # We set fromtag above by extracting FROM_IMAGE from `podman inspect` + if [[ "${fromtag}" != "${default_fromtag}" ]] ; then branch_repo_tag=${repopath}:${BRANCH}-${fromtag} sha1_repo_tag=${repopath}:${CEPH_SHA1}-${fromtag} + if [[ ${FLAVOR} == "debug" ]]; then + branch_repo_tag=${branch_repo_tag}-${FLAVOR} + sha1_repo_tag=${sha1_repo_tag}-${FLAVOR} + fi fi if [[ "${ARCH}" == "arm64" ]] ; then @@ -182,28 +228,16 @@ if [[ ${CI_CONTAINER} == "true" ]] ; then sha1_repo_tag=${sha1_repo_tag}-arm64 fi - podman tag ${image_id} ${full_repo_tag} - podman tag ${image_id} ${branch_repo_tag} - podman tag ${image_id} ${sha1_repo_tag} - - if [[ (${FLAVOR} == "crimson-debug" || ${FLAVOR} == "crimson-release") && ${ARCH} == "x86_64" ]] ; then - sha1_flavor_repo_tag=${sha1_repo_tag}-${FLAVOR} - podman tag ${image_id} ${sha1_flavor_repo_tag} - if [[ -z "${NO_PUSH}" ]] ; then - podman push ${sha1_flavor_repo_tag} - if [[ ${REMOVE_LOCAL_IMAGES} == "true" ]] ; then - podman rmi -f ${sha1_flavor_repo_tag} - fi - fi - exit - fi + ${CONTAINER_ENGINE} tag ${image_id} ${full_repo_tag} + ${CONTAINER_ENGINE} tag ${image_id} ${branch_repo_tag} + ${CONTAINER_ENGINE} tag ${image_id} ${sha1_repo_tag} if [[ -z "${NO_PUSH}" ]] ; then - podman push ${full_repo_tag} - podman push ${branch_repo_tag} - podman push ${sha1_repo_tag} + ${CONTAINER_ENGINE} push ${full_repo_tag} + ${CONTAINER_ENGINE} push ${branch_repo_tag} + ${CONTAINER_ENGINE} push ${sha1_repo_tag} if [[ ${REMOVE_LOCAL_IMAGES} == "true" ]] ; then - podman rmi -f ${full_repo_tag} ${branch_repo_tag} ${sha1_repo_tag} + ${CONTAINER_ENGINE} rmi -f ${full_repo_tag} ${branch_repo_tag} ${sha1_repo_tag} fi fi else @@ -213,12 +247,11 @@ else # version_tag=${repopath}:v${VERSION}-${builddate} - podman tag ${image_id} ${version_tag} + ${CONTAINER_ENGINE} tag ${image_id} ${version_tag} if [[ -z "${NO_PUSH}" ]] ; then - podman push ${version_tag} + ${CONTAINER_ENGINE} push ${version_tag} if [[ ${REMOVE_LOCAL_IMAGES} == "true" ]] ; then - podman rmi -f ${version_tag} + ${CONTAINER_ENGINE} rmi -f ${version_tag} fi fi -fi - +fi \ No newline at end of file diff --git a/container/make-manifest-list.py b/container/make-manifest-list.py index 27b00cc47776..0893f73ebfc3 100755 --- a/container/make-manifest-list.py +++ b/container/make-manifest-list.py @@ -77,14 +77,17 @@ def run_command_show_failure(args): @functools.lru_cache -def get_tags(path): +def get_tags(path, version=None): cmdout = get_command_output(f'skopeo list-tags docker://{path}') - return json.loads(cmdout)['Tags'] + alltags = json.loads(cmdout)['Tags'] + if version is None: + return alltags + return [t for t in alltags if t.startswith(version)] -def get_latest_tag(path): +def get_latest_tag(path, version): try: - latest_tag = get_tags(path)[-1] + latest_tag = get_tags(path, version)[-1] except IndexError: return None return latest_tag @@ -121,13 +124,13 @@ def get_all_matching_digest_tags(path, tag): def parse_args(): ap = argparse.ArgumentParser() - ap.add_argument('-n', '--dry-run', action='store_true', help='do all local manipulations but do not push final containers to MANIFEST_HOST, or in --promote, calculate but do not copy images to release host') - ap.add_argument('-P', '--promote', action='store_true', help='promote newest prerelease manifest container to released (move from MANIFEST_HOST to RELEASE_MANIFEST_HOST') + ap.add_argument('--dry-run', '-n', action='store_true', help='do all local manipulations but do not push final containers to MANIFEST_HOST, or in --promote, calculate but do not copy images to release host') + ap.add_argument('--promote', '-P', action='store_true', help='promote newest prerelease manifest container to released (move from MANIFEST_HOST to RELEASE_MANIFEST_HOST') + ap.add_argument('--version', '-v', required=True, help='operate on this version (leading string of container tag, like v20.2.0)') args = ap.parse_args() return args def build_prerelease(sysargs): - global args arch_specific_host = os.environ.get('ARCH_SPECIFIC_HOST', 'quay.ceph.io') amd64_repo = os.environ.get('AMD64_REPO', 'ceph/prerelease-amd64') @@ -147,7 +150,14 @@ def build_prerelease(sysargs): f'{arch_specific_host}/{amd64_repo}', f'{arch_specific_host}/{arm64_repo}', ) - tags = [get_latest_tag(p) for p in repopaths] + tags = list() + for p in repopaths: + latest = get_latest_tag(p, sysargs.version) + if latest is None: + print(f'no {sysargs.version} tag in {p}', file=sys.stderr) + return(1) + tags.append(latest) + print(f'latest tags: amd64:{tags[0]} arm64:{tags[1]}') # check that version of latest tag matches @@ -218,7 +228,7 @@ def promote(sysargs): manifest_path = f'{manifest_host}/{manifest_repo}' release_path = f'{release_manifest_host}/{release_manifest_repo}' - latest_tag = get_latest_tag(manifest_path) + latest_tag = get_latest_tag(manifest_path, sysargs.version) all_tags = get_all_matching_digest_tags(manifest_path, latest_tag) copypaths = list() @@ -241,6 +251,8 @@ def promote(sysargs): def main(): args = parse_args() + if args.version[0] != 'v': + args.version = f'v{args.version}' if args.promote: promote(args) diff --git a/debian/ceph-base.prerm b/debian/ceph-base.prerm deleted file mode 100644 index 12e5da7d6331..000000000000 --- a/debian/ceph-base.prerm +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -# vim: set noet ts=8: - -set -e - -case "$1" in - remove) - invoke-rc.d ceph stop || { - RESULT=$? - if [ $RESULT != 100 ]; then - exit $RESULT - fi - } - ;; - - *) - ;; -esac - -#DEBHELPER# - -exit 0 diff --git a/debian/ceph-common.install b/debian/ceph-common.install index d6e3db774568..8941d5ed38cb 100755 --- a/debian/ceph-common.install +++ b/debian/ceph-common.install @@ -10,17 +10,21 @@ usr/bin/ceph usr/bin/ceph-authtool usr/bin/ceph-conf usr/bin/ceph-dencoder +usr/bin/ceph-diff-sorted usr/bin/ceph-rbdnamer usr/bin/ceph-syn usr/bin/cephfs-data-scan usr/bin/cephfs-journal-tool usr/bin/cephfs-table-tool +usr/bin/cephfs-tool usr/bin/crushdiff usr/bin/rados usr/bin/radosgw-admin usr/bin/rgw-gap-list usr/bin/rgw-gap-list-comparator usr/bin/rgw-orphan-list +usr/bin/rgw-policy-check +usr/bin/rgw-policy-test usr/bin/rgw-restore-bucket-index usr/bin/rbd usr/bin/rbdmap @@ -33,6 +37,7 @@ usr/lib/ceph/crypto/* [amd64] usr/share/man/man8/ceph-authtool.8 usr/share/man/man8/ceph-conf.8 usr/share/man/man8/ceph-dencoder.8 +usr/share/man/man8/ceph-diff-sorted.8 usr/share/man/man8/ceph-rbdnamer.8 usr/share/man/man8/ceph-syn.8 usr/share/man/man8/ceph-post-file.8 @@ -42,6 +47,10 @@ usr/share/man/man8/mount.ceph.8 usr/share/man/man8/rados.8 usr/share/man/man8/radosgw-admin.8 usr/share/man/man8/rgw-policy-check.8 +usr/share/man/man8/rgw-policy-test.8 +usr/share/man/man8/rgw-gap-list.8 +usr/share/man/man8/rgw-orphan-list.8 +usr/share/man/man8/rgw-restore-bucket-index.8 usr/share/man/man8/rbd.8 usr/share/man/man8/rbdmap.8 usr/share/man/man8/rbd-replay*.8 diff --git a/debian/ceph-mds.prerm b/debian/ceph-mds.prerm deleted file mode 100644 index 51f30d7f98e1..000000000000 --- a/debian/ceph-mds.prerm +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -# vim: set noet ts=8: - -set -e - -case "$1" in - remove) - invoke-rc.d ceph stop mds || { - RESULT=$? - if [ $RESULT != 100 ]; then - exit $RESULT - fi - } - ;; - - *) - ;; -esac - -#DEBHELPER# - -exit 0 diff --git a/debian/ceph-mgr-alerts.install b/debian/ceph-mgr-alerts.install new file mode 100644 index 000000000000..c49b4e7d778f --- /dev/null +++ b/debian/ceph-mgr-alerts.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/alerts diff --git a/debian/ceph-mgr-alerts.postinst b/debian/ceph-mgr-alerts.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-alerts.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-cephadm.requires b/debian/ceph-mgr-cephadm.requires index ec2e22b83691..06766350a949 100644 --- a/debian/ceph-mgr-cephadm.requires +++ b/debian/ceph-mgr-cephadm.requires @@ -1,4 +1,6 @@ CherryPy asyncssh +bcrypt cryptography Jinja2 +pyOpenSSL diff --git a/debian/ceph-mgr-cli-api.install b/debian/ceph-mgr-cli-api.install new file mode 100644 index 000000000000..882f9512aa93 --- /dev/null +++ b/debian/ceph-mgr-cli-api.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/cli_api diff --git a/debian/ceph-mgr-cli-api.postinst b/debian/ceph-mgr-cli-api.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-cli-api.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-influx.install b/debian/ceph-mgr-influx.install new file mode 100644 index 000000000000..921bc04ea2f1 --- /dev/null +++ b/debian/ceph-mgr-influx.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/influx diff --git a/debian/ceph-mgr-influx.postinst b/debian/ceph-mgr-influx.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-influx.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-insights.install b/debian/ceph-mgr-insights.install new file mode 100644 index 000000000000..ad6296ed487c --- /dev/null +++ b/debian/ceph-mgr-insights.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/insights diff --git a/debian/ceph-mgr-insights.postinst b/debian/ceph-mgr-insights.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-insights.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-iostat.install b/debian/ceph-mgr-iostat.install new file mode 100644 index 000000000000..dc0c7c936cc8 --- /dev/null +++ b/debian/ceph-mgr-iostat.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/iostat diff --git a/debian/ceph-mgr-iostat.postinst b/debian/ceph-mgr-iostat.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-iostat.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-localpool.install b/debian/ceph-mgr-localpool.install new file mode 100644 index 000000000000..a99b0fadc75e --- /dev/null +++ b/debian/ceph-mgr-localpool.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/localpool diff --git a/debian/ceph-mgr-localpool.postinst b/debian/ceph-mgr-localpool.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-localpool.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-mds-autoscaler.install b/debian/ceph-mgr-mds-autoscaler.install new file mode 100644 index 000000000000..bacecd47778a --- /dev/null +++ b/debian/ceph-mgr-mds-autoscaler.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/mds_autoscaler diff --git a/debian/ceph-mgr-mds-autoscaler.postinst b/debian/ceph-mgr-mds-autoscaler.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-mds-autoscaler.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-mirroring.install b/debian/ceph-mgr-mirroring.install new file mode 100644 index 000000000000..1229957d5ea7 --- /dev/null +++ b/debian/ceph-mgr-mirroring.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/mirroring diff --git a/debian/ceph-mgr-mirroring.postinst b/debian/ceph-mgr-mirroring.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-mirroring.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-modules-core.install b/debian/ceph-mgr-modules-core.install index 5d1e35204fc2..b5927c1763c1 100644 --- a/debian/ceph-mgr-modules-core.install +++ b/debian/ceph-mgr-modules-core.install @@ -1,26 +1,10 @@ -usr/share/ceph/mgr/alerts usr/share/ceph/mgr/balancer usr/share/ceph/mgr/crash usr/share/ceph/mgr/devicehealth -usr/share/ceph/mgr/influx -usr/share/ceph/mgr/insights -usr/share/ceph/mgr/iostat -usr/share/ceph/mgr/localpool -usr/share/ceph/mgr/mirroring -usr/share/ceph/mgr/nfs usr/share/ceph/mgr/orchestrator -usr/share/ceph/mgr/osd_perf_query -usr/share/ceph/mgr/osd_support usr/share/ceph/mgr/pg_autoscaler usr/share/ceph/mgr/progress -usr/share/ceph/mgr/prometheus usr/share/ceph/mgr/rbd_support -usr/share/ceph/mgr/rgw -usr/share/ceph/mgr/selftest -usr/share/ceph/mgr/snap_schedule -usr/share/ceph/mgr/stats usr/share/ceph/mgr/status -usr/share/ceph/mgr/telegraf usr/share/ceph/mgr/telemetry -usr/share/ceph/mgr/test_orchestrator usr/share/ceph/mgr/volumes diff --git a/debian/ceph-mgr-modules-core.requires b/debian/ceph-mgr-modules-core.requires index 07769e866f88..91ec889083e3 100644 --- a/debian/ceph-mgr-modules-core.requires +++ b/debian/ceph-mgr-modules-core.requires @@ -1,5 +1,3 @@ natsort -CherryPy -packaging requests python-dateutil diff --git a/debian/ceph-mgr-nfs.install b/debian/ceph-mgr-nfs.install new file mode 100644 index 000000000000..d4063e9ed108 --- /dev/null +++ b/debian/ceph-mgr-nfs.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/nfs diff --git a/debian/ceph-mgr-nfs.postinst b/debian/ceph-mgr-nfs.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-nfs.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-nvmeof.install b/debian/ceph-mgr-nvmeof.install new file mode 100644 index 000000000000..5d330c85e814 --- /dev/null +++ b/debian/ceph-mgr-nvmeof.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/nvmeof diff --git a/debian/ceph-mgr-nvmeof.postinst b/debian/ceph-mgr-nvmeof.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-nvmeof.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-osd-perf-query.install b/debian/ceph-mgr-osd-perf-query.install new file mode 100644 index 000000000000..fe19e8f480ab --- /dev/null +++ b/debian/ceph-mgr-osd-perf-query.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/osd_perf_query diff --git a/debian/ceph-mgr-osd-perf-query.postinst b/debian/ceph-mgr-osd-perf-query.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-osd-perf-query.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-osd-support.install b/debian/ceph-mgr-osd-support.install new file mode 100644 index 000000000000..0d1231afbe6a --- /dev/null +++ b/debian/ceph-mgr-osd-support.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/osd_support diff --git a/debian/ceph-mgr-osd-support.postinst b/debian/ceph-mgr-osd-support.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-osd-support.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-prometheus.install b/debian/ceph-mgr-prometheus.install new file mode 100644 index 000000000000..fde2a6e22573 --- /dev/null +++ b/debian/ceph-mgr-prometheus.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/prometheus diff --git a/debian/ceph-mgr-prometheus.postinst b/debian/ceph-mgr-prometheus.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-prometheus.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-rgw.install b/debian/ceph-mgr-rgw.install new file mode 100644 index 000000000000..44b5ffaa18b1 --- /dev/null +++ b/debian/ceph-mgr-rgw.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/rgw diff --git a/debian/ceph-mgr-rgw.postinst b/debian/ceph-mgr-rgw.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-rgw.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-selftest.install b/debian/ceph-mgr-selftest.install new file mode 100644 index 000000000000..936d2fc8a67c --- /dev/null +++ b/debian/ceph-mgr-selftest.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/selftest diff --git a/debian/ceph-mgr-selftest.postinst b/debian/ceph-mgr-selftest.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-selftest.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-smb.install b/debian/ceph-mgr-smb.install new file mode 100644 index 000000000000..64b29016cc4d --- /dev/null +++ b/debian/ceph-mgr-smb.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/smb diff --git a/debian/ceph-mgr-smb.postinst b/debian/ceph-mgr-smb.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-smb.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-snap-schedule.install b/debian/ceph-mgr-snap-schedule.install new file mode 100644 index 000000000000..1ca15ab08346 --- /dev/null +++ b/debian/ceph-mgr-snap-schedule.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/snap_schedule diff --git a/debian/ceph-mgr-snap-schedule.postinst b/debian/ceph-mgr-snap-schedule.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-snap-schedule.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-stats.install b/debian/ceph-mgr-stats.install new file mode 100644 index 000000000000..c4169a633af6 --- /dev/null +++ b/debian/ceph-mgr-stats.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/stats diff --git a/debian/ceph-mgr-stats.postinst b/debian/ceph-mgr-stats.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-stats.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-telegraf.install b/debian/ceph-mgr-telegraf.install new file mode 100644 index 000000000000..c215974ece5f --- /dev/null +++ b/debian/ceph-mgr-telegraf.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/telegraf diff --git a/debian/ceph-mgr-telegraf.postinst b/debian/ceph-mgr-telegraf.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-telegraf.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr-test-orchestrator.install b/debian/ceph-mgr-test-orchestrator.install new file mode 100644 index 000000000000..bd3b9a25ee13 --- /dev/null +++ b/debian/ceph-mgr-test-orchestrator.install @@ -0,0 +1 @@ +usr/share/ceph/mgr/test_orchestrator diff --git a/debian/ceph-mgr-test-orchestrator.postinst b/debian/ceph-mgr-test-orchestrator.postinst new file mode 100644 index 000000000000..78ec769b4ad3 --- /dev/null +++ b/debian/ceph-mgr-test-orchestrator.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + deb-systemd-invoke try-restart ceph-mgr.target + ;; +esac + +#DEBHELPER# diff --git a/debian/ceph-mgr.install b/debian/ceph-mgr.install index 11a4a9ce4e2a..803dcf6bcd8f 100644 --- a/debian/ceph-mgr.install +++ b/debian/ceph-mgr.install @@ -3,3 +3,4 @@ usr/bin/ceph-mgr usr/share/ceph/mgr/mgr_module.* usr/share/ceph/mgr/mgr_util.* usr/share/ceph/mgr/object_format.* +usr/share/ceph/mgr/cherrypy_mgr.* diff --git a/debian/ceph-mgr.prerm b/debian/ceph-mgr.prerm deleted file mode 100644 index 5e4bf42c2dda..000000000000 --- a/debian/ceph-mgr.prerm +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -# vim: set noet ts=8: - -set -e - -case "$1" in - remove) - invoke-rc.d ceph stop mgr || { - RESULT=$? - if [ $RESULT != 100 ]; then - exit $RESULT - fi - } - ;; - - *) - ;; -esac - -#DEBHELPER# - -exit 0 diff --git a/debian/ceph-mon-client-nvmeof.install b/debian/ceph-mon-client-nvmeof.install new file mode 100644 index 000000000000..6e6606db8c39 --- /dev/null +++ b/debian/ceph-mon-client-nvmeof.install @@ -0,0 +1 @@ +usr/bin/ceph-nvmeof-monitor-client diff --git a/debian/ceph-mon.prerm b/debian/ceph-mon.prerm deleted file mode 100644 index a31fc3c21842..000000000000 --- a/debian/ceph-mon.prerm +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -# vim: set noet ts=8: - -set -e - -case "$1" in - remove) - invoke-rc.d ceph stop mon || { - RESULT=$? - if [ $RESULT != 100 ]; then - exit $RESULT - fi - } - ;; - - *) - ;; -esac - -#DEBHELPER# - -exit 0 diff --git a/debian/ceph-osd.prerm b/debian/ceph-osd.prerm deleted file mode 100644 index 93c459614e44..000000000000 --- a/debian/ceph-osd.prerm +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -# vim: set noet ts=8: - -set -e - -case "$1" in - remove) - invoke-rc.d ceph stop osd || { - RESULT=$? - if [ $RESULT != 100 ]; then - exit $RESULT - fi - } - ;; - - *) - ;; -esac - -#DEBHELPER# - -exit 0 diff --git a/debian/ceph-test.install b/debian/ceph-test.install index 454b25c86ffd..424fd0cb4198 100644 --- a/debian/ceph-test.install +++ b/debian/ceph-test.install @@ -10,7 +10,6 @@ usr/bin/ceph_perf_msgr_client usr/bin/ceph_perf_msgr_server usr/bin/ceph_perf_objectstore usr/bin/ceph_psim -usr/bin/ceph_radosacl usr/bin/ceph_rgw_jsonparser usr/bin/ceph_rgw_multiparser usr/bin/ceph_scratchtool diff --git a/debian/cephadm.postinst b/debian/cephadm.postinst index b586ee7183d7..f01e7430cc91 100644 --- a/debian/cephadm.postinst +++ b/debian/cephadm.postinst @@ -41,6 +41,12 @@ case "$1" in usermod -U cephadm fi + # Older versions may not have configured a home directory. + # If they don't have one configured then add it. + if ! test ~cephadm = "/nonexistent"; then + usermod --home /var/lib/cephadm -m cephadm + fi + # set up (initially empty) .ssh/authorized_keys file if ! test -d ~cephadm/.ssh; then mkdir ~cephadm/.ssh diff --git a/debian/cephfs-top.install b/debian/cephfs-top.install index 930396b0c68f..ca08175b5e06 100644 --- a/debian/cephfs-top.install +++ b/debian/cephfs-top.install @@ -1,2 +1,3 @@ usr/bin/cephfs-top usr/lib/python3*/dist-packages/cephfs_top-*.egg-info +usr/share/man/man8/cephfs-top.8 diff --git a/debian/control b/debian/control index 9b4ade7e336c..ef61b7f025b0 100644 --- a/debian/control +++ b/debian/control @@ -21,6 +21,7 @@ Build-Depends: automake, golang, gperf, g++ (>= 11), + iproute2 , javahelper, jq , jsonnet , @@ -48,6 +49,7 @@ Build-Depends: automake, libhwloc-dev , libibverbs-dev, libicu-dev, + libjerasure-dev, librdmacm-dev, libkeyutils-dev, libldap2-dev, @@ -71,20 +73,16 @@ Build-Depends: automake, libxml2-dev, librabbitmq-dev, libre2-dev, + libgrpc++-dev, + protobuf-compiler-grpc, libutf8proc-dev (>= 2.2.0), - librdkafka-dev, + librdkafka-dev (>= 2.11) , + libsasl2-dev , libthrift-dev (>= 0.13.0), libyaml-cpp-dev (>= 0.6), libzstd-dev , - libxmlsec1 , - libxmlsec1-nss , - libxmlsec1-openssl , - libxmlsec1-dev , - libdaxctl-dev (>= 63) , - libndctl-dev (>= 63) , - libpmem-dev , libpmemobj-dev (>= 1.8) , - libprotobuf-dev , + libprotobuf-dev, libxsimd-dev , ninja-build, nlohmann-json3-dev, @@ -109,7 +107,9 @@ Build-Depends: automake, python3-onelogin-saml2 , python3-jinja2, python3-markupsafe, + python3-pip, python3-setuptools, + python3-wheel, python3-sphinx, python3-venv, python3-yaml, @@ -141,6 +141,7 @@ Package: ceph-base Architecture: linux-any Depends: binutils, ceph-common (= ${binary:Version}), + libjerasure2, logrotate, parted, psmisc, @@ -242,11 +243,30 @@ Depends: ceph-base (= ${binary:Version}), ${misc:Depends}, ${python3:Depends}, ${shlibs:Depends}, -Recommends: ceph-mgr-dashboard, +Recommends: ceph-mgr-alerts, + ceph-mgr-cephadm, + ceph-mgr-cli-api, + ceph-mgr-dashboard, ceph-mgr-diskprediction-local, + ceph-mgr-influx, + ceph-mgr-insights, + ceph-mgr-iostat, ceph-mgr-k8sevents, - ceph-mgr-cephadm -Suggests: python3-influxdb + ceph-mgr-localpool, + ceph-mgr-mds-autoscaler, + ceph-mgr-mirroring, + ceph-mgr-nfs, + ceph-mgr-nvmeof, + ceph-mgr-osd-perf-query, + ceph-mgr-osd-support, + ceph-mgr-prometheus, + ceph-mgr-rgw, + ceph-mgr-selftest, + ceph-mgr-smb, + ceph-mgr-snap-schedule, + ceph-mgr-stats, + ceph-mgr-telegraf, + ceph-mgr-test-orchestrator Replaces: ceph (<< 0.93-417), Breaks: ceph (<< 0.93-417), Description: manager for the ceph distributed storage system @@ -260,6 +280,7 @@ Description: manager for the ceph distributed storage system Package: ceph-mgr-dashboard Architecture: all Depends: ceph-mgr (= ${binary:Version}), + ceph-mgr-smb (= ${binary:Version}), ${python3:Depends} Description: dashboard module for ceph-mgr Ceph is a massively scalable, open-source, distributed @@ -287,7 +308,8 @@ Description: diskprediction-local module for ceph-mgr Package: ceph-mgr-modules-core Architecture: all -Depends: ${misc:Depends}, +Depends: python3-prettytable, + ${misc:Depends}, ${python3:Depends}, Replaces: ceph-mgr (<< 15.1.0) Breaks: ceph-mgr (<< 15.1.0) @@ -299,9 +321,43 @@ Description: ceph manager modules which are always enabled This package contains a set of core ceph-mgr modules which are always enabled. +Package: ceph-mgr-modules-standard +Architecture: all +Depends: ceph-mgr-modules-core (= ${binary:Version}), + ceph-mgr-alerts (= ${binary:Version}), + ceph-mgr-influx (= ${binary:Version}), + ceph-mgr-insights (= ${binary:Version}), + ceph-mgr-iostat (= ${binary:Version}), + ceph-mgr-localpool (= ${binary:Version}), + ceph-mgr-mds-autoscaler (= ${binary:Version}), + ceph-mgr-mirroring (= ${binary:Version}), + ceph-mgr-nfs (= ${binary:Version}), + ceph-mgr-nvmeof (= ${binary:Version}), + ceph-mgr-osd-perf-query (= ${binary:Version}), + ceph-mgr-osd-support (= ${binary:Version}), + ceph-mgr-prometheus (= ${binary:Version}), + ceph-mgr-rgw (= ${binary:Version}), + ceph-mgr-selftest (= ${binary:Version}), + ceph-mgr-smb (= ${binary:Version}), + ceph-mgr-snap-schedule (= ${binary:Version}), + ceph-mgr-stats (= ${binary:Version}), + ceph-mgr-telegraf (= ${binary:Version}), + ceph-mgr-test-orchestrator (= ${binary:Version}), + ${misc:Depends}, +Description: Ceph Manager modules without heavy external dependencies + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This meta-package has no files of its own. It pulls in the full set of + ceph-mgr modules that were formerly shipped together in + ceph-mgr-modules-core, so that existing users or scripts that want the + complete standard module set can depend on a single package. + Package: ceph-mgr-rook Architecture: all Depends: ceph-mgr (= ${binary:Version}), + ceph-mgr-nfs (= ${binary:Version}), ${misc:Depends}, ${python3:Depends}, ${shlibs:Depends}, @@ -332,7 +388,9 @@ Description: kubernetes events module for ceph-mgr Package: ceph-mgr-cephadm Architecture: all Depends: ceph-mgr (= ${binary:Version}), - cephadm, + ceph-mgr-nfs (= ${binary:Version}), + ceph-mgr-smb (= ${binary:Version}), + cephadm, ${misc:Depends}, ${python3:Depends}, openssh-client, @@ -347,6 +405,307 @@ Description: cephadm orchestrator module for ceph-mgr functionality, to allow ceph-mgr to perform orchestration functions over a standard SSH connection. +Package: ceph-mgr-cli-api +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, +Description: CLI API module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the CLI API module for ceph-mgr, which provides + a REST-like API for the Ceph command-line interface. + +Package: ceph-mgr-alerts +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: alerts module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the alerts module for ceph-mgr, which sends + email notifications on cluster health state changes. + +Package: ceph-mgr-influx +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, +Suggests: python3-influxdb +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: influx module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the influx module for ceph-mgr, which sends + performance metrics to an InfluxDB time-series database. + +Package: ceph-mgr-insights +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: insights module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the insights module for ceph-mgr, which records + cluster health history to support cluster analysis. + +Package: ceph-mgr-iostat +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: iostat module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the iostat module for ceph-mgr, which displays + a running summary of I/O statistics across the cluster. + +Package: ceph-mgr-localpool +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: localpool module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the localpool module for ceph-mgr, which + automatically creates per-host CRUSH rules and pools. + +Package: ceph-mgr-mds-autoscaler +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: mds_autoscaler module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the mds_autoscaler module for ceph-mgr, which + automatically scales the number of MDS daemons based on file system needs. + +Package: ceph-mgr-mirroring +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: mirroring module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the mirroring module for ceph-mgr, which + provides management commands for CephFS mirroring. + +Package: ceph-mgr-nfs +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: nfs module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the nfs module for ceph-mgr, which manages + NFS gateway deployments on top of CephFS and RGW. + +Package: ceph-mgr-nvmeof +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: nvmeof module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the nvmeof module for ceph-mgr, which manages + NVMe-oF gateway deployments for Ceph RBD. + +Package: ceph-mgr-osd-perf-query +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + python3-prettytable, + ${misc:Depends}, + ${python3:Depends}, +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: osd_perf_query module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the osd_perf_query module for ceph-mgr, which + exposes OSD performance counter query functionality. + +Package: ceph-mgr-osd-support +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: osd_support module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the osd_support module for ceph-mgr, which + provides additional OSD management commands. + +Package: ceph-mgr-prometheus +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + python3-cherrypy3, + ${misc:Depends}, + ${python3:Depends}, +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: prometheus module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the prometheus module for ceph-mgr, which + exposes cluster metrics in Prometheus exposition format. + +Package: ceph-mgr-rgw +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: rgw module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the rgw module for ceph-mgr, which provides + management and status commands for the RADOS Gateway. + +Package: ceph-mgr-selftest +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: selftest module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the selftest module for ceph-mgr, used for + testing the manager framework. + +Package: ceph-mgr-smb +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: smb module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the smb module for ceph-mgr, which manages + SMB gateway deployments on Ceph. + +Package: ceph-mgr-snap-schedule +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: snap_schedule module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the snap_schedule module for ceph-mgr, which + manages automated CephFS snapshot schedules. + +Package: ceph-mgr-stats +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: stats module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the stats module for ceph-mgr, which exposes + file system client I/O statistics. + +Package: ceph-mgr-telegraf +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: telegraf module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the telegraf module for ceph-mgr, which sends + performance metrics to a Telegraf agent. + +Package: ceph-mgr-test-orchestrator +Architecture: all +Depends: ceph-mgr (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, +Breaks: ceph-mgr-modules-core (<< 21.0.0) +Replaces: ceph-mgr-modules-core (<< 21.0.0) +Description: test_orchestrator module for ceph-mgr + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the test_orchestrator module for ceph-mgr, used + for testing the orchestrator framework. + Package: ceph-mgr-dbg Architecture: linux-any Section: debug @@ -414,9 +773,37 @@ Description: debugging symbols for ceph-mon . This package contains the debugging symbols for ceph-mon. +Package: ceph-mon-client-nvmeof +Architecture: linux-any +Depends: librados2 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Description: NVMe-oF Gateway Monitor Client for Ceph + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the NVMe-oF Gateway Monitor Client. It distributes + Paxos ANA info to the NVMe-oF Gateway and provides beacons to the + ceph-mon daemon. + +Package: ceph-mon-client-nvmeof-dbg +Architecture: linux-any +Section: debug +Priority: extra +Depends: ceph-mon-client-nvmeof (= ${binary:Version}), + ${misc:Depends}, +Description: debugging symbols for ceph-mon-client-nvmeof + Ceph is a massively scalable, open-source, distributed + storage system that runs on commodity hardware and delivers object, + block and file system storage. + . + This package contains the debugging symbols for ceph-mon-client-nvmeof. + Package: ceph-osd Architecture: linux-any -Depends: ceph-osd-classic (= ${binary:Version}) | ceph-osd-crimson (= ${binary:Version}), +Depends: ceph-osd-classic (= ${binary:Version}), + ceph-osd-crimson (= ${binary:Version}) , sudo, ${python3:Depends}, ${misc:Depends}, @@ -450,16 +837,16 @@ Package: ceph-osd-classic Architecture: linux-any Depends: ceph-base (= ${binary:Version}), ${misc:Depends}, - ${shlibs:Depends}, + ${shlibs:Depends} +Conflicts: ceph-osd (<< 20.3) Replaces: ceph (<< 10), ceph-test (<< 12.2.2-14), - ceph-osd (<< 20.1.1) + ceph-osd (<< 20.3) Breaks: ceph (<< 10), - ceph-test (<< 12.2.2-14), - ceph-osd (<< 20.1.1) + ceph-test (<< 12.2.2-14) Recommends: ceph-volume (= ${binary:Version}), nvme-cli, - smartmontools, + smartmontools Description: Classic OSD server for the ceph storage system Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -489,10 +876,11 @@ Architecture: any Depends: ceph-base (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends}, - libprotobuf23, Recommends: ceph-volume (= ${binary:Version}), nvme-cli, smartmontools, +Conflicts: ceph-osd (<< 20.3) +Replaces: ceph-osd (<< 20.3) Description: Crimson OSD server for the ceph storage system Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -528,6 +916,7 @@ Depends: ceph-osd (= ${binary:Version}), e2fsprogs, lvm2, parted, + python3-packaging, xfsprogs, ${misc:Depends}, ${python3:Depends} diff --git a/debian/copyright b/debian/copyright index 8dc4b9e4f49a..23e4ee2b9bdc 100644 --- a/debian/copyright +++ b/debian/copyright @@ -209,9 +209,8 @@ License: GPL-2 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + You should have received a copy of the GNU General Public License + along with this program. If not, see . . On Debian systems, the complete text of the GNU General Public License version 2 can be found in `/usr/share/common-licenses/GPL-2' file. diff --git a/debian/libradospp-dev.install b/debian/libradospp-dev.install index 749cdd772d6f..0d346e0b6232 100644 --- a/debian/libradospp-dev.install +++ b/debian/libradospp-dev.install @@ -6,3 +6,5 @@ usr/include/rados/librados.hpp usr/include/rados/librados_fwd.hpp usr/include/rados/page.h usr/include/rados/rados_types.hpp +usr/include/rados/cls_flags.hpp +usr/include/rados/cls_traits.hpp diff --git a/debian/py3dist-overrides b/debian/py3dist-overrides index b6358cf123ef..73c20633a7dd 100644 --- a/debian/py3dist-overrides +++ b/debian/py3dist-overrides @@ -1,4 +1,3 @@ cephfs python3-cephfs; PEP386 ceph_argparse python3-ceph-argparse ceph_common python3-ceph-common -distutils python3-distutils diff --git a/debian/python3-cephfs.install b/debian/python3-cephfs.install index 9ac75f5366b4..577236c76a8b 100644 --- a/debian/python3-cephfs.install +++ b/debian/python3-cephfs.install @@ -1,2 +1,2 @@ -usr/lib/python3*/dist-packages/cephfs-*.egg-info +usr/lib/python3*/dist-packages/cephfs-*.dist-info usr/lib/python3*/dist-packages/cephfs.cpython*.so diff --git a/debian/python3-rados.install b/debian/python3-rados.install index 98b5d76cbe7d..84009ee79c58 100644 --- a/debian/python3-rados.install +++ b/debian/python3-rados.install @@ -1,2 +1,2 @@ -usr/lib/python3*/dist-packages/rados-*.egg-info +usr/lib/python3*/dist-packages/rados-*.dist-info usr/lib/python3*/dist-packages/rados.cpython*.so diff --git a/debian/python3-rbd.install b/debian/python3-rbd.install index 5f4e6e143e8b..a447182a56df 100644 --- a/debian/python3-rbd.install +++ b/debian/python3-rbd.install @@ -1,2 +1,2 @@ -usr/lib/python3*/dist-packages/rbd-*.egg-info +usr/lib/python3*/dist-packages/rbd-*.dist-info usr/lib/python3*/dist-packages/rbd.cpython*.so diff --git a/debian/python3-rgw.install b/debian/python3-rgw.install index 57f455907710..bf6678ad79db 100644 --- a/debian/python3-rgw.install +++ b/debian/python3-rgw.install @@ -1,2 +1,2 @@ -usr/lib/python3*/dist-packages/rgw-*.egg-info +usr/lib/python3*/dist-packages/rgw-*.dist-info usr/lib/python3*/dist-packages/rgw.cpython*.so diff --git a/debian/radosgw.install b/debian/radosgw.install index 074f769a181f..603f0248d771 100644 --- a/debian/radosgw.install +++ b/debian/radosgw.install @@ -1,10 +1,7 @@ {usr/,}lib/systemd/system/ceph-radosgw* -usr/bin/ceph-diff-sorted usr/bin/radosgw usr/bin/radosgw-es usr/bin/radosgw-object-expirer usr/bin/radosgw-token usr/share/man/man8/ceph-diff-sorted.8 usr/share/man/man8/radosgw.8 -usr/share/man/man8/rgw-orphan-list.8 -usr/share/man/man8/rgw-restore-bucket-index.8 diff --git a/debian/rules b/debian/rules index 4d31ffd069f3..c4af2e2fe00a 100755 --- a/debian/rules +++ b/debian/rules @@ -18,8 +18,12 @@ endif ifneq ($(filter pkg.ceph.crimson,$(DEB_BUILD_PROFILES)),) extraopts += -DWITH_CRIMSON=ON endif +ifneq ($(filter pkg.ceph.system-rdkafka,$(DEB_BUILD_PROFILES)),) + extraopts += -DWITH_SYSTEM_RDKAFKA=ON +endif extraopts += -DWITH_JAEGER=ON +extraopts += -DWITH_SYSTEM_JERASURE=ON extraopts += -DWITH_SYSTEM_UTF8PROC=ON extraopts += -DWITH_OCF=ON -DWITH_LTTNG=ON extraopts += -DWITH_MGR_DASHBOARD_FRONTEND=OFF @@ -53,6 +57,11 @@ endif ifeq ($(DWZ), false) override_dh_dwz: +else +override_dh_dwz: + # Exclude ceph-osd-crimson, librgw, and radosgw due to excessive debug info (too many DIEs) + dh_dwz -Xceph-osd-crimson -Xlibrgw -Xradosgw + endif # for python3-${pkg} packages @@ -115,6 +124,8 @@ override_dh_strip: dh_strip -pceph-exporter --dbg-package=ceph-exporter-dbg dh_strip -pceph-mon --dbg-package=ceph-mon-dbg dh_strip -pceph-osd --dbg-package=ceph-osd-dbg + dh_strip -pceph-osd-classic --dbg-package=ceph-osd-classic-dbg + dh_strip -pceph-osd-crimson --dbg-package=ceph-osd-crimson-dbg dh_strip -pceph-base --dbg-package=ceph-base-dbg dh_strip -pcephfs-mirror --dbg-package=cephfs-mirror-dbg dh_strip -prbd-fuse --dbg-package=rbd-fuse-dbg diff --git a/do_cmake.sh b/do_cmake.sh index a3b901fb66ac..383272456409 100755 --- a/do_cmake.sh +++ b/do_cmake.sh @@ -19,7 +19,9 @@ if [ -r /etc/os-release ]; then source /etc/os-release case "$ID" in fedora) - if [ "$VERSION_ID" -ge "41" ] ; then + if [ "$VERSION_ID" -ge "43" ] ; then + PYBUILD="3.14" + elif [ "$VERSION_ID" -ge "41" ] ; then PYBUILD="3.13" elif [ "$VERSION_ID" -ge "39" ] ; then PYBUILD="3.12" @@ -45,7 +47,9 @@ if [ -r /etc/os-release ]; then ;; ubuntu) MAJOR_VER=$(echo "$VERSION_ID" | sed -e 's/\..*$//') - if [ "$MAJOR_VER" -ge "24" ] ; then + if [ "$MAJOR_VER" -ge "26" ] ; then + PYBUILD="3.14" + elif [ "$MAJOR_VER" -ge "24" ] ; then PYBUILD="3.12" elif [ "$MAJOR_VER" -ge "22" ] ; then PYBUILD="3.10" diff --git a/doc/_ext/ceph_commands.py b/doc/_ext/ceph_commands.py index d96eab08853f..f86ad94f4cc6 100644 --- a/doc/_ext/ceph_commands.py +++ b/doc/_ext/ceph_commands.py @@ -285,6 +285,14 @@ def mocked_modules(self): # make diskprediction_local happy mock_imports += ['numpy', 'scipy'] + # make cephadm happy + mock_imports += ['cherrypy.process', + 'cherrypy.process.servers', + 'cherrypy._cptree', + 'cheroot', + 'cheroot.wsgi', + 'cheroot.ssl', + 'cheroot.ssl.builtin'] for m in mock_imports: args = {} @@ -316,8 +324,18 @@ def subclass(x): ms = [c for c in mgr_mod.__dict__.values() if subclass(c) and 'Standby' not in c.__name__] [m] = ms - assert isinstance(m.COMMANDS, list) - return m.COMMANDS + + # Modules can define commands in two ways: + # 1. New decorator pattern: Commands registered via @ModuleCLICommand decorators, + # retrieved via CLICommand.dump_cmd_list() + # 2. Old list pattern: Commands defined in a COMMANDS list + # Some modules have CLICommand defined but haven't migrated their commands yet, + # so we try the new pattern first and fall back to the old COMMANDS list. + if hasattr(m, 'CLICommand'): + commands = m.CLICommand.dump_cmd_list() + if commands: + return commands + return getattr(m, 'COMMANDS', []) def _normalize_command(self, command): if 'handler' in command: diff --git a/doc/_ext/ceph_confval.py b/doc/_ext/ceph_confval.py index b997224ce4eb..abd3abaee608 100644 --- a/doc/_ext/ceph_confval.py +++ b/doc/_ext/ceph_confval.py @@ -31,6 +31,7 @@ {{ desc | wordwrap(70) | indent(3) }} {% endif %} :type: ``{{opt.type}}`` + :runtime updatable: ``{{ runtime_updatable | string | lower }}`` {%- if default is not none %} {%- if opt.type == 'size' %} :default: ``{{ default | eval_size | iec_size }}`` @@ -183,6 +184,22 @@ def jinja_template() -> jinja2.Template: FieldValueT = Union[bool, float, int, str] +RUNTIME_UPDATABLE_TYPES = { + 'bool', + 'float', + 'int', + 'millisecs', + 'secs', + 'size', + 'uint', +} + +NON_RUNTIME_FLAGS = { + 'cluster_create', + 'create', + 'startup', +} + class CephModule(SphinxDirective): """ @@ -221,6 +238,10 @@ class CephOption(ObjectDescription): label=_('Default'), has_arg=False, names=('default',)), + Field('runtime_updatable', + label=_('Runtime updatable'), + has_arg=False, + names=('runtime updatable',)), Field('type', label=_('Type'), has_arg=False, @@ -348,6 +369,23 @@ def _current_module(self) -> str: return self.options.get('module', self.env.ref_context.get('ceph:module')) + @staticmethod + def _can_update_at_runtime(opt: Dict[str, FieldValueT], + cur_module: str = '') -> bool: + flags = set(opt.get('flags', [])) + if opt.get('runtime') is True: + flags.add('runtime') + if cur_module: + flags.add('mgr') + # Keep this in sync with src/common/options.h: Option::can_update_at_runtime(). + if flags & NON_RUNTIME_FLAGS: + return False + if 'runtime' in flags: + return True + if 'mgr' in flags: + return False + return opt.get('type') in RUNTIME_UPDATABLE_TYPES + def _render_option(self, name) -> str: cur_module = self._current_module() if cur_module: @@ -366,10 +404,12 @@ def _render_option(self, name) -> str: desc = opt.get('fmt_desc') or opt.get('long_desc') or opt.get('desc') opt_default = opt.get('default') default = self.options.get('default', opt_default) + runtime_updatable = self._can_update_at_runtime(opt, cur_module) try: return self.template.render(opt=opt, desc=desc, - default=default) + default=default, + runtime_updatable=runtime_updatable) except Exception as e: message = (f'Unable to render option "{name}": {e}. ', f'opt={opt}, desc={desc}, default={default}') diff --git a/doc/_ext/ceph_releases.py b/doc/_ext/ceph_releases.py index 481c2a1b6194..abc1f88c1c7c 100644 --- a/doc/_ext/ceph_releases.py +++ b/doc/_ext/ceph_releases.py @@ -191,9 +191,10 @@ def run(self): class CephTimeline(Directive): has_content = False - required_arguments = 4 + required_arguments = 2 optional_arguments = 0 option_spec = {} + final_argument_whitespace = True def run(self): filename = self.arguments[0] @@ -209,7 +210,7 @@ def run(self): "Failed to open Ceph releases file {}: {}".format(filename, e), line=self.lineno)] - display_releases = self.arguments[1:] + display_releases = self.arguments[1].split() timeline = [] for code_name, info in releases["releases"].items(): diff --git a/doc/_static/js/pgcalc.js b/doc/_static/js/pgcalc.js index e13c30895fcf..df6f316d1c6b 100644 --- a/doc/_static/js/pgcalc.js +++ b/doc/_static/js/pgcalc.js @@ -13,107 +13,106 @@ if (!self.__WB_pmw) { self.__WB_pmw = function(obj) { this.__WB_source = obj; re var pow2belowThreshold = 0.25 var key_values={}; key_values['poolName'] ={'name':'Pool Name','default':'newPool','description': 'Name of the pool in question. Typical pool names are included below.', 'width':'30%; text-align: left'}; -key_values['size'] ={'name':'Size','default': 3, 'description': 'Number of replicas the pool will have. Default value of 3 is pre-filled.', 'width':'10%', 'global':1}; -key_values['osdNum'] ={'name':'OSD #','default': 100, 'description': 'Number of OSDs which this Pool will have PGs in. Typically, this is the entire Cluster OSD count, but could be less based on CRUSH rules. (e.g. Separate SSD and SATA disk sets)', 'width':'10%', 'global':1}; +key_values['size'] ={'name':'Size','default': 3, 'description': 'Number of replicas the pool will have. Default value of 3 is pre-filled. For EC pools enter K+M', 'width':'10%', 'global':1}; +key_values['osdNum'] ={'name':'OSD #','default': 200, 'description': 'Number of OSDs hosting this pool. By default this is the entire cluster OSD count, but could be less based on CRUSH rules. (e.g. separate SSD and HDD device classes)', 'width':'10%', 'global':1}; key_values['percData'] ={'name':'%Data', 'default': 5, 'description': 'This value represents the approximate percentage of data which will be contained in this pool for that specific OSD set. Examples are pre-filled below for guidance.','width':'10%'}; -key_values['targPGsPerOSD'] ={'name':'Target PGs per OSD', 'default':100, 'description': 'This value should be populated based on the following guidance:', 'width':'10%', 'global':1, 'options': [ ['100','If the cluster OSD count is not expected to increase in the foreseeable future.'], ['200', 'If the cluster OSD count is expected to increase (up to double the size) in the foreseeable future.']]} +key_values['targPGsPerOSD'] ={'name':'Target PGs per OSD', 'default':200, 'description': 'This value should be populated based on the following guidance:', 'width':'10%', 'global':1, 'options': [ ['200','If the cluster OSD count is not expected to increase in the foreseeable future.'], ['300', 'If the cluster OSD count is expected to increase (up to double the size) in the foreseeable future.']]} var notes ={ - 'totalPerc':'"Total Data Percentage" below table should be a multiple of 100%.', - 'totalPGs':'"Total PG Count" below table will be the count of Primary PG copies. However, when calculating total PGs per OSD average, you must include all copies.', - 'noDecrease':'It\'s also important to know that the PG count can be increased, but NEVER decreased without destroying / recreating the pool. However, increasing the PG Count of a pool is one of the most impactful events in a Ceph Cluster, and should be avoided for production clusters if possible.', + 'totalPerc':'"Total Data Percentage" below should be a multiple of 100%.', + 'totalPGs':'"Total PG Count"in the below table will be the count of primary PGs. However, when calculating target PGs per OSD, you must include all replicas. For an EC pool, the number of replicas here is K+M', }; var presetTables={}; presetTables['All-in-One']=[ - { 'poolName' : 'rbd', 'size' : '3', 'osdNum' : '100', 'percData' : '100', 'targPGsPerOSD' : '100'}, + { 'poolName' : 'rbd', 'size' : '3', 'osdNum' : '100', 'percData' : '200', 'targPGsPerOSD' : '200'}, ]; presetTables['OpenStack']=[ - { 'poolName' : 'cinder-backup', 'size' : '3', 'osdNum' : '100', 'percData' : '25', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'cinder-volumes', 'size' : '3', 'osdNum' : '100', 'percData' : '53', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'ephemeral-vms', 'size' : '3', 'osdNum' : '100', 'percData' : '15', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'glance-images', 'size' : '3', 'osdNum' : '100', 'percData' : '7', 'targPGsPerOSD' : '100'}, + { 'poolName' : 'cinder-backup', 'size' : '3', 'osdNum' : '100', 'percData' : '25', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'cinder-volumes', 'size' : '3', 'osdNum' : '100', 'percData' : '53', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'ephemeral-vms', 'size' : '3', 'osdNum' : '100', 'percData' : '15', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'glance-images', 'size' : '3', 'osdNum' : '100', 'percData' : '7', 'targPGsPerOSD' : '200'}, ]; presetTables['OpenStack w RGW - Jewel and later']=[ - { 'poolName' : '.rgw.root', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.control', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.data.root', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.gc', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.log', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.intent-log', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.meta', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.usage', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.users.keys', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.users.email', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.users.swift', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.users.uid', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.buckets.extra', 'size' : '3', 'osdNum' : '100', 'percData' : '1.0', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.buckets.index', 'size' : '3', 'osdNum' : '100', 'percData' : '3.0', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.buckets.data', 'size' : '3', 'osdNum' : '100', 'percData' : '19', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'cinder-backup', 'size' : '3', 'osdNum' : '100', 'percData' : '18', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'cinder-volumes', 'size' : '3', 'osdNum' : '100', 'percData' : '42.8', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'ephemeral-vms', 'size' : '3', 'osdNum' : '100', 'percData' : '10', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'glance-images', 'size' : '3', 'osdNum' : '100', 'percData' : '5', 'targPGsPerOSD' : '100'}, + { 'poolName' : '.rgw.root', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.control', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.data.root', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.gc', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.log', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.intent-log', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.meta', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.usage', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.users.keys', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.users.email', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.users.swift', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.users.uid', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.buckets.extra', 'size' : '3', 'osdNum' : '100', 'percData' : '1.0', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.buckets.index', 'size' : '3', 'osdNum' : '100', 'percData' : '3.0', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.buckets.data', 'size' : '3', 'osdNum' : '100', 'percData' : '19', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'cinder-backup', 'size' : '3', 'osdNum' : '100', 'percData' : '18', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'cinder-volumes', 'size' : '3', 'osdNum' : '100', 'percData' : '42.8', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'ephemeral-vms', 'size' : '3', 'osdNum' : '100', 'percData' : '10', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'glance-images', 'size' : '3', 'osdNum' : '100', 'percData' : '5', 'targPGsPerOSD' : '200'}, ]; presetTables['Rados Gateway Only - Jewel and later']=[ - { 'poolName' : '.rgw.root', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.control', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.data.root', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.gc', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.log', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.intent-log', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.meta', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.usage', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.users.keys', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.users.email', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.users.swift', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.users.uid', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.buckets.extra', 'size' : '3', 'osdNum' : '100', 'percData' : '1.0', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.buckets.index', 'size' : '3', 'osdNum' : '100', 'percData' : '3.0', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'default.rgw.buckets.data', 'size' : '3', 'osdNum' : '100', 'percData' : '94.8', 'targPGsPerOSD' : '100'}, + { 'poolName' : '.rgw.root', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.control', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.data.root', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.gc', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.log', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.intent-log', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.meta', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.usage', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.users.keys', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.users.email', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.users.swift', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.users.uid', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.buckets.extra', 'size' : '3', 'osdNum' : '100', 'percData' : '1.0', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.buckets.index', 'size' : '3', 'osdNum' : '100', 'percData' : '3.0', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'default.rgw.buckets.data', 'size' : '3', 'osdNum' : '100', 'percData' : '94.8', 'targPGsPerOSD' : '200'}, ]; presetTables['OpenStack w RGW - Infernalis and earlier']=[ - { 'poolName' : '.intent-log', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.log', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.rgw', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.rgw.buckets', 'size' : '3', 'osdNum' : '100', 'percData' : '18', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.rgw.buckets.extra', 'size' : '3', 'osdNum' : '100', 'percData' : '1.0', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.rgw.buckets.index', 'size' : '3', 'osdNum' : '100', 'percData' : '3.0', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.rgw.control', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.rgw.gc', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.rgw.root', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.usage', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.users', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.users.email', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.users.swift', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.users.uid', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'cinder-backup', 'size' : '3', 'osdNum' : '100', 'percData' : '19', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'cinder-volumes', 'size' : '3', 'osdNum' : '100', 'percData' : '42.9', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'ephemeral-vms', 'size' : '3', 'osdNum' : '100', 'percData' : '10', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'glance-images', 'size' : '3', 'osdNum' : '100', 'percData' : '5', 'targPGsPerOSD' : '100'}, + { 'poolName' : '.intent-log', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.log', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.rgw', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.rgw.buckets', 'size' : '3', 'osdNum' : '100', 'percData' : '18', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.rgw.buckets.extra', 'size' : '3', 'osdNum' : '100', 'percData' : '1.0', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.rgw.buckets.index', 'size' : '3', 'osdNum' : '100', 'percData' : '3.0', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.rgw.control', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.rgw.gc', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.rgw.root', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.usage', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.users', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.users.email', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.users.swift', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.users.uid', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'cinder-backup', 'size' : '3', 'osdNum' : '100', 'percData' : '19', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'cinder-volumes', 'size' : '3', 'osdNum' : '100', 'percData' : '42.9', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'ephemeral-vms', 'size' : '3', 'osdNum' : '100', 'percData' : '10', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'glance-images', 'size' : '3', 'osdNum' : '100', 'percData' : '5', 'targPGsPerOSD' : '200'}, ]; presetTables['Rados Gateway Only - Infernalis and earlier']=[ - { 'poolName' : '.intent-log', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.log', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.rgw', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.rgw.buckets', 'size' : '3', 'osdNum' : '100', 'percData' : '94.9', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.rgw.buckets.extra', 'size' : '3', 'osdNum' : '100', 'percData' : '1.0', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.rgw.buckets.index', 'size' : '3', 'osdNum' : '100', 'percData' : '3.0', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.rgw.control', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.rgw.gc', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.rgw.root', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.usage', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.users', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.users.email', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.users.swift', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, - { 'poolName' : '.users.uid', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '100'}, + { 'poolName' : '.intent-log', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.log', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.rgw', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.rgw.buckets', 'size' : '3', 'osdNum' : '100', 'percData' : '94.9', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.rgw.buckets.extra', 'size' : '3', 'osdNum' : '100', 'percData' : '1.0', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.rgw.buckets.index', 'size' : '3', 'osdNum' : '100', 'percData' : '3.0', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.rgw.control', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.rgw.gc', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.rgw.root', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.usage', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.users', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.users.email', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.users.swift', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, + { 'poolName' : '.users.uid', 'size' : '3', 'osdNum' : '100', 'percData' : '0.1', 'targPGsPerOSD' : '200'}, ]; presetTables['RBD and libRados']=[ - { 'poolName' : 'rbd', 'size' : '3', 'osdNum' : '100', 'percData' : '75', 'targPGsPerOSD' : '100'}, - { 'poolName' : 'myObjects', 'size' : '3', 'osdNum' : '100', 'percData' : '25', 'targPGsPerOSD' : '100'}, + { 'poolName' : 'rbd', 'size' : '3', 'osdNum' : '100', 'percData' : '75', 'targPGsPerOSD' : '200'}, + { 'poolName' : 'myObjects', 'size' : '3', 'osdNum' : '100', 'percData' : '25', 'targPGsPerOSD' : '200'}, ]; $(function() { diff --git a/doc/_themes/ceph/layout.html b/doc/_themes/ceph/layout.html index f89edfe371a8..bf6f39b4449b 100644 --- a/doc/_themes/ceph/layout.html +++ b/doc/_themes/ceph/layout.html @@ -138,18 +138,6 @@ {% endif %} - {% if theme_display_version %} - {%- set nav_version = version %} - {% if READTHEDOCS and current_version %} - {%- set nav_version = current_version %} - {% endif %} - {% if nav_version %} -
- {{ nav_version }} -
- {% endif %} - {% endif %} - {% include "searchbox.html" %} {% endblock %} diff --git a/doc/architecture.rst b/doc/architecture.rst index 25beebf037e4..c16aa3db1e7a 100644 --- a/doc/architecture.rst +++ b/doc/architecture.rst @@ -528,7 +528,7 @@ Pools set at least the following parameters: See :ref:`setpoolvalues` for details. -.. index: architecture; placement group mapping +.. index:: architecture; placement group mapping Mapping PGs to OSDs ~~~~~~~~~~~~~~~~~~~ diff --git a/doc/ceph-volume/drive-group.rst b/doc/ceph-volume/drive-group.rst index 4296ba7e9fca..3c3441d8b7a3 100644 --- a/doc/ceph-volume/drive-group.rst +++ b/doc/ceph-volume/drive-group.rst @@ -3,7 +3,7 @@ ``drive-group`` =============== The drive-group subcommand allows for passing :ref:`drivegroups` specifications -straight to ceph-volume as json. ceph-volume will then attempt to deploy this +straight to ceph-volume as JSON. ceph-volume will then attempt to deploy this drive groups via the batch subcommand. The specification can be passed via a file, string argument or on stdin. diff --git a/doc/ceph-volume/index.rst b/doc/ceph-volume/index.rst index 9271bc2a0e96..ab033b2559b2 100644 --- a/doc/ceph-volume/index.rst +++ b/doc/ceph-volume/index.rst @@ -2,17 +2,17 @@ ceph-volume =========== -Deploy OSDs with different device technologies like lvm or physical disks using +Deploy OSDs with different device technologies like LVM or physical devices using pluggable tools (:doc:`lvm/index` itself is treated like a plugin) and trying to -follow a predictable, and robust way of preparing, activating, and starting OSDs. +follow a predictable and robust way of preparing, activating, and starting OSDs. :ref:`Overview ` | -:ref:`Plugin Guide ` | +:ref:`Plugin Guide ` **Command Line Subcommands** -There is currently support for ``lvm``, and plain disks (with GPT partitions) +There is currently support for ``lvm``, and plain devices (with GPT partitions) that may have been deployed with ``ceph-disk``. ``zfs`` support is available for running a FreeBSD cluster. @@ -24,30 +24,37 @@ that may have been deployed with ``ceph-disk``. **Node inventory** The :ref:`ceph-volume-inventory` subcommand provides information and metadata -about a nodes physical disk inventory. +about a node's physical device inventory. Migrating --------- -Starting on Ceph version 13.0.0, ``ceph-disk`` is deprecated. Deprecation -warnings will show up that will link to this page. It is strongly suggested -that users start consuming ``ceph-volume``. There are two paths for migrating: +``ceph-disk`` was deprecated in the Mimic release and has since been removed. +``ceph-volume`` is the supported tool for provisioning and managing OSDs. If +your cluster still has OSDs that rely on ``ceph-disk``, +there are two migration paths: -#. Keep OSDs deployed with ``ceph-disk``: The :ref:`ceph-volume-simple` command - provides a way to take over the management while disabling ``ceph-disk`` - triggers. -#. Redeploy existing OSDs with ``ceph-volume``: This is covered in depth on - :ref:`rados-replacing-an-osd` +#. Keep OSDs deployed with ``ceph-disk``: the :ref:`ceph-volume-simple` command + takes over their management and disables the old ``ceph-disk`` triggers. +#. Redeploy existing OSDs with ``ceph-volume``: this is covered in depth in + :ref:`rados-replacing-an-osd`. -For details on why ``ceph-disk`` was removed please see the :ref:`Why was -ceph-disk replaced? ` section. +.. note:: + + Adopted ``ceph-disk`` OSDs continue to run, but the cephadm + orchestrator cannot manage them as it does ``ceph-volume`` OSDs. + Incremental redeployment with ``ceph-volume`` is therefore + preferred. + +For background on why ``ceph-disk`` was replaced, see the :ref:`Replacing +ceph-disk ` section. New deployments ^^^^^^^^^^^^^^^ -For new deployments, :ref:`ceph-volume-lvm` is recommended, it can use any -logical volume as input for data OSDs, or it can setup a minimal/naive logical -volume from a device. +For new deployments, :ref:`ceph-volume-lvm` is recommended. It can use any +logical volume for OSDs, or it can set up a minimal logical +volume on a device. Existing OSDs ^^^^^^^^^^^^^ diff --git a/doc/ceph-volume/intro.rst b/doc/ceph-volume/intro.rst index c36f12a776dd..57cfa691573e 100644 --- a/doc/ceph-volume/intro.rst +++ b/doc/ceph-volume/intro.rst @@ -2,83 +2,67 @@ Overview -------- -The ``ceph-volume`` tool aims to be a single purpose command line tool to deploy -logical volumes as OSDs, trying to maintain a similar API to ``ceph-disk`` when +The ``ceph-volume`` tool deploys and manages OSDs on logical volumes. It +maintains an API similar to that of the older ``ceph-disk`` tool when preparing, activating, and creating OSDs. -It deviates from ``ceph-disk`` by not interacting or relying on the udev rules -that come installed for Ceph. These rules allow automatic detection of -previously setup devices that are in turn fed into ``ceph-disk`` to activate -them. +Unlike ``ceph-disk``, it does not interact with or rely on udev rules. Those +rules allowed automatic detection of previously set up devices, which were in +turn fed into ``ceph-disk`` to activate them. + +Cephadm shell +------------- +Do not run ``ceph-volume`` from a container session that was started with +``cephadm shell`` while relying on that shell's default bind mounts. By design, +``cephadm shell`` omits several host bind mounts that ``ceph-volume`` expects +(for example /run/udev, /run/lvm, etc.). Invoking ``ceph-volume`` in that +environment is likely to fail or behave incorrectly. + +Running ``ceph-volume`` yourself, outside of what ``ceph orch`` / cephadm +drives, is not the normal operational path: it is mainly for debugging, +testing, or development. + +.. note:: Advanced use only + + If you truly understand the implications, you can extend the default container + environment by passing ``cephadm shell`` a single ``-m`` (or ``--mount``) + option followed by every bind mount you need, for example: + + .. code-block:: bash + + cephadm shell -m /dev:/dev /run/udev:/run/udev /sys:/sys /run/lvm:/run/lvm /run/lock/lvm:/run/lock/lvm /:/rootfs + + From **inside** that shell, if you still need the ``client.bootstrap-osd`` + keyring (``cephadm shell`` does not expose it by default), you can obtain it + with the cluster tools available in the container, for example: + + .. code-block:: bash + + ceph auth get client.bootstrap-osd -o /var/lib/ceph/bootstrap-osd/ceph.keyring + + Prefer doing this inside the enriched shell rather than generating key + material on the host and bind-mounting it in: the latter is easy to get + wrong, can leave sensitive files behind on the host, and is generally more + intrusive than running the same command from within the shell session. .. _ceph-disk-replaced: Replacing ``ceph-disk`` ----------------------- -The ``ceph-disk`` tool was created at a time when the project was required to -support many different types of init systems (upstart, sysvinit, etc...) while -being able to discover devices. This caused the tool to concentrate initially -(and exclusively afterwards) on GPT partitions. Specifically on GPT GUIDs, -which were used to label devices in a unique way to answer questions like: - -* is this device a Journal? -* an encrypted data partition? -* was the device left partially prepared? - -To solve these, it used ``UDEV`` rules to match the GUIDs, that would call -``ceph-disk``, and end up in a back and forth between the ``ceph-disk`` systemd -unit and the ``ceph-disk`` executable. The process was very unreliable and time -consuming (a timeout of close to three hours **per OSD** had to be put in -place), and would cause OSDs to not come up at all during the boot process of -a node. - -It was hard to debug, or even replicate these problems given the asynchronous -behavior of ``UDEV``. - -Since the world-view of ``ceph-disk`` had to be GPT partitions exclusively, it meant -that it couldn't work with other technologies like LVM, or similar device -mapper devices. It was ultimately decided to create something modular, starting -with LVM support, and the ability to expand on other technologies as needed. - - -GPT partitions are simple? --------------------------- -Although partitions in general are simple to reason about, ``ceph-disk`` -partitions were not simple by any means. It required a tremendous amount of -special flags in order to get them to work correctly with the device discovery -workflow. Here is an example call to create a data partition:: - - /sbin/sgdisk --largest-new=1 --change-name=1:ceph data --partition-guid=1:f0fc39fd-eeb2-49f1-b922-a11939cf8a0f --typecode=1:89c57f98-2fe5-4dc0-89c1-f3ad0ceff2be --mbrtogpt -- /dev/sdb - -Not only creating these was hard, but these partitions required devices to be -exclusively owned by Ceph. For example, in some cases a special partition would -be created when devices were encrypted, which would contain unencrypted keys. -This was ``ceph-disk`` domain knowledge, which would not translate to a "GPT -partitions are simple" understanding. Here is an example of that special -partition being created:: - - /sbin/sgdisk --new=5:0:+10M --change-name=5:ceph lockbox --partition-guid=5:None --typecode=5:fb3aabf9-d25f-47cc-bf5e-721d181642be --mbrtogpt -- /dev/sdad - - -Modularity ----------- -``ceph-volume`` was designed to be a modular tool because we anticipate that -there are going to be lots of ways that people provision the hardware devices -that we need to consider. There are already two: legacy ceph-disk devices that -are still in use and have GPT partitions (handled by :ref:`ceph-volume-simple`), -and lvm. SPDK devices where we manage NVMe devices directly from userspace are -on the immediate horizon, where LVM won't work there since the kernel isn't -involved at all. +``ceph-disk`` was the original OSD provisioning tool. It relied on GPT +partitions and ``UDEV`` rules to label, discover, and activate devices. That +approach was slow and hard to debug, and because it was tied to GPT partitions +it could not work with technologies such as LVM. For these reasons +``ceph-disk`` was deprecated in the Mimic release and has since been +removed. + +``ceph-volume`` replaces it with a modular design: OSDs that were originally +deployed with ``ceph-disk`` (plain disks with GPT partitions) are managed by +:ref:`ceph-volume-simple`, while new OSDs are provisioned with +:ref:`ceph-volume-lvm`. ``ceph-volume lvm`` ------------------- -By making use of :term:`LVM tags`, the :ref:`ceph-volume-lvm` sub-command is +By making use of :term:`LVM tags`, the :ref:`ceph-volume-lvm` subcommand is able to store and later re-discover and query devices associated with OSDs so that they can later be activated. - -LVM performance penalty ------------------------ -In short: we haven't been able to notice any significant performance penalties -associated with the change to LVM. By being able to work closely with LVM, the -ability to work with other device mapper technologies was a given: there is no -technical difficulty in working with anything that can sit below a Logical Volume. diff --git a/doc/ceph-volume/inventory.rst b/doc/ceph-volume/inventory.rst index edb1fd20501f..071bbb82ff83 100644 --- a/doc/ceph-volume/inventory.rst +++ b/doc/ceph-volume/inventory.rst @@ -2,16 +2,16 @@ ``inventory`` ============= -The ``inventory`` subcommand queries a host's disc inventory and provides +The ``inventory`` subcommand queries a host's disk inventory and provides hardware information and metadata on every physical device. By default the command returns a short, human-readable report of all physical disks. -For programmatic consumption of this report pass ``--format json`` to generate a +For programmatic consumption of this report, pass ``--format json`` to generate a JSON formatted report. This report includes extensive information on the physical drives such as disk metadata (like model and size), logical volumes -and whether they are used by ceph, and if the disk is usable by ceph and +and whether they are used by Ceph, and if the disk is usable by Ceph and reasons why not. A device path can be specified to report extensive information on a device in -both plain and json format. +both plain and JSON format. diff --git a/doc/ceph-volume/lvm/activate.rst b/doc/ceph-volume/lvm/activate.rst index fe34ecb713a9..78be5eab3d82 100644 --- a/doc/ceph-volume/lvm/activate.rst +++ b/doc/ceph-volume/lvm/activate.rst @@ -20,7 +20,7 @@ For information about OSDs deployed by cephadm, refer to New OSDs -------- -To activate newly prepared OSDs both the :term:`OSD id` and :term:`OSD uuid` +To activate newly prepared OSDs, both the :term:`OSD ID` and :term:`OSD UUID` need to be supplied. For example:: ceph-volume lvm activate --bluestore 0 0263644D-0BF1-4D6D-BC34-28BD98AE3BC8 @@ -44,11 +44,11 @@ and will activate them one by one. If any of the OSDs are already running, it will report them in the command output and skip them, making it safe to rerun (idempotent). -requiring uuids +Requiring UUIDs ^^^^^^^^^^^^^^^ -The :term:`OSD uuid` is being required as an extra step to ensure that the +The :term:`OSD UUID` is being required as an extra step to ensure that the right OSD is being activated. It is entirely possible that a previous OSD with -the same id exists and would end up activating the incorrect one. +the same ID exists and would end up activating the incorrect one. dmcrypt @@ -63,19 +63,19 @@ Discovery With OSDs previously created by ``ceph-volume``, a *discovery* process is performed using :term:`LVM tags` to enable the systemd units. -The systemd unit will capture the :term:`OSD id` and :term:`OSD uuid` and +The systemd unit will capture the :term:`OSD ID` and :term:`OSD UUID` and persist it. Internally, the activation will enable it like:: - systemctl enable ceph-volume@lvm-$id-$uuid + systemctl enable ceph-volume@lvm-- For example:: systemctl enable ceph-volume@lvm-0-8715BEB4-15C5-49DE-BA6F-401086EC7B41 -Would start the discovery process for the OSD with an id of ``0`` and a UUID of +Would start the discovery process for the OSD with an ID of ``0`` and a UUID of ``8715BEB4-15C5-49DE-BA6F-401086EC7B41``. -.. note:: for more details on the systemd workflow see :ref:`ceph-volume-lvm-systemd` +.. note:: For more details on the systemd workflow, see :ref:`ceph-volume-lvm-systemd`. The systemd unit will look for the matching OSD device, and by looking at its :term:`LVM tags` will proceed to: @@ -93,19 +93,19 @@ The systemd unit will look for the matching OSD device, and by looking at its Existing OSDs ------------- For existing OSDs that have been deployed with ``ceph-disk``, they need to be -scanned and activated :ref:`using the simple sub-command `. +scanned and activated :ref:`using the simple subcommand `. If a different tool was used then the only way to port them over to the new mechanism is to prepare them again (losing data). See :ref:`ceph-volume-lvm-existing-osds` for details on how to proceed. Summary ------- -To recap the ``activate`` process for :term:`bluestore`: +To recap the ``activate`` process for :term:`BlueStore`: -#. Require both :term:`OSD id` and :term:`OSD uuid` -#. Enable the system unit with matching id and uuid +#. Require both :term:`OSD ID` and :term:`OSD UUID` +#. Enable the system unit with matching ID and UUID #. Create the ``tmpfs`` mount at the OSD directory in - ``/var/lib/ceph/osd/$cluster-$id/`` + ``/var/lib/ceph/osd/-/`` #. Recreate all the files needed with ``ceph-bluestore-tool prime-osd-dir`` by pointing it to the OSD ``block`` device. #. The systemd unit will ensure all devices are ready and linked diff --git a/doc/ceph-volume/lvm/batch.rst b/doc/ceph-volume/lvm/batch.rst index 2114518bf56f..da841a20f039 100644 --- a/doc/ceph-volume/lvm/batch.rst +++ b/doc/ceph-volume/lvm/batch.rst @@ -7,13 +7,13 @@ an input of devices. The ``batch`` subcommand is closely related to drive-groups. One individual drive group specification translates to a single ``batch`` invocation. -The subcommand is based to :ref:`ceph-volume-lvm-create`, and will use the very +The subcommand is based on :ref:`ceph-volume-lvm-create`, and will use the very same code path. All ``batch`` does is to calculate the appropriate sizes of all volumes and skip over already created volumes. All the features that ``ceph-volume lvm create`` supports, like ``dmcrypt``, -avoiding ``systemd`` units from starting, defining bluestore, -is supported. +avoiding ``systemd`` units from starting, and defining BlueStore, +are supported. .. _ceph-volume-lvm-batch_auto: @@ -21,15 +21,15 @@ is supported. Automatic sorting of disks -------------------------- If ``batch`` receives only a single list of data devices and other options are -passed , ``ceph-volume`` will auto-sort disks by its rotational +passed, ``ceph-volume`` will auto-sort disks by its rotational property and use non-rotating disks for ``block.db`` or ``journal`` depending on the objectstore used. If all devices are to be used for standalone OSDs, no matter if rotating or solid state, pass ``--no-auto``. -For example assuming :term:`bluestore` is used and ``--no-auto`` is not passed, +For example assuming :term:`BlueStore` is used and ``--no-auto`` is not passed, the deprecated behavior would deploy the following, depending on the devices passed: -#. Devices are all spinning HDDs: 1 OSD is created per device +#. Devices are all HDDs: 1 OSD is created per device #. Devices are all SSDs: 2 OSDs are created per device #. Devices are a mix of HDDs and SSDs: data is placed on the spinning device, the ``block.db`` is created on the SSD, as large as possible. @@ -37,11 +37,11 @@ passed: .. note:: Although operations in ``ceph-volume lvm create`` allow usage of ``block.wal`` it isn't supported with the ``auto`` behavior. -This default auto-sorting behavior is now DEPRECATED and will be changed in future releases. -Instead devices are not automatically sorted unless the ``--auto`` option is passed +This default auto-sorting behavior is now **deprecated** and will be changed in future releases. +Instead, devices are not automatically sorted unless the ``--auto`` option is passed. -It is recommended to make use of the explicit device lists for ``block.db``, - ``block.wal`` and ``journal``. +It is recommended to make use of the explicit device lists +for ``block.db``, ``block.wal`` and ``journal``. .. _ceph-volume-lvm-batch_bluestore: @@ -58,7 +58,7 @@ Consider the following invocation:: $ ceph-volume lvm batch --report /dev/sdb /dev/sdc /dev/sdd --db-devices /dev/nvme0n1 This will deploy three OSDs with external ``db`` and ``wal`` volumes on -an NVME device. +an NVMe device. Pretty reporting ---------------- @@ -160,6 +160,55 @@ It is also possible to provide explicit sizes to `ceph-volume` via the arguments this is not possible, no OSDs will be deployed. +Collocated DB on the same device +--------------------------------- + +.. versionadded:: Squid 19.2.3 + +It is possible to deploy a non-collocated BlueStore layout where the ``block.db`` +LV is carved out of the **same physical device** as the data LV, without needing +a separate device. This helps mitigate BlueStore fragmentation by isolating metadata +writes. + +To enable this, pass ``--block-db-size`` **without** ``--db-devices``. +``ceph-volume`` will create two LVs on each data device: one for data and one for +``block.db``:: + + $ ceph-volume lvm batch --report /dev/sdb /dev/sdc --block-db-size 4G + +Example output:: + + Total OSDs: 2 + + Type Path LV Size % of device + ---------------------------------------------------------------------------------------------------- + data /dev/sdb 196.00 GB 98.00% + block_db /dev/sdb 4.00 GB 2.00% + ---------------------------------------------------------------------------------------------------- + data /dev/sdc 196.00 GB 98.00% + block_db /dev/sdc 4.00 GB 2.00% + +This also works with ``--osds-per-device``:: + + $ ceph-volume lvm batch --report /dev/sdb --osds-per-device 2 --block-db-size 4G + +Example output:: + + Total OSDs: 2 + + Type Path LV Size % of device + ---------------------------------------------------------------------------------------------------- + data /dev/sdb 96.00 GB 48.00% + block_db /dev/sdb 4.00 GB 2.00% + ---------------------------------------------------------------------------------------------------- + data /dev/sdb 96.00 GB 48.00% + block_db /dev/sdb 4.00 GB 2.00% + +.. note:: ``ceph-volume`` cannot derive a sensible default DB size automatically + in this scenario, so ``--block-db-size`` is mandatory. If the requested + size cannot be accommodated, no OSDs will be deployed. + + Idempotency and disk replacements ================================= `ceph-volume lvm batch` intends to be idempotent, i.e. calling the same command diff --git a/doc/ceph-volume/lvm/create.rst b/doc/ceph-volume/lvm/create.rst index 17fe9fa5ab2a..ea915c817e28 100644 --- a/doc/ceph-volume/lvm/create.rst +++ b/doc/ceph-volume/lvm/create.rst @@ -2,10 +2,10 @@ ``create`` =========== -This subcommand wraps the two-step process to provision a new osd (calling +This subcommand wraps the two-step process to provision a new OSD (calling ``prepare`` first and then ``activate``) into a single one. The reason to prefer ``prepare`` and then ``activate`` is to gradually -introduce new OSDs into a cluster, and avoiding large amounts of data being +introduce new OSDs into a cluster, avoiding large amounts of data being rebalanced. The single-call process unifies exactly what :ref:`ceph-volume-lvm-prepare` and diff --git a/doc/ceph-volume/lvm/encryption.rst b/doc/ceph-volume/lvm/encryption.rst index 4564a7ffed84..0f069ac02022 100644 --- a/doc/ceph-volume/lvm/encryption.rst +++ b/doc/ceph-volume/lvm/encryption.rst @@ -6,7 +6,7 @@ Encryption Logical volumes can be encrypted using ``dmcrypt`` by specifying the ``--dmcrypt`` flag when creating OSDs. When using LVM, logical volumes can be encrypted in different ways. ``ceph-volume`` does not offer as many options as -LVM does, but it encrypts logical volumes in a way that is consistent and +LVM does, but it encrypts logical volumes in a way that is consistent and robust. In this case, ``ceph-volume lvm`` follows this constraint: @@ -21,7 +21,7 @@ implement but not widely available in all Linux distributions supported by Ceph. .. note:: Version 1 of LUKS is referred to in this documentation as "LUKS". - Version 2 is of LUKS is referred to in this documentation as "LUKS2". + Version 2 of LUKS is referred to in this documentation as "LUKS2". LUKS on LVM @@ -62,8 +62,8 @@ compatibility and prevent ceph-disk from breaking, ceph-volume uses the same naming convention *although it does not make sense for the new encryption workflow*. -After the common steps of setting up the OSD during the "prepare stage" ( -with :term:`bluestore`), the logical volume is left ready +After the common steps of setting up the OSD during the "prepare stage" +(with :term:`BlueStore`), the logical volume is left ready to be activated, regardless of the state of the device (encrypted or decrypted). diff --git a/doc/ceph-volume/lvm/index.rst b/doc/ceph-volume/lvm/index.rst index 962e51a51c68..c951841ef43f 100644 --- a/doc/ceph-volume/lvm/index.rst +++ b/doc/ceph-volume/lvm/index.rst @@ -27,7 +27,7 @@ Implements the functionality needed to deploy OSDs from the ``lvm`` subcommand: **Internal functionality** There are other aspects of the ``lvm`` subcommand that are internal and not -exposed to the user, these sections explain how these pieces work together, +exposed to the user. These sections explain how these pieces work together, clarifying the workflows of the tool. :ref:`Systemd Units ` | diff --git a/doc/ceph-volume/lvm/list.rst b/doc/ceph-volume/lvm/list.rst index 6fb8fe84d27b..55a7ccfc2608 100644 --- a/doc/ceph-volume/lvm/list.rst +++ b/doc/ceph-volume/lvm/list.rst @@ -21,7 +21,7 @@ When no positional arguments are used, a full reporting will be presented. This means that all devices and logical volumes found in the system will be displayed. -Full ``pretty`` reporting for two OSDs, one with a lv as a journal, and another +Full ``pretty`` reporting for two OSDs, one with a LV as a journal, and another one with a physical device may look similar to: .. prompt:: bash # @@ -81,8 +81,8 @@ to be part of a logical volume, the value will be comma separated when using ``pretty``, but an array when using ``json``. .. note:: Tags are displayed in a readable format. The ``osd id`` key is stored - as a ``ceph.osd_id`` tag. For more information on lvm tag conventions - see :ref:`ceph-volume-lvm-tag-api` + as a ``ceph.osd_id`` tag. For more information on LVM tag conventions, + see :ref:`ceph-volume-lvm-tag-api`. Single Reporting ---------------- @@ -115,8 +115,8 @@ can be listed in the following way: .. note:: Tags are displayed in a readable format. The ``osd id`` key is stored - as a ``ceph.osd_id`` tag. For more information on lvm tag conventions - see :ref:`ceph-volume-lvm-tag-api` + as a ``ceph.osd_id`` tag. For more information on LVM tag conventions, + see :ref:`ceph-volume-lvm-tag-api`. For plain disks, the full path to the device is required. For example, for @@ -188,7 +188,7 @@ that may be in use haven't changed naming. It is possible that non-persistent devices like ``/dev/sda1`` could change to ``/dev/sdb1``. The detection is possible because the ``PARTUUID`` is stored as part of the -metadata in the logical volume for the data lv. Even in the case of a journal +metadata in the logical volume for the data LV. Even in the case of a journal that is a physical device, this information is still stored on the data logical volume associated with it. diff --git a/doc/ceph-volume/lvm/migrate.rst b/doc/ceph-volume/lvm/migrate.rst index 983d2e79716b..37c6f5039cf1 100644 --- a/doc/ceph-volume/lvm/migrate.rst +++ b/doc/ceph-volume/lvm/migrate.rst @@ -3,15 +3,15 @@ ``migrate`` =========== -Moves BlueFS data from source volume(s) to the target one, source volumes +Moves BlueFS data from source volume(s) to the target one. Source volumes (except the main, i.e. data or block one) are removed on success. -LVM volumes are permitted for Target only, both already attached or new one. +LVM volumes are permitted for target only, both already attached or new one. In the latter case it is attached to the OSD replacing one of the source devices. -Following replacement rules apply (in the order of precedence, stop +Following replacement rules apply (in the order of precedence; stop on the first match): - if source list has DB volume - target device replaces it. diff --git a/doc/ceph-volume/lvm/newdb.rst b/doc/ceph-volume/lvm/newdb.rst index a8136c9886bb..1682f0341e06 100644 --- a/doc/ceph-volume/lvm/newdb.rst +++ b/doc/ceph-volume/lvm/newdb.rst @@ -27,30 +27,30 @@ following steps: .. prompt:: bash # - lvextend -l ${size} ${lv}/${db} ${ssd_dev} + lvextend -l / #. Stop the OSD: .. prompt:: bash # - cephadm unit --fsid $cid --name osd.${osd} stop + cephadm unit --fsid --name osd. stop #. Run the ``bluefs-bdev-expand`` command: .. prompt:: bash # - cephadm shell --fsid $cid --name osd.${osd} -- ceph-bluestore-tool bluefs-bdev-expand --path /var/lib/ceph/osd/ceph-${osd} + cephadm shell --fsid --name osd. -- ceph-bluestore-tool bluefs-bdev-expand --path /var/lib/ceph/osd/ceph- #. Run the ``bluefs-bdev-migrate`` command: .. prompt:: bash # - cephadm shell --fsid $cid --name osd.${osd} -- ceph-bluestore-tool bluefs-bdev-migrate --path /var/lib/ceph/osd/ceph-${osd} --devs-source /var/lib/ceph/osd/ceph-${osd}/block --dev-target /var/lib/ceph/osd/ceph-${osd}/block.db + cephadm shell --fsid --name osd. -- ceph-bluestore-tool bluefs-bdev-migrate --path /var/lib/ceph/osd/ceph- --devs-source /var/lib/ceph/osd/ceph-/block --dev-target /var/lib/ceph/osd/ceph-/block.db #. Restart the OSD: .. prompt:: bash # - cephadm unit --fsid $cid --name osd.${osd} start + cephadm unit --fsid --name osd. start -.. note:: *The above procedure was developed by Chris Dunlop on the [ceph-users] mailing list, and can be seen in its original context here:* `[ceph-users] Re: Fixing BlueFS spillover (pacific 16.2.14) `_ +.. note:: *The above procedure was developed by Chris Dunlop on the [ceph-users] mailing list, and can be seen in its original context here:* `[ceph-users] Re: Fixing BlueFS spillover (pacific 16.2.14) `_. diff --git a/doc/ceph-volume/lvm/prepare.rst b/doc/ceph-volume/lvm/prepare.rst index 5fc3662611fa..7682bed6cd38 100644 --- a/doc/ceph-volume/lvm/prepare.rst +++ b/doc/ceph-volume/lvm/prepare.rst @@ -25,7 +25,7 @@ the backend, which can be done by using the following flags and arguments: ``bluestore`` ------------- -:term:`Bluestore` is the default backend for new OSDs. Bluestore +:term:`BlueStore` is the default backend for new OSDs. BlueStore supports the following configurations: * a block device, a block.wal device, and a block.db device @@ -70,7 +70,7 @@ Starting with Ceph Squid, you can opt for TPM2 token enrollment for the created If a ``block.db`` device or a ``block.wal`` device is needed, it can be specified with ``--block.db`` or ``--block.wal``. These can be physical devices, partitions, or logical volumes. ``block.db`` and ``block.wal`` are -optional for bluestore. +optional for BlueStore. For both ``block.db`` and ``block.wal``, partitions can be used as-is, and therefore are not made into logical volumes. @@ -102,10 +102,10 @@ directory looks like this: In the above case, a device was used for ``block``, so ``ceph-volume`` created a volume group and a logical volume using the following conventions: -* volume group name: ``ceph-{cluster fsid}`` (or if the volume group already - exists: ``ceph-{random uuid}``) +* volume group name: ``ceph-`` (or if the volume group already + exists: ``ceph-``) -* logical volume name: ``osd-block-{osd_fsid}`` +* logical volume name: ``osd-block-`` .. _ceph-volume-lvm-prepare_filestore: @@ -114,11 +114,11 @@ a volume group and a logical volume using the following conventions: ------------- .. warning:: Filestore has been deprecated in the Reef release and is no longer supported. -``Filestore`` is the OSD backend that prepares logical volumes for a -`filestore`-backed object-store OSD. +Filestore is the OSD backend that prepares logical volumes for a +filestore-backed object-store OSD. -``Filestore`` uses a logical volume to store OSD data and it uses +Filestore uses a logical volume to store OSD data and it uses physical devices, partitions, or logical volumes to store the journal. If a physical device is used to create a filestore backend, a logical volume will be created on that physical device. If the provided volume group's name begins @@ -196,7 +196,7 @@ To fetch the monmap by using the bootstrap key from the OSD, use this command: /var/lib/ceph/bootstrap-osd/ceph.keyring mon getmap -o \ /var/lib/ceph/osd/-/activate.monmap -To populate the OSD directory (which has already been mounted), use this ``ceph-osd`` command: +To populate the OSD directory (which has already been mounted), use this ``ceph-osd`` command: .. prompt:: bash # @@ -252,7 +252,7 @@ print``: Partition Table: gpt Disk Flags: -Now lets create a single partition, and verify later if ``blkid`` can find +Now let's create a single partition, and verify later if ``blkid`` can find a ``PARTUUID`` that is needed by ``ceph-volume``: .. prompt:: bash # @@ -270,9 +270,9 @@ a ``PARTUUID`` that is needed by ``ceph-volume``: Existing OSDs ------------- For existing clusters that want to use this new system and have OSDs that are -already running there are a few things to take into account: +already running, there are a few things to take into account: -.. warning:: this process will forcefully format the data device, destroying +.. warning:: This process will forcefully format the data device, destroying existing data, if any. * OSD paths should follow this convention:: @@ -290,7 +290,7 @@ any data** in the OSD): ceph-volume lvm prepare --filestore --osd-id 0 --osd-fsid E3D291C1-E7BF-4984-9794-B60D9FA139CB -The command line tool will not contact the monitor to generate an OSD ID and +The command line tool will not contact the Monitor to generate an OSD ID and will format the LVM device in addition to storing the metadata on it so that it can be started later (for detailed metadata description see :ref:`ceph-volume-lvm-tags`). @@ -336,7 +336,7 @@ regardless of the type of volume (journal or data) or OSD objectstore: * ``osd_id`` * ``crush_device_class`` -For :term:`bluestore` these tags will be added: +For :term:`BlueStore`, these tags will be added: * ``block_device`` * ``block_uuid`` @@ -350,12 +350,12 @@ For :term:`bluestore` these tags will be added: Summary ------- -To recap the ``prepare`` process for :term:`bluestore`: +To recap the ``prepare`` process for :term:`BlueStore`: #. Accepts raw physical devices, partitions on physical devices or logical volumes as arguments. #. Creates logical volumes on any raw physical devices. #. Generate a UUID for the OSD -#. Ask the monitor get an OSD ID reusing the generated UUID +#. Ask the Monitor for an OSD ID reusing the generated UUID #. OSD data directory is created on a tmpfs mount. #. ``block``, ``block.wal``, and ``block.db`` are symlinked if defined. #. monmap is fetched for activation diff --git a/doc/ceph-volume/lvm/scan.rst b/doc/ceph-volume/lvm/scan.rst index aa9990f7199d..b5e2ce93408e 100644 --- a/doc/ceph-volume/lvm/scan.rst +++ b/doc/ceph-volume/lvm/scan.rst @@ -1,9 +1,9 @@ scan ==== -This sub-command will allow to discover Ceph volumes previously setup by the +This subcommand will allow to discover Ceph volumes previously set up by the tool by looking into the system's logical volumes and their tags. As part of the :ref:`ceph-volume-lvm-prepare` process, the logical volumes are assigned a few tags with important pieces of information. -.. note:: This sub-command is not yet implemented +.. note:: This subcommand is not yet implemented. diff --git a/doc/ceph-volume/lvm/systemd.rst b/doc/ceph-volume/lvm/systemd.rst index 30260de7e882..33a6c4378bdc 100644 --- a/doc/ceph-volume/lvm/systemd.rst +++ b/doc/ceph-volume/lvm/systemd.rst @@ -4,14 +4,14 @@ systemd ======= Upon startup, it will identify the logical volume using :term:`LVM tags`, finding a matching ID and later ensuring it is the right one with -the :term:`OSD uuid`. +the :term:`OSD UUID`. -After identifying the correct volume it will then proceed to mount it by using +After identifying the correct volume, it will then proceed to mount it by using the OSD destination conventions, that is:: /var/lib/ceph/osd/- -For our example OSD with an id of ``0``, that means the identified device will +For our example OSD with an ID of ``0``, that means the identified device will be mounted at:: @@ -23,6 +23,6 @@ Once that process is complete, a call will be made to start the OSD:: systemctl start ceph-osd@0 The systemd portion of this process is handled by the ``ceph-volume lvm -trigger`` sub-command, which is only in charge of parsing metadata coming from +trigger`` subcommand, which is only in charge of parsing metadata coming from systemd and startup, and then dispatching to ``ceph-volume lvm activate`` which would proceed with activation. diff --git a/doc/ceph-volume/lvm/zap.rst b/doc/ceph-volume/lvm/zap.rst index e737fc38685a..bc70d9e0b673 100644 --- a/doc/ceph-volume/lvm/zap.rst +++ b/doc/ceph-volume/lvm/zap.rst @@ -3,19 +3,19 @@ ``zap`` ======= -This subcommand is used to zap lvs, partitions or raw devices that have been used -by ceph OSDs so that they may be reused. If given a path to a logical -volume it must be in the format of vg/lv. Any file systems present -on the given lv or partition will be removed and all data will be purged. +This subcommand is used to zap LVs, partitions, or raw devices that have been used +by Ceph OSDs so that they may be reused. If given a path to a logical +volume, it must be in the format of vg/lv. Any file systems present +on the given LV or partition will be removed and all data will be purged. -.. note:: The lv or partition will be kept intact. +.. note:: The LV or partition will be kept intact. -.. note:: If the logical volume, raw device or partition is being used for any ceph related - mount points they will be unmounted. +.. note:: If the logical volume, raw device, or partition is being used for any Ceph-related + mount points, they will be unmounted. Zapping a logical volume:: - ceph-volume lvm zap {vg name/lv name} + ceph-volume lvm zap Zapping a partition:: @@ -23,20 +23,20 @@ Zapping a partition:: Removing Devices ---------------- -When zapping, and looking for full removal of the device (lv, vg, or partition) +When zapping and looking for full removal of the device (LV, VG, or partition), use the ``--destroy`` flag. A common use case is to simply deploy OSDs using a whole raw device. If you do so and then wish to reuse that device for another -OSD you must use the ``--destroy`` flag when zapping so that the vgs and lvs +OSD, you must use the ``--destroy`` flag when zapping so that the VGs and LVs that ceph-volume created on the raw device will be removed. -.. note:: Multiple devices can be accepted at once, to zap them all +.. note:: Multiple devices can be specified at once to zap them all. -Zapping a raw device and destroying any vgs or lvs present:: +Zapping a raw device and destroying any VGs or LVs present:: ceph-volume lvm zap /dev/sdc --destroy -This action can be performed on partitions, and logical volumes as well:: +This action can be performed on partitions and logical volumes:: ceph-volume lvm zap /dev/sdc1 --destroy ceph-volume lvm zap osd-vg/data-lv --destroy diff --git a/doc/ceph-volume/simple/activate.rst b/doc/ceph-volume/simple/activate.rst index 8c7737162e8f..325036549145 100644 --- a/doc/ceph-volume/simple/activate.rst +++ b/doc/ceph-volume/simple/activate.rst @@ -2,19 +2,19 @@ ``activate`` ============ -Once :ref:`ceph-volume-simple-scan` has been completed, and all the metadata -captured for an OSD has been persisted to ``/etc/ceph/osd/{id}-{uuid}.json`` +Once :ref:`ceph-volume-simple-scan` has been completed and all the metadata +captured for an OSD has been persisted to ``/etc/ceph/osd/-.json``, the OSD is now ready to get "activated". This activation process **disables** all ``ceph-disk`` systemd units by masking -them, to prevent the UDEV/ceph-disk interaction that will attempt to start them +them, to prevent the udev/ceph-disk interaction that will attempt to start them up at boot time. The disabling of ``ceph-disk`` units is done only when calling ``ceph-volume simple activate`` directly, but is avoided when being called by systemd when the system is booting up. -The activation process requires using both the :term:`OSD id` and :term:`OSD uuid` +The activation process requires using both the :term:`OSD ID` and :term:`OSD UUID`. To activate parsed OSDs:: ceph-volume simple activate 0 6cc43680-4f6e-4feb-92ff-9c7ba204120e @@ -27,11 +27,11 @@ Alternatively, using a path to a JSON file directly is also possible:: ceph-volume simple activate --file /etc/ceph/osd/0-6cc43680-4f6e-4feb-92ff-9c7ba204120e.json -requiring uuids +Requiring UUIDs ^^^^^^^^^^^^^^^ -The :term:`OSD uuid` is being required as an extra step to ensure that the +The :term:`OSD UUID` is being required as an extra step to ensure that the right OSD is being activated. It is entirely possible that a previous OSD with -the same id exists and would end up activating the incorrect one. +the same ID exists and would end up activating the incorrect one. Discovery @@ -46,7 +46,7 @@ queried against ``lvs`` (the LVM tool to list logical volumes). This discovery process ensures that devices can be correctly detected even if they are repurposed into another system or if their name changes (as in the -case of non-persisting names like ``/dev/sda1``) +case of non-persisting names like ``/dev/sda1``). The JSON configuration file used to map what devices go to what OSD will then coordinate the mounting and symlinking as part of activation. @@ -54,26 +54,25 @@ coordinate the mounting and symlinking as part of activation. To ensure that the symlinks are always correct, if they exist in the OSD directory, the symlinks will be re-done. -A systemd unit will capture the :term:`OSD id` and :term:`OSD uuid` and +A systemd unit will capture the :term:`OSD ID` and :term:`OSD UUID` and persist it. Internally, the activation will enable it like:: - systemctl enable ceph-volume@simple-$id-$uuid + systemctl enable ceph-volume@simple-- For example:: systemctl enable ceph-volume@simple-0-8715BEB4-15C5-49DE-BA6F-401086EC7B41 -Would start the discovery process for the OSD with an id of ``0`` and a UUID of +Would start the discovery process for the OSD with an ID of ``0`` and a UUID of ``8715BEB4-15C5-49DE-BA6F-401086EC7B41``. The systemd process will call out to activate passing the information needed to identify the OSD and its devices, and it will proceed to: -# mount the device in the corresponding location (by convention this is - ``/var/lib/ceph/osd/-/``) +#. mount the device in the corresponding location (by convention this is + ``/var/lib/ceph/osd/-/``) +#. ensure that all required devices are ready for that OSD and properly linked -# ensure that all required devices are ready for that OSD and properly linked. -The symbolic link will **always** be re-done to ensure that the correct device is linked. - -# start the ``ceph-osd@0`` systemd unit + The symbolic link will **always** be re-done to ensure that the correct device is linked. +#. start the ``ceph-osd@0`` systemd unit diff --git a/doc/ceph-volume/simple/index.rst b/doc/ceph-volume/simple/index.rst index 315dea99a106..8fb1c9bb4273 100644 --- a/doc/ceph-volume/simple/index.rst +++ b/doc/ceph-volume/simple/index.rst @@ -27,6 +27,6 @@ The scanning will infer everything that ``ceph-volume`` needs to start the OSD, so that when activation is needed, the OSD can start normally without getting interference from ``ceph-disk``. -As part of the activation process the systemd units for ``ceph-disk`` in charge -of reacting to ``udev`` events, are linked to ``/dev/null`` so that they are +As part of the activation process, the systemd units for ``ceph-disk`` in charge +of reacting to ``udev`` events are linked to ``/dev/null`` so that they are fully inactive. diff --git a/doc/ceph-volume/simple/scan.rst b/doc/ceph-volume/simple/scan.rst index 2749b14b64ac..172c65fb0d0a 100644 --- a/doc/ceph-volume/simple/scan.rst +++ b/doc/ceph-volume/simple/scan.rst @@ -7,14 +7,14 @@ so that ``ceph-volume`` can manage it without the need of any other startup workflows or tools (like ``udev`` or ``ceph-disk``). Encryption with LUKS or PLAIN formats is fully supported. -The command has the ability to inspect a running OSD, by inspecting the +The command has the ability to inspect a running OSD by inspecting the directory where the OSD data is stored, or by consuming the data partition. The command can also scan all running OSDs if no path or device is provided. Once scanned, information will (by default) persist the metadata as JSON in a file in ``/etc/ceph/osd``. This ``JSON`` file will use the naming convention -of: ``{OSD ID}-{OSD FSID}.json``. An OSD with an id of 1, and an FSID like -``86ebd829-1405-43d3-8fd6-4cbc9b6ecf96`` the absolute path of the file would +of: ``-.json``. For an OSD with an ID of 1 and an FSID like +``86ebd829-1405-43d3-8fd6-4cbc9b6ecf96``, the absolute path of the file would be:: /etc/ceph/osd/1-86ebd829-1405-43d3-8fd6-4cbc9b6ecf96.json @@ -22,12 +22,12 @@ be:: The ``scan`` subcommand will refuse to write to this file if it already exists. If overwriting the contents is needed, the ``--force`` flag must be used:: - ceph-volume simple scan --force {path} + ceph-volume simple scan --force If there is no need to persist the ``JSON`` metadata, there is support to send the contents to ``stdout`` (no file will be written):: - ceph-volume simple scan --stdout {path} + ceph-volume simple scan --stdout .. _ceph-volume-simple-scan-directory: @@ -36,7 +36,7 @@ Running OSDs scan ----------------- Using this command without providing an OSD directory or device will scan the directories of any currently running OSDs. If a running OSD was not created -by ceph-disk it will be ignored and not scanned. +by ceph-disk, it will be ignored and not scanned. To scan all running ceph-disk OSDs, the command would look like:: @@ -85,7 +85,7 @@ Would get stored as:: For a directory like ``/var/lib/ceph/osd/ceph-1``, the command could look like:: - ceph-volume simple scan /var/lib/ceph/osd/ceph1 + ceph-volume simple scan /var/lib/ceph/osd/ceph-1 .. _ceph-volume-simple-scan-device: @@ -99,7 +99,7 @@ still require a few files present. This means that the device to be scanned **must be** the data partition of the OSD. As long as the data partition of the OSD is being passed in as an argument, the -sub-command can scan its contents. +subcommand can scan its contents. In the case where the device is already mounted, the tool can detect this scenario and capture file contents from that directory. @@ -121,7 +121,7 @@ could look like:: The contents of the JSON object is very simple. The scan not only will persist information from the special OSD files and their contents, but will also validate paths and device UUIDs. Unlike what ``ceph-disk`` would do, by storing -them in ``{device type}_uuid`` files, the tool will persist them as part of the +them in ``_uuid`` files, the tool will persist them as part of the device type key. For example, a ``block.db`` device would look something like:: @@ -138,12 +138,12 @@ But it will also persist the ``ceph-disk`` special file generated, like so:: This duplication is in place because the tool is trying to ensure the following: -# Support OSDs that may not have ceph-disk special files -# Check the most up-to-date information on the device, by querying against LVM -and ``blkid`` -# Support both logical volumes and GPT devices +#. Support OSDs that may not have ceph-disk special files +#. Check the most up-to-date information on the device, by querying against LVM + and ``blkid`` +#. Support both logical volumes and GPT devices -This is a sample ``JSON`` metadata, from an OSD that is using ``bluestore``:: +This is a sample ``JSON`` metadata, from an OSD that is using BlueStore:: { "active": "ok", diff --git a/doc/ceph-volume/simple/systemd.rst b/doc/ceph-volume/simple/systemd.rst index aa5bebffe71c..32fbc486bd95 100644 --- a/doc/ceph-volume/simple/systemd.rst +++ b/doc/ceph-volume/simple/systemd.rst @@ -3,13 +3,13 @@ systemd ======= Upon startup, it will identify the logical volume by loading the JSON file in -``/etc/ceph/osd/{id}-{uuid}.json`` corresponding to the instance name of the +``/etc/ceph/osd/-.json`` corresponding to the instance name of the systemd unit. -After identifying the correct volume it will then proceed to mount it by using +After identifying the correct volume, it will then proceed to mount it by using the OSD destination conventions, that is:: - /var/lib/ceph/osd/{cluster name}-{osd id} + /var/lib/ceph/osd/- For our example OSD with an id of ``0``, that means the identified device will be mounted at:: @@ -23,6 +23,6 @@ Once that process is complete, a call will be made to start the OSD:: systemctl start ceph-osd@0 The systemd portion of this process is handled by the ``ceph-volume simple -trigger`` sub-command, which is only in charge of parsing metadata coming from +trigger`` subcommand, which is only in charge of parsing metadata coming from systemd and startup, and then dispatching to ``ceph-volume simple activate`` which would proceed with activation. diff --git a/doc/ceph-volume/systemd.rst b/doc/ceph-volume/systemd.rst index 5b5273c9cfd8..fd6b552be1ed 100644 --- a/doc/ceph-volume/systemd.rst +++ b/doc/ceph-volume/systemd.rst @@ -4,25 +4,25 @@ systemd ======= As part of the activation process (either with :ref:`ceph-volume-lvm-activate` or :ref:`ceph-volume-simple-activate`), systemd units will get enabled that -will use the OSD id and uuid as part of their name. These units will be run +will use the OSD ID and UUID as part of their name. These units will be run when the system boots, and will proceed to activate their corresponding -volumes via their sub-command implementation. +volumes via their subcommand implementation. -The API for activation is a bit loose, it only requires two parts: the +The API for activation is a bit loose. It only requires two parts: the subcommand to use and any extra meta information separated by a dash. This convention makes the units look like:: - ceph-volume@{command}-{extra metadata} + ceph-volume@- The *extra metadata* can be anything needed that the subcommand implementing the processing might need. In the case of :ref:`ceph-volume-lvm` and -:ref:`ceph-volume-simple`, both look to consume the :term:`OSD id` and :term:`OSD uuid`, -but this is not a hard requirement, it is just how the sub-commands are +:ref:`ceph-volume-simple`, both look to consume the :term:`OSD ID` and :term:`OSD UUID`, +but this is not a hard requirement, it is just how the subcommands are implemented. -Both the command and extra metadata gets persisted by systemd as part of the +Both the command and extra metadata get persisted by systemd as part of the *"instance name"* of the unit. For example an OSD with an ID of 0, for the -``lvm`` sub-command would look like:: +``lvm`` subcommand would look like:: systemctl enable ceph-volume@lvm-0-0A3E1ED2-DA8A-4F0E-AA95-61DEC71768D6 diff --git a/doc/ceph-volume/zfs/index.rst b/doc/ceph-volume/zfs/index.rst index c06228de91dc..5bf2217a5ae8 100644 --- a/doc/ceph-volume/zfs/index.rst +++ b/doc/ceph-volume/zfs/index.rst @@ -5,7 +5,7 @@ Implements the functionality needed to deploy OSDs from the ``zfs`` subcommand: ``ceph-volume zfs`` -The current implementation only works for ZFS on FreeBSD +The current implementation only works for ZFS on FreeBSD. **Command Line Subcommands** @@ -25,7 +25,7 @@ The current implementation only works for ZFS on FreeBSD **Internal functionality** There are other aspects of the ``zfs`` subcommand that are internal and not -exposed to the user, these sections explain how these pieces work together, +exposed to the user. These sections explain how these pieces work together, clarifying the workflows of the tool. :ref:`zfs ` diff --git a/doc/ceph-volume/zfs/inventory.rst b/doc/ceph-volume/zfs/inventory.rst index fd00325b6a88..3266b226c42a 100644 --- a/doc/ceph-volume/zfs/inventory.rst +++ b/doc/ceph-volume/zfs/inventory.rst @@ -2,18 +2,18 @@ ``inventory`` ============= -The ``inventory`` subcommand queries a host's disc inventory through GEOM and provides +The ``inventory`` subcommand queries a host's disk inventory through GEOM and provides hardware information and metadata on every physical device. This only works on a FreeBSD platform. -By default the command returns a short, human-readable report of all physical disks. +By default, the command returns a short, human-readable report of all physical disks. -For programmatic consumption of this report pass ``--format json`` to generate a +For programmatic consumption of this report, pass ``--format json`` to generate a JSON formatted report. This report includes extensive information on the physical drives such as disk metadata (like model and size), logical volumes -and whether they are used by ceph, and if the disk is usable by ceph and +and whether they are used by Ceph, and if the disk is usable by Ceph and reasons why not. A device path can be specified to report extensive information on a device in -both plain and json format. +both plain and JSON format. diff --git a/doc/cephadm/adoption.rst b/doc/cephadm/adoption.rst index 2ebce606c4f0..177e5bedc2ad 100644 --- a/doc/cephadm/adoption.rst +++ b/doc/cephadm/adoption.rst @@ -1,23 +1,26 @@ .. _cephadm-adoption: -Converting an existing cluster to cephadm +========================================= +Converting an Existing Cluster to Cephadm ========================================= It is possible to convert some existing clusters so that they can be managed with ``cephadm``. This statement applies to some clusters that were deployed -with ``ceph-deploy``, ``ceph-ansible``, or ``DeepSea``. +with ``ceph-deploy`` (a legacy deployment tool), ``ceph-ansible``, or ``DeepSea``. This section of the documentation explains how to determine whether your clusters can be converted to a state in which they can be managed by ``cephadm`` and how to perform those conversions. + Limitations ------------ +=========== * Cephadm works only with BlueStore OSDs. + Preparation ------------ +=========== #. Make sure that the ``cephadm`` command line tool is available on each host in the existing cluster. See :ref:`get-cephadm` to learn how. @@ -55,20 +58,20 @@ Preparation adopted daemons will appear with the style ``cephadm:v1``. -Adoption process ----------------- +Adoption Process +================ -#. Make sure that the ceph configuration has been migrated to use the cluster's - central config database. If ``/etc/ceph/ceph.conf`` is identical on all - hosts, then the following command can be run on one host and will take - effect for all hosts: +#. Make sure that the Ceph configuration has been migrated to use the cluster's + central config database (see :ref:`ceph-conf-database`). + If ``/etc/ceph/ceph.conf`` is identical on all hosts, then the following + command can be run on one host and will take effect for all hosts: .. prompt:: bash # ceph config assimilate-conf -i /etc/ceph/ceph.conf If there are configuration variations between hosts, you will need to repeat - this command on each host, taking care that if there are conflicting option + this command on each host, taking care that if there are conflicting configuration settings across hosts, the values from the last host will be used. During this adoption process, view the cluster's central configuration to confirm that it is complete by running the following @@ -120,11 +123,11 @@ Adoption process SSH keys. .. note:: - It is also possible to arrange for cephadm to use a non-root user to SSH + It is also possible to arrange for cephadm to use a non-root user to SSH into cluster hosts. This user needs to have passwordless sudo access. Use ``ceph cephadm set-user `` and copy the SSH key to that user's home directory on each host. - See :ref:`cephadm-ssh-user` + See :ref:`cephadm-ssh-user`. #. Tell cephadm which hosts to manage: @@ -137,7 +140,7 @@ Adoption process argument is recommended. If the address is not provided, then the host name will be resolved via DNS. -#. Verify that the adopted monitor and manager daemons are visible: +#. Verify that the adopted Monitor and Manager daemons are visible: .. prompt:: bash # @@ -158,20 +161,20 @@ Adoption process #. Redeploy CephFS MDS daemons (if deployed) by telling cephadm how many daemons to run for each file system. List CephFS file systems by name with the command ``ceph fs - ls``. Run the following command on the master nodes to redeploy the MDS + ls``. Run a command of the following form on the master nodes to redeploy the MDS daemons: .. prompt:: bash # ceph orch apply mds [--placement=] - For example, in a cluster with a single file system called `foo`: + For example, in a cluster with a single file system called ``foo``: .. prompt:: bash # ceph fs ls - .. code-block:: bash + .. code-block:: console name: foo, metadata pool: foo_metadata, data pools: [foo_data ] @@ -192,16 +195,17 @@ Adoption process systemctl stop ceph-mds.target rm -rf /var/lib/ceph/mds/ceph-* -#. Redeploy Ceph Object Gateway RGW daemons if deployed. Cephadm manages RGW +#. Redeploy Ceph Object Gateway (RGW) daemons if deployed. Cephadm manages RGW daemons by zone. For each zone, deploy new RGW daemons with cephadm: .. prompt:: bash # ceph orch apply rgw [--realm=] [--zone=] [--port=] [--ssl] [--placement=] - where ** can be a simple daemon count, or a list of + where ```` can be a simple daemon count, or a list of specific hosts (see :ref:`orchestrator-cli-placement-spec`). The - zone and realm arguments are needed only for a multisite setup. + ``zone`` and ``realm`` arguments are needed only for a multisite setup + (see :ref:`multisite`). After the daemons have started and you have confirmed that they are functioning, stop and remove the legacy daemons: diff --git a/doc/cephadm/client-setup.rst b/doc/cephadm/client-setup.rst index 0f38773b12bd..4ca1e4c85ffe 100644 --- a/doc/cephadm/client-setup.rst +++ b/doc/cephadm/client-setup.rst @@ -1,6 +1,7 @@ ======================= Basic Ceph Client Setup ======================= + Client hosts require basic configuration to interact with Ceph clusters. This section describes how to perform this configuration. @@ -10,10 +11,10 @@ Ceph clusters. This section describes how to perform this configuration. ``rados`` commands, as well as other commands including ``mount.ceph`` and ``rbd``. + Config File Setup ================= -Client hosts usually require smaller configuration files (here -sometimes called "config files") than do back-end cluster hosts. + To generate a minimal config file, log into a host that has been configured as a client or that is running a cluster daemon, then run the following command: @@ -26,14 +27,16 @@ This command generates a minimal config file that tells the client how to reach the Ceph Monitors. This file should usually be copied to ``/etc/ceph/ceph.conf`` on each client host. + Keyring Setup ============= + Most Ceph clusters run with authentication enabled. This means that the client needs keys in order to communicate with Ceph daemons. To generate a keyring file with credentials for ``client.fs``, -log into an running cluster member and run the following command: +log into a running cluster member and run the following command: -.. prompt:: bash $ +.. prompt:: bash # ceph auth get-or-create client.fs @@ -44,6 +47,5 @@ To gain a broader understanding of client keyring distribution and administratio you should read :ref:`client_keyrings_and_configs`. To see an example that explains how to distribute ``ceph.conf`` configuration -files to hosts that are tagged with the ``bare_config`` label, you should read -the subsection named "Distributing ceph.conf to hosts tagged with bare_config" -under the heading :ref:`etc_ceph_conf_distribution`. +files to hosts that are tagged with the ``bare_config`` label, you should +read :ref:`ceph_conf_distribution_label`. diff --git a/doc/cephadm/compatibility.rst b/doc/cephadm/compatibility.rst index 8dd301f1a222..7ec373a541e0 100644 --- a/doc/cephadm/compatibility.rst +++ b/doc/cephadm/compatibility.rst @@ -34,12 +34,12 @@ This table shows which version pairs are expected to work or not work together: all Ceph versions, there are no known issues with using Podman version 3.0 or greater with Ceph Quincy and later releases. -.. warning:: +.. warning:: To use Podman with Ceph Pacific, you must use **a version of Podman that is 2.0.0 or higher**. However, **Podman version 2.2.1 does not work with Ceph Pacific**. - + "Kubic stable" is known to work with Ceph Pacific, but it must be run with a newer kernel. @@ -57,7 +57,7 @@ Cephadm support remains under development for the following features: - ceph-exporter deployment - stretch mode integration -- monitoring stack (moving towards prometheus service discover and providing TLS) +- monitoring stack (moving towards Prometheus service discovery and providing TLS) - RGW multisite deployment support (requires lots of manual steps currently) - cephadm agent diff --git a/doc/cephadm/host-management.rst b/doc/cephadm/host-management.rst index b25c476fda6a..9c65810fdb5e 100644 --- a/doc/cephadm/host-management.rst +++ b/doc/cephadm/host-management.rst @@ -13,33 +13,34 @@ Run a command of this form to list hosts associated with the cluster: ceph orch host ls [--format yaml] [--host-pattern ] [--label