[
  {
    "path": ".github/FUNDING.yml",
    "content": "github: [\"jschwe\"]\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "content": "name: Bug Report\ndescription: File a bug report\ntitle: \"[Bug]: \"\nlabels: [\"bug\", \"triage\"]\nassignees:\n  - jschwe\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for taking the time to fill out this bug report!\n  - type: textarea\n    attributes:\n      label: Current Behavior\n      description: A concise description of what you're experiencing.\n    validations:\n      required: false\n  - type: textarea\n    attributes:\n      label: Expected Behavior\n      description: A concise description of what you expected to happen.\n    validations:\n      required: false\n  - type: textarea\n    attributes:\n      label: Steps To Reproduce\n      description: Steps to reproduce the behavior.\n      placeholder: |\n        1. In this environment...\n        2. With this config...\n        3. Run '...'\n        4. See error...\n    validations:\n      required: false\n  - type: textarea\n    attributes:\n      label: Environment\n      description: |\n        examples:\n          - **OS**: Ubuntu 22.04\n          - **CMake**: 3.22.0\n          - **CMake Generator**: Ninja 1.11\n      value: |\n        - OS:\n        - CMake:\n        - CMake Generator:\n      render: markdown\n    validations:\n      required: false\n  - type: textarea\n    attributes:\n      label: CMake configure log with Debug log-level\n      description: |\n        Output when configuring with `cmake -S<source_dir> -B<build_dir> --log-level=DEBUG <your_other_options>`:\n        <details><summary>CMake configure log</summary>\n        <p>\n        \n        ```\n        <log>\n        ```\n        \n        </p>\n        </details>\n    validations:\n      required: false\n  - type: textarea\n    attributes:\n      label: CMake Build step log\n      description: |\n        Output when building with `cmake --build <build_dir> --verbose`:\n        <details><summary>CMake build log</summary>\n        <p>\n\n        ```\n        <log>\n        ```\n\n        </p>\n        </details>\n    validations:\n      required: false\n"
  },
  {
    "path": ".github/scripts/determine_compiler.sh",
    "content": "#!/usr/bin/env bash\n\ncompiler_kind=\"$1\"\nrunner_os=\"$2\"\ntarget_abi=\"$3\"\ntarget_system_name=\"$4\"\ntarget_arch=\"$5\"\n\nset -e\n\nif [[ -z \"$GITHUB_OUTPUT\" ]]; then\n  echo \"Error: This script should only be run in github actions environment\"\n  exit 1\nfi\nif [[ -z \"${runner_os}\" || -z \"${target_abi}\" || -z  \"${target_arch}\" ]]; then\n  echo \"Error: Not all required parameters where set\"\n  exit 1\nfi\nif [[ -z \"${compiler_kind}\" || \"${compiler_kind}\" == \"default\" ]]; then\n  echo \"compiler option was not set. Determining default compiler.\"\n  if [[ \"${runner_os}\" == \"Windows\" ]]; then\n    if [[ \"${target_abi}\" == \"msvc\" ]]; then\n      compiler_kind=msvc\n    elif [[ \"${target_abi}\" == \"gnu\" ]]; then\n      compiler_kind=gcc\n    else\n      echo \"Unknown abi for Windows: ${target_abi}\"\n      exit 1\n    fi\n  elif [[ \"${runner_os}\" == \"macOS\" ]]; then\n    compiler_kind=\"clang\"\n  elif [[ \"${runner_os}\" == \"Linux\" ]]; then\n    compiler_kind=\"gcc\"\n  else\n    echo \"Unknown Runner OS: ${runner_os}\"\n    exit 1\n  fi\nfi\necho \"Compiler Family: '${compiler_kind}'\"\n\nif [[ \"${compiler_kind}\" == \"clang\" ]]; then\n  c_compiler=\"clang\"\n  cxx_compiler=\"clang++\"\nelif [[ \"${compiler_kind}\" == \"msvc\" ]]; then\n  c_compiler=\"cl\"\n  cxx_compiler=\"cl\"\nelif [[ \"${compiler_kind}\" == \"gcc\" ]]; then\n  if [[ -z \"${target_system_name}\" ]]; then\n    c_compiler=\"gcc\"\n    cxx_compiler=\"g++\"\n  else\n    c_compiler=\"${target_arch}-linux-gnu-gcc\"\n    cxx_compiler=\"${target_arch}-linux-gnu-g++\"\n  fi\nfi\necho \"Chose C compiler: '${c_compiler}'\"\necho \"Chose C++ compiler: '${cxx_compiler}'\"\necho \"c_compiler=-DCMAKE_C_COMPILER=${c_compiler}\" >> $GITHUB_OUTPUT\necho \"cxx_compiler=-DCMAKE_CXX_COMPILER=${cxx_compiler}\" >> $GITHUB_OUTPUT\n"
  },
  {
    "path": ".github/scripts/toolchains/aarch64-apple-darwin-clang.cmake",
    "content": "set(CMAKE_C_COMPILER \"clang\")\nset(CMAKE_CXX_COMPILER \"clang++\")\nset(CMAKE_C_COMPILER_TARGET \"aarch64-apple-darwin\")\nset(CMAKE_CXX_COMPILER_TARGET \"aarch64-apple-darwin\")\nset(CMAKE_OSX_ARCHITECTURES \"arm64\" CACHE STRING \"\")\n"
  },
  {
    "path": ".github/scripts/toolchains/aarch64-unknown-linux-gnu-clang.cmake",
    "content": "set(CMAKE_C_COMPILER \"clang\")\nset(CMAKE_CXX_COMPILER \"clang++\")\nset(CMAKE_C_COMPILER_TARGET \"aarch64-linux-gnu\")\nset(CMAKE_CXX_COMPILER_TARGET \"aarch64-linux-gnu\")\n"
  },
  {
    "path": ".github/scripts/toolchains/aarch64-unknown-linux-gnu-gcc.cmake",
    "content": "set(CMAKE_C_COMPILER \"aarch64-linux-gnu-gcc\")\nset(CMAKE_CXX_COMPILER \"aarch64-linux-gnu-g++\")\nset(CMAKE_SYSTEM_NAME \"Linux\")\n"
  },
  {
    "path": ".github/scripts/toolchains/i686-unknown-linux-gnu-clang.cmake",
    "content": "set(CMAKE_C_COMPILER \"clang\")\nset(CMAKE_CXX_COMPILER \"clang++\")\nset(CMAKE_C_COMPILER_TARGET \"i686-pc-linux-gnu\")\nset(CMAKE_CXX_COMPILER_TARGET \"i686-pc-linux-gnu\")\n"
  },
  {
    "path": ".github/scripts/toolchains/i686-unknown-linux-gnu-gcc.cmake",
    "content": "set(CMAKE_C_COMPILER \"i686-linux-gnu-gcc\")\nset(CMAKE_CXX_COMPILER \"i686-linux-gnu-g++\")\nset(CMAKE_SYSTEM_NAME \"Linux\")\n"
  },
  {
    "path": ".github/scripts/toolchains/x86_64-apple-darwin-clang.cmake",
    "content": "set(CMAKE_C_COMPILER \"clang\")\nset(CMAKE_CXX_COMPILER \"clang++\")\nset(CMAKE_C_COMPILER_TARGET \"x86_64-apple-darwin\")\nset(CMAKE_CXX_COMPILER_TARGET \"x86_64-apple-darwin\")\nset(CMAKE_SYSTEM_NAME \"Darwin\")\nset(CMAKE_SYSTEM_VERSION ${CMAKE_HOST_SYSTEM_VERSION})\nset(CMAKE_OSX_ARCHITECTURES \"x86_64\" CACHE STRING \"\")\n"
  },
  {
    "path": ".github/scripts/toolchains/x86_64-pc-windows-gnullvm.cmake",
    "content": "set(CMAKE_C_COMPILER \"clang\")\nset(CMAKE_CXX_COMPILER \"clang++\")\nset(CMAKE_C_COMPILER_TARGET \"x86_64-pc-windows-gnu\")\nset(CMAKE_CXX_COMPILER_TARGET \"x86_64-pc-windows-gnu\")\n"
  },
  {
    "path": ".github/scripts/toolchains/x86_64-unknown-linux-gnu-clang.cmake",
    "content": "# Assumption: This is the native host target.\nset(CMAKE_C_COMPILER \"clang\")\nset(CMAKE_CXX_COMPILER \"clang++\")\n"
  },
  {
    "path": ".github/scripts/toolchains/x86_64-unknown-linux-gnu-gcc.cmake",
    "content": "# Assumption: This is the native host target.\nset(CMAKE_C_COMPILER \"gcc\")\nset(CMAKE_CXX_COMPILER \"g++\")\n"
  },
  {
    "path": ".github/workflows/gh-pages.yaml",
    "content": "name: Deploy GH pages\non:\n  push:\n    branches:\n      - master\n  # Allows you to run this workflow manually from the Actions tab\n  workflow_dispatch:\n\n# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages\npermissions:\n  contents: read\n  pages: write\n  id-token: write\n\n# Allow one concurrent deployment\nconcurrency:\n  group: \"pages\"\n  cancel-in-progress: true\n\njobs:\n  # Build and deploy the documentation of master and the stable/v0.5 branch\n  deploy:\n    runs-on: ubuntu-latest\n    environment:\n      name: github-pages\n      url: ${{ steps.deployment.outputs.page_url }}\n    steps:\n      - name: Install mdbook\n        env:\n          MDBOOK_VERSION: 'v0.4.27'\n        run: |\n          mkdir mdbook\n          curl -sSL https://github.com/rust-lang/mdBook/releases/download/${MDBOOK_VERSION}/mdbook-${MDBOOK_VERSION}-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook\n          echo `pwd`/mdbook >> $GITHUB_PATH\n      - name: Checkout master\n        uses: actions/checkout@v4\n        with:\n          path: main\n      - name: Checkout stable/v0.5\n        uses: actions/checkout@v4\n        with:\n          path: stable-v0.5\n          ref: 'stable/v0.5'\n      - name: Setup Pages\n        uses: actions/configure-pages@v5\n      - name: Build mdbook for main branch\n        working-directory: 'main/doc'\n        run: mdbook build\n      - name: Build mdbook for stable/v0.5 branch\n        working-directory: 'stable-v0.5/doc'\n        run: mdbook build\n      # Override mdbooks default highlight.js with a custom version containing CMake support.\n      - uses: actions/checkout@v4\n        with:\n          repository: 'highlightjs/highlight.js'\n          # mdbook currently (as of v0.4.27) does not support v11 yet.\n          ref: '10.7.3'\n          path: highlightjs\n      - name: Build custom highlight.js\n        run: |\n          npm install\n          node tools/build.js :common cmake yaml\n        working-directory: highlightjs\n      - name: Override highlightjs\n        run: |\n          cp highlightjs/build/highlight.min.js main/doc/book/highlight.js\n          cp highlightjs/build/highlight.min.js stable-v0.5/doc/book/highlight.js\n      - name: Copy stable doc into main\n        run: mkdir main/doc/book/v0.5 && cp -a stable-v0.5/doc/book/. main/doc/book/v0.5/\n      - name: Debug print\n        run: ls -la main/doc/book/v0.5\n      - name: Upload artifact\n        uses: actions/upload-pages-artifact@v3\n        with:\n          path: 'main/doc/book'\n      - name: Deploy to GitHub Pages\n        id: deployment\n        uses: actions/deploy-pages@v4\n"
  },
  {
    "path": ".github/workflows/linux.yaml",
    "content": "# Workflow file for Linux hosts\nname: Corrosion on Linux\non:\n  workflow_call:\n    inputs:\n      ubuntu_version:\n        required: false\n        type: string\n        default: \"latest\"\n      cmake:\n        required: false\n        type: string\n        default: \"3.22.6\"\n      generator:\n        required: true\n        type: string\n      c_compiler:\n        required: true\n        type: string\n      rust:\n        required: false\n        type: string\n        default: 1.46.0\n      target_arch:\n        required: false\n        type: string\n        default: x86_64\n\njobs:\n  linux:\n    name: Test Linux\n    runs-on: ubuntu-${{ inputs.ubuntu_version }}\n    steps:\n      - uses: actions/checkout@v4\n      - name: Install CMake\n        uses: lukka/get-cmake@519de0c7b4812477d74976b2523a9417f552d126\n        with:\n          cmakeVersion: \"${{ inputs.cmake }}\"\n          ninjaVersion: \"~1.10.0\"\n      - name: Install Rust\n        id: install_rust\n        uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{inputs.rust}}\n          targets: ${{inputs.target_arch}}-unknown-linux-gnu\n          components: rust-src\n      - name: Install Cross Compiler\n        shell: bash\n        run: |\n          echo \"::group::apt-install\"\n          sudo apt-get update\n          sudo apt-get install -y \"g++-${{inputs.target_arch}}-linux-gnu\"\n          echo \"::endgroup::\"\n        if: ${{ 'Linux' == runner.os && inputs.target_arch != 'x86_64' }}\n      - name: Configure Corrosion\n        run: cmake -S. -Bbuild -G \"${{ inputs.generator }}\" \"-DRust_TOOLCHAIN=${{steps.install_rust.outputs.name}}\" --preset \"${{ inputs.target_arch }}-unknown-linux-gnu-${{ inputs.c_compiler }}\"\n      - name: Run Tests\n        working-directory: build\n        run: ctest --output-on-failure --build-config Debug -j 3\n"
  },
  {
    "path": ".github/workflows/test.yaml",
    "content": "name: Tests\non:\n  push:\n    branches:\n      - master\n  pull_request:\n    branches:\n      - 'master'\n      - 'stable/**'\njobs:\n\n  visual_studio_base:\n    name: Test Visual Studio (base)\n    uses: ./.github/workflows/visual_studio.yaml\n    with:\n      vs_version: \"2022\"\n      rust: 1.46.0\n\n  visual_studio_stage2:\n    name: Test Visual Studio\n    uses: ./.github/workflows/visual_studio.yaml\n    needs:\n      - visual_studio_base\n    strategy:\n      matrix:\n        vs_version:\n          - \"2022\"\n        arch:\n          - x86_64\n          - i686\n          - aarch64\n        rust:\n          - \"1.54.0\"\n        include:\n          - arch: x86_64\n            vs_version: 2022\n            rust: stable\n          - arch: x86_64\n            vs_version: 2022\n            rust: nightly\n    with:\n      vs_version: \"${{ matrix.vs_version}}\"\n      rust: 1.54.0\n      target_arch: \"${{ matrix.arch}}\"\n\n  windows_ninja_cl:\n    name: Test Windows Ninja MSVC\n    runs-on: ${{ matrix.os }}\n    needs:\n      - visual_studio_base\n    strategy:\n      fail-fast: false\n      matrix:\n        os:\n          - windows-2022\n        arch:\n          - x86_64\n          - i686\n          - aarch64\n        compiler:\n          - cl\n          - clang-cl\n          - clang\n        include:\n          - os: windows-2022\n            vs_version: vs-2022\n            cmake: 3.22.6\n          - rust: 1.54.0\n          # Add variable mapping for ilammy/msvc-dev-cmd action\n          - arch: x86_64\n            msvc_dev_arch: amd64\n          - arch: i686\n            msvc_dev_arch: amd64_x86\n          - arch: aarch64\n            msvc_dev_arch: amd64_arm64\n        exclude:\n          # Not sure what parameters CMake needs when cross-compiling with clang-cl, so exclude for now\n          - compiler: clang-cl\n            arch: i686\n          - compiler: clang-cl\n            arch: aarch64\n          - compiler: clang\n            arch: i686\n          - compiler: clang\n            arch: aarch64\n\n    steps:\n      - uses: actions/checkout@v4\n      - name: Install CMake\n        uses: lukka/get-cmake@519de0c7b4812477d74976b2523a9417f552d126\n        with:\n          cmakeVersion: \"${{ matrix.cmake }}\"\n          ninjaVersion: \"~1.10.0\"\n      - name: Install Rust\n        id: install_rust\n        uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{matrix.rust}}\n          targets: ${{matrix.arch}}-pc-windows-msvc\n          components: rust-src\n      - name: Setup MSVC Development Environment\n        uses: ilammy/msvc-dev-cmd@v1\n        with:\n          arch: ${{ matrix.msvc_dev_arch }}\n      - name: Configure\n        run: cmake -S. -Bbuild \"-DRust_TOOLCHAIN=${{steps.install_rust.outputs.name}}\" --preset \"ninja-${{ matrix.arch }}-pc-windows-msvc-${{ matrix.compiler }}\"\n      - name: Run Tests\n        working-directory: build\n        run: ctest --output-on-failure --build-config Debug -j 3\n\n  windows_gnu:\n    name: Test Windows GNU\n    runs-on: ${{ matrix.os }}\n    strategy:\n      fail-fast: false\n      matrix:\n        os:\n          - windows-2022\n        arch:\n          - x86_64\n          # - i686\n          # - aarch64\n        compiler:\n          - gcc # Clang only has experimental support for Cygwin / MinGW, so we don't test it\n        generator:\n          - ninja\n          - make\n        include:\n          - cmake: 3.22.6\n          - rust: 1.54.0\n\n    steps:\n      - uses: actions/checkout@v4\n      - name: Install CMake\n        uses: lukka/get-cmake@519de0c7b4812477d74976b2523a9417f552d126\n        with:\n          cmakeVersion: \"${{ matrix.cmake }}\"\n          ninjaVersion: \"~1.10.0\"\n      - name: Install Rust\n        id: install_rust\n        uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{matrix.rust}}\n          targets: ${{matrix.arch}}-pc-windows-gnu\n          components: rust-src\n      - name: Configure\n        run: cmake -S. -Bbuild \"-DRust_TOOLCHAIN=${{steps.install_rust.outputs.name}}\" --preset \"${{ matrix.generator }}-${{ matrix.arch }}-pc-windows-gnu-${{ matrix.compiler }}\"\n      - name: Run Tests\n        working-directory: build\n        run: ctest --output-on-failure --build-config Debug -j 3\n\n  windows_gnullvm_msys2:\n    name: Test Windows gnullvm on msys2\n    runs-on: ${{ matrix.os }}\n    strategy:\n      fail-fast: false\n      matrix:\n        os:\n          - windows-2022\n        arch:\n          - x86_64\n          # - i686\n          # - aarch64\n        generator:\n          - Ninja\n          - MSYS Makefiles\n        include:\n          - arch: x86_64\n            msystem: CLANG64\n#          - arch: i686\n#            msystem: CLANG32\n#          - arch: aarch64\n#            msystem: CLANGARM64\n    defaults:\n      run:\n        shell: msys2 {0}\n    steps:\n      - uses: actions/checkout@v4\n      - name: Install Rust\n        id: install_rust\n        uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: stable\n          targets: ${{matrix.arch}}-pc-windows-gnullvm\n          components: rust-src\n      - uses: msys2/setup-msys2@v2\n        with:\n          msystem: ${{matrix.msystem}}\n          path-type: inherit\n          install: >-\n            git\n            make\n          pacboy: >-\n            toolchain:p\n            cmake:p\n            ninja:p\n      - name: Configure\n        run: cmake -S. -Bbuild -G \"${{matrix.generator}}\" --toolchain=.github/scripts/toolchains/${{matrix.arch}}-pc-windows-gnullvm.cmake\n      - name: Run Tests\n        working-directory: build\n        run: ctest --output-on-failure --build-config Debug -j 3\n\n# For now just test if hostbuild works when cross-compiling on windows.\n# For testing everything we would also need to install a cross-compiler first.\n  windows_cross_hostbuild:\n    name: Test Windows Cross\n    runs-on: windows-2022\n    steps:\n      - uses: actions/checkout@v4\n      - name: Install CMake\n        uses: lukka/get-cmake@519de0c7b4812477d74976b2523a9417f552d126\n        with:\n          cmakeVersion: \"~3.22.0\"\n          ninjaVersion: \"~1.10.0\"\n      - name: Install Rust\n        id: install_rust\n        uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: stable\n          targets: aarch64-unknown-linux-gnu\n          components: rust-src\n      - name: Configure\n        run: cmake -S. -Bbuild \"-DRust_TOOLCHAIN=${{steps.install_rust.outputs.name}}\" -DRust_CARGO_TARGET=aarch64-unknown-linux-gnu\n      - name: Run Tests\n        working-directory: build\n        run: ctest --output-on-failure --build-config Debug -R hostbuild\n\n  linux_base:\n    name: Test Linux (base)\n    uses: ./.github/workflows/linux.yaml\n    with:\n      c_compiler: \"gcc\"\n      generator: \"Ninja\"\n\n  linux_stage2:\n    name: Test Linux\n    needs:\n      - linux_base\n    uses: ./.github/workflows/linux.yaml\n    with:\n      target_arch: \"${{ matrix.arch }}\"\n      c_compiler: \"${{ matrix.compiler }}\"\n      generator: \"${{ matrix.generator }}\"\n    strategy:\n      fail-fast: false\n      matrix:\n        arch:\n          - x86_64\n          - i686\n          - aarch64\n        compiler:\n          - gcc\n        generator:\n          - \"Ninja\"\n          - \"Unix Makefiles\"\n        include:\n          # rustc doesn't support cross-compiling with clang out of the box, since\n          # clang requires a --target parameter. Corrosion currently can only pass\n          # this for the top-level crate, so linking of cdylibs that are built as\n          # dependencies of this crate will fail if they exist.\n          # Solutions would be to make cross-compiling with clang work out-of-the-box\n          # in rustc, or working around it in corrosion by adding a linker-wrapper.\n          # For this reason we only test clang with the host target for now.\n          - arch: x86_64\n            compiler: clang\n            generator: \"Ninja\"\n          - arch: x86_64\n            generator: \"Ninja Multi-Config\"\n            compiler: gcc\n\n  darwin:\n    name: Test MacOS\n    runs-on: ${{ matrix.os }}\n    strategy:\n      fail-fast: false\n      matrix:\n        arch:\n          - x86_64\n          - aarch64\n        compiler:\n          - clang\n        generator:\n          - \"Ninja\"\n          - \"Xcode\"\n        include:\n          - os: macos-latest\n          - cmake: 3.22.6\n          - rust: 1.54.0\n\n    steps:\n      - uses: actions/checkout@v4\n      - name: Install CMake\n        uses: lukka/get-cmake@519de0c7b4812477d74976b2523a9417f552d126\n        with:\n          cmakeVersion: \"${{ matrix.cmake }}\"\n          ninjaVersion: \"~1.10.0\"\n      # Install cbindgen before Rust to use recent default Rust version.\n      - name: Install cbindgen\n        run: cargo install cbindgen\n      - name: Install Rust\n        id: install_rust\n        uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{matrix.rust}}\n          targets: ${{matrix.arch}}-apple-darwin\n          components: rust-src\n      - name: Configure\n        run: cmake -S. -Bbuild --log-level=DEBUG -G \"${{ matrix.generator }}\" \"-DRust_TOOLCHAIN=${{steps.install_rust.outputs.name}}\" --preset \"${{ matrix.arch }}-apple-darwin-${{ matrix.compiler }}\"\n      - name: Run Tests\n        working-directory: build\n        run: ctest --output-on-failure --build-config Debug -j 3\n\n  iOS:\n    name: Test iOS (simulator)\n    runs-on: macos-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        generator:\n          - \"Ninja\"\n          - \"Xcode\"\n        include:\n          - os: macos-latest\n          - cmake: 3.24.0\n          - rust: stable\n\n    steps:\n      - uses: actions/checkout@v4\n      - name: Install CMake\n        uses: lukka/get-cmake@519de0c7b4812477d74976b2523a9417f552d126\n        with:\n          cmakeVersion: \"${{ matrix.cmake }}\"\n          ninjaVersion: \"~1.11.0\"\n      # Install cbindgen before Rust to use recent default Rust version.\n      - name: Install cbindgen\n        run: cargo install cbindgen\n      - name: Install Rust\n        id: install_rust\n        uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{matrix.rust}}\n          targets: aarch64-apple-ios-sim\n          components: rust-src\n      - name: Configure\n        run: cmake -S. -Bbuild --log-level=DEBUG -G \"${{ matrix.generator }}\" -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphonesimulator -DCMAKE_OSX_ARCHITECTURES=arm64 -DRust_TOOLCHAIN=${{steps.install_rust.outputs.name}} -DRust_CARGO_TARGET=aarch64-apple-ios-sim\n      - name: Run Tests\n        working-directory: build\n        run: ctest --output-on-failure --build-config Debug -j 3\n\n\n  test_cxxbridge:\n    name: Test cxxbridge integration\n    runs-on: ${{ matrix.os }}\n    strategy:\n      fail-fast: false\n      matrix:\n        os:\n          - windows-2022\n          - ubuntu-latest\n          - macos-15\n        include:\n          # Should be in sync with the `cxx` version the Carg.lock of the cxxbridge tests,\n          # otherwise the caching will not work and the cmd will be built from source.\n          - cxxbridge_version: \"1.0.86\"\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/cache@v4\n        id: cache_cxxbridge\n        with:\n          path: \"~/.cargo/bin/cxxbridge*\"\n          key: ${{ runner.os }}-cxxbridge_${{ matrix.cxxbridge_version }}\n      - name: Install cxxbridge\n        if: steps.cache_cxxbridge.outputs.cache-hit != 'true'\n        run: cargo install cxxbridge-cmd@${{ matrix.cxxbridge_version }}\n      - name: Install lld\n        run: sudo apt update && sudo apt install -y lld\n        if: ${{ 'Linux' == runner.os }}\n      - name: Setup MSVC Development Environment\n        uses: ilammy/msvc-dev-cmd@v1\n        if: runner.os == 'Windows'\n      - name: Install CMake\n        uses: lukka/get-cmake@519de0c7b4812477d74976b2523a9417f552d126\n        with:\n          cmakeVersion: \"~3.24.0\"\n          ninjaVersion: \"~1.10.0\"\n      - name: Install Rust\n        uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: stable minus 2 releases\n          components: rust-src\n      - name: Configure\n        run: >\n          cmake\n          -S.\n          -Bbuild\n          -GNinja\n          -DCORROSION_VERBOSE_OUTPUT=ON\n          -DCORROSION_TESTS_CXXBRIDGE=ON\n      - name: Run Tests\n        working-directory: build\n        run: ctest --output-on-failure --build-config Debug -j 3 -R \"^cxxbridge\"\n\n  autoinstall_cargo_target:\n    name: Test Auto-installing Cargo target via rustup\n    runs-on: ubuntu-22.04\n    steps:\n      - uses: actions/checkout@v4\n      - name: Install CMake\n        uses: lukka/get-cmake@519de0c7b4812477d74976b2523a9417f552d126\n      - name: Install Rust\n        id: install_rust\n        uses: dtolnay/rust-toolchain@stable\n      - name: Install Cross Compiler\n        shell: bash\n        run: |\n          echo \"::group::apt-install\"\n          sudo apt-get update\n          sudo apt-get install -y gcc-aarch64-linux-gnu\n          echo \"::endgroup::\"\n      - name: Assert rustup target is not installed\n        run: rustup show | ( ! grep aarch64)\n      - name: Configure Corrosion\n        run: cmake -S. -Bbuild -GNinja -DRust_RUSTUP_INSTALL_MISSING_TARGET=ON --preset \"aarch64-unknown-linux-gnu-gcc\"\n      - name: Check rustup target is installed after configuring\n        run: rustup show | grep aarch64\n\n  install:\n    name: Test Corrosion as a Library\n    runs-on: ${{ matrix.os }}\n    strategy:\n      fail-fast: false\n      matrix:\n        os:\n          - windows-2022\n          - ubuntu-latest\n          - macos-15\n        include:\n          - rust: 1.54.0\n\n    steps:\n      - uses: actions/checkout@v4\n      - name: Setup MSVC Development Environment\n        uses: ilammy/msvc-dev-cmd@v1\n        if: runner.os == 'Windows'\n      - name: Install CMake\n        uses: lukka/get-cmake@519de0c7b4812477d74976b2523a9417f552d126\n        with:\n          cmakeVersion: \"~3.22.0\"\n          ninjaVersion: \"~1.10.0\"\n      # Install cbindgen before Rust to use recent default Rust version.\n      - name: Install cbindgen\n        run: cargo install cbindgen\n      - name: Install Rust\n        uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{matrix.rust}}\n          components: rust-src\n      - name: Test Corrosion as installed module\n        run: >\n          cmake\n          -S.\n          -Bbuild\n          -GNinja\n          -DCORROSION_VERBOSE_OUTPUT=ON\n          -DCMAKE_BUILD_TYPE=Release\n          -DCORROSION_TESTS_INSTALL_CORROSION=ON\n          &&\n          cd build\n          &&\n          ctest --output-on-failure -C Release -j 3\n\n  # We want an \"accumulation\" job here because it is easier to specify required\n  # jobs here via needs, then in the github UI, since we use matrix jobs.\n  ci-success:\n    name: bors-ci-status\n    if: ${{ always() }}\n    needs:\n      - visual_studio_stage2\n      - windows_ninja_cl\n      - windows_gnu\n      - windows_gnullvm_msys2\n      - linux_stage2\n      - darwin\n      - iOS\n      - test_cxxbridge\n      - autoinstall_cargo_target\n      - install\n    runs-on: ubuntu-latest\n    # Step copied from: https://github.com/cross-rs/cross/blob/80c9f9109a719ffb0f694060ddc6e371d5b3a540/.github/workflows/ci.yml#L361\n    steps:\n      - name: Result\n        run: |\n          jq -C <<< \"${needs}\"\n          # Check if all needs were successful or skipped.\n          \"$(jq -r 'all(.result as $result | ([\"success\", \"skipped\"] | contains([$result])))' <<< \"${needs}\")\"\n        env:\n          needs: ${{ toJson(needs) }}\n\n"
  },
  {
    "path": ".github/workflows/visual_studio.yaml",
    "content": "name: Corrosion with Visual Studio\n\non:\n  workflow_call:\n    inputs:\n      vs_version:\n        required: true\n        type: string\n        default: 2022\n      cmake:\n        required: false\n        type: string\n        default: \"3.22.6\"\n      rust:\n        required: false\n        type: string\n        default: 1.46.0\n      target_arch:\n        required: false\n        type: string\n        default: x86_64\n\njobs:\n  visual_studio:\n    name: Test Visual Studio ${{ inputs.vs_version }}\n    runs-on: \"windows-${{ inputs.vs_version }}\"\n    steps:\n      - uses: actions/checkout@v4\n      - name: Install CMake\n        uses: lukka/get-cmake@519de0c7b4812477d74976b2523a9417f552d126\n        with:\n          cmakeVersion: \"${{ inputs.cmake }}\"\n          ninjaVersion: \"~1.10.0\"\n      - name: Install Rust\n        id: install_rust\n        uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{inputs.rust}}\n          targets: ${{inputs.target_arch}}-pc-windows-msvc\n          components: rust-src\n      # The initial configure for MSVC is quite slow, so we cache the build directory\n      # (including the build directories of the tests) since reconfiguring is\n      # significantly faster.\n      # - name: Cache MSVC build directory\n      #   id: cache-msvc-builddir\n      #   uses: actions/cache@v4\n      #   with:\n      #     path: build\n      #     key: ${{ inputs.os }}-${{ inputs.target_arch }}-${{ inputs.rust }}-msvc-${{ inputs.vs_version}}-build\n      - name: Configure\n        run: cmake -S. -Bbuild -DCORROSION_TESTS_KEEP_BUILDDIRS=ON \"-DRust_TOOLCHAIN=${{steps.install_rust.outputs.name}}\" --preset \"vs-${{ inputs.vs_version }}-${{ inputs.target_arch }}\"\n      - name: Run Tests\n        working-directory: build\n        run: ctest --output-on-failure --build-config Debug -j 3\n"
  },
  {
    "path": ".gitignore",
    "content": "\n**/target/\n**/*.rs.bk\nbuild*/\n.vscode\n.idea\ncmake-build-*\ntest/test_header.cmake\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.22)\nproject(Corrosion\n    VERSION 0.6.1\n    LANGUAGES NONE\n    HOMEPAGE_URL \"https://corrosion-rs.github.io/corrosion/\"\n)\n\n# ==== Corrosion Configuration ====\n\noption(\n    CORROSION_BUILD_TESTS\n    \"Build Corrosion test project\"\n    ${PROJECT_IS_TOP_LEVEL}\n)\n\nif (PROJECT_IS_TOP_LEVEL)\n    # We need to enable a language for corrosions test to work.\n    # For projects using corrosion this is not needed\n    enable_language(C)\nendif()\n\n# This little bit self-hosts the Corrosion toolchain to build the generator\n# tool.\n#\n# It is strongly encouraged to install Corrosion separately and use\n# `find_package(Corrosion REQUIRED)` instead if that works with your workflow.\noption(CORROSION_INSTALL_ONLY \"Only add rules for installing Corrosion itself.\" OFF)\nif (NOT CORROSION_INSTALL_ONLY)\n    list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)\n    include(Corrosion)\nendif()\n\n# Testing\nif (CORROSION_BUILD_TESTS)\n    include(CTest)\n    add_subdirectory(test)\nendif()\n\n# If Corrosion is a subdirectory, do not enable its install code\nif (NOT PROJECT_IS_TOP_LEVEL)\n    return()\nendif()\n\n# Installation\n\ninclude(GNUInstallDirs)\n\n# Generate the Config file\ninclude(CMakePackageConfigHelpers)\n\nconfigure_package_config_file(\n    cmake/CorrosionConfig.cmake.in CorrosionConfig.cmake\n    INSTALL_DESTINATION\n        \"${CMAKE_INSTALL_FULL_LIBDIR}/cmake/Corrosion\"\n)\n\nwrite_basic_package_version_file(\n    \"${CMAKE_CURRENT_BINARY_DIR}/CorrosionConfigVersion.cmake\"\n    VERSION ${PROJECT_VERSION}\n    COMPATIBILITY\n        SameMajorVersion\n    ARCH_INDEPENDENT\n)\n\ninstall(\n    FILES\n        \"${CMAKE_CURRENT_BINARY_DIR}/CorrosionConfig.cmake\"\n        \"${CMAKE_CURRENT_BINARY_DIR}/CorrosionConfigVersion.cmake\"\n    DESTINATION\n        \"${CMAKE_INSTALL_FULL_LIBDIR}/cmake/Corrosion\"\n)\n\n# These CMake scripts are needed both for the install and as a subdirectory\ninstall(\n    FILES\n        cmake/Corrosion.cmake\n        cmake/CorrosionGenerator.cmake\n        cmake/FindRust.cmake\n    DESTINATION\n        \"${CMAKE_INSTALL_FULL_DATADIR}/cmake\"\n)\n"
  },
  {
    "path": "CMakePresets.json",
    "content": "{\n    \"version\": 3,\n    \"cmakeMinimumRequired\": {\n        \"major\": 3,\n        \"minor\": 22,\n        \"patch\": 0\n    },\n    \"configurePresets\": [\n        {\n            \"name\": \"ninja\",\n            \"hidden\": true,\n            \"generator\": \"Ninja\"\n        },\n        {\n            \"name\": \"ninja-mc\",\n            \"hidden\": true,\n            \"generator\": \"Ninja Multi-Config\"\n        },\n        {\n            \"name\": \"make\",\n            \"hidden\": true,\n            \"generator\": \"Unix Makefiles\"\n        },\n        {\n            \"name\": \"vs-2019\",\n            \"hidden\": true,\n            \"generator\": \"Visual Studio 16 2019\"\n        },\n        {\n            \"name\": \"vs-2022\",\n            \"hidden\": true,\n            \"generator\": \"Visual Studio 17 2022\"\n        },\n        {\n            \"name\": \"windows-only\",\n            \"hidden\": true,\n            \"condition\": {\n                \"type\": \"equals\",\n                \"lhs\": \"${hostSystemName}\",\n                \"rhs\": \"Windows\"\n            }\n        },\n        {\n            \"name\": \"windows-10-cross\",\n            \"hidden\": true,\n            \"cacheVariables\": {\n                \"CMAKE_SYSTEM_NAME\": \"Windows\",\n                \"CMAKE_SYSTEM_VERSION\": \"10.0\"\n            },\n            \"condition\": {\n                \"type\": \"equals\",\n                \"lhs\": \"${hostSystemName}\",\n                \"rhs\": \"Windows\"\n            }\n        },\n        {\n            \"name\": \"x86_64-pc-windows-msvc\",\n            \"hidden\": true,\n            \"inherits\": [\"windows-only\"],\n            \"cacheVariables\": {\n                \"Rust_CARGO_TARGET\": \"x86_64-pc-windows-msvc\"\n            }\n        },\n        {\n            \"name\": \"i686-pc-windows-msvc\",\n            \"hidden\": true,\n            \"cacheVariables\": {\n                \"Rust_CARGO_TARGET\": \"i686-pc-windows-msvc\"\n            }\n        },\n        {\n            \"name\": \"aarch64-pc-windows-msvc\",\n            \"hidden\": true,\n            \"cacheVariables\": {\n                \"Rust_CARGO_TARGET\": \"aarch64-pc-windows-msvc\"\n            }\n        },\n        {\n            \"name\": \"x86_64-unknown-linux-gnu\",\n            \"hidden\": true,\n            \"cacheVariables\": {\n                \"Rust_CARGO_TARGET\": \"x86_64-unknown-linux-gnu\"\n            }\n        },\n        {\n            \"name\": \"i686-unknown-linux-gnu\",\n            \"hidden\": true,\n            \"cacheVariables\": {\n                \"Rust_CARGO_TARGET\": \"i686-unknown-linux-gnu\"\n            }\n        },\n        {\n            \"name\": \"aarch64-unknown-linux-gnu\",\n            \"hidden\": true,\n            \"cacheVariables\": {\n                \"Rust_CARGO_TARGET\": \"aarch64-unknown-linux-gnu\"\n            }\n        },\n        {\n            \"name\": \"x86_64-apple-darwin\",\n            \"hidden\": true,\n            \"cacheVariables\": {\n                \"Rust_CARGO_TARGET\": \"x86_64-apple-darwin\"\n            }\n        },\n        {\n            \"name\": \"aarch64-apple-darwin\",\n            \"hidden\": true,\n            \"cacheVariables\": {\n                \"Rust_CARGO_TARGET\": \"aarch64-apple-darwin\"\n            }\n        },\n        {\n            \"name\": \"vs-platform-arm64\",\n            \"hidden\": true,\n            \"inherits\": [\"aarch64-pc-windows-msvc\",\"windows-10-cross\"],\n            \"architecture\": {\n                \"value\": \"ARM64\"\n            }\n        },\n        {\n            \"name\": \"vs-platform-x64\",\n            \"hidden\": true,\n            \"inherits\": [\"x86_64-pc-windows-msvc\"],\n            \"architecture\": {\n                \"value\": \"x64\"\n            }\n        },\n        {\n            \"name\": \"vs-platform-i686\",\n            \"hidden\": true,\n            \"inherits\": [\"i686-pc-windows-msvc\", \"windows-10-cross\"],\n            \"architecture\": {\n                \"value\": \"Win32\"\n            }\n        },\n        {\n            \"name\": \"vs-2019-x86_64\",\n            \"inherits\": [\"vs-platform-x64\", \"vs-2019\"]\n        },\n        {\n            \"name\": \"vs-2022-x86_64\",\n            \"inherits\": [\"vs-platform-x64\", \"vs-2022\"]\n        },\n        {\n            \"name\": \"vs-2019-i686\",\n            \"inherits\": [\"vs-platform-i686\", \"vs-2019\"]\n        },\n        {\n            \"name\": \"vs-2022-i686\",\n            \"inherits\": [\"vs-platform-i686\", \"vs-2022\"]\n        },\n        {\n            \"name\": \"vs-2019-aarch64\",\n            \"inherits\": [\"vs-platform-arm64\", \"vs-2019\"]\n        },\n        {\n            \"name\": \"vs-2022-aarch64\",\n            \"inherits\": [\"vs-platform-arm64\", \"vs-2022\"]\n        },\n        {\n            \"name\": \"clang\",\n            \"hidden\": true,\n            \"cacheVariables\": {\n                \"CMAKE_C_COMPILER\": \"clang\",\n                \"CMAKE_CXX_COMPILER\": \"clang++\"\n            }\n        },\n        {\n            \"name\": \"host-gcc\",\n            \"hidden\": true,\n            \"cacheVariables\": {\n                \"CMAKE_C_COMPILER\": \"gcc\",\n                \"CMAKE_CXX_COMPILER\": \"g++\"\n            }\n        },\n        {\n            \"name\": \"clang-cl\",\n            \"hidden\": true,\n            \"inherits\": [\"windows-only\"],\n            \"cacheVariables\": {\n                \"CMAKE_C_COMPILER\": \"clang-cl\",\n                \"CMAKE_CXX_COMPILER\": \"clang-cl\"\n            }\n        },\n        {\n            \"name\": \"cl\",\n            \"hidden\": true,\n            \"inherits\": [\"windows-only\"],\n            \"cacheVariables\": {\n                \"CMAKE_C_COMPILER\": \"cl\",\n                \"CMAKE_CXX_COMPILER\": \"cl\"\n            }\n        },\n        {\n            \"name\": \"ninja-x86_64-pc-windows-msvc-cl\",\n            \"inherits\": [\"ninja\", \"x86_64-pc-windows-msvc\", \"cl\"]\n        },\n        {\n            \"name\": \"ninja-x86_64-pc-windows-msvc-clang-cl\",\n            \"inherits\": [\"ninja\", \"x86_64-pc-windows-msvc\", \"clang-cl\"]\n        },\n        {\n            \"name\": \"ninja-x86_64-pc-windows-msvc-clang\",\n            \"inherits\": [\"ninja\", \"x86_64-pc-windows-msvc\", \"clang\"]\n        },\n        {\n            \"name\": \"ninja-i686-pc-windows-msvc-cl\",\n            \"inherits\": [\"ninja\", \"i686-pc-windows-msvc\", \"cl\", \"windows-10-cross\"]\n        },\n        {\n            \"name\": \"ninja-i686-pc-windows-msvc-clang-cl\",\n            \"inherits\": [\"ninja\", \"i686-pc-windows-msvc\", \"clang-cl\", \"windows-10-cross\"]\n        },\n        {\n            \"name\": \"ninja-i686-pc-windows-msvc-clang\",\n            \"inherits\": [\"ninja\", \"i686-pc-windows-msvc\", \"clang\", \"windows-10-cross\"]\n        },\n        {\n            \"name\": \"ninja-aarch64-pc-windows-msvc-cl\",\n            \"inherits\": [\"ninja\", \"aarch64-pc-windows-msvc\", \"cl\", \"windows-10-cross\"]\n        },\n        {\n            \"name\": \"ninja-aarch64-pc-windows-msvc-clang-cl\",\n            \"inherits\": [\"ninja\", \"aarch64-pc-windows-msvc\", \"clang-cl\", \"windows-10-cross\"]\n        },\n        {\n            \"name\": \"ninja-aarch64-pc-windows-msvc-clang\",\n            \"inherits\": [\"ninja\", \"aarch64-pc-windows-msvc\", \"clang\", \"windows-10-cross\"]\n        },\n        {\n            \"name\": \"ninja-x86_64-pc-windows-gnullvm\",\n            \"inherits\": [\"ninja\", \"windows-only\", \"clang\"],\n            \"toolchainFile\": \"${sourceDir}/.github/scripts/toolchains/x86_64-pc-windows-gnullvm.cmake\"\n        },\n        {\n            \"name\": \"make-x86_64-pc-windows-gnullvm\",\n            \"inherits\": [\"make\", \"windows-only\", \"clang\"],\n            \"toolchainFile\": \"${sourceDir}/.github/scripts/toolchains/x86_64-pc-windows-gnullvm.cmake\"\n        },\n        {\n            \"name\": \"ninja-x86_64-pc-windows-gnu-gcc\",\n            \"inherits\": [\"ninja\", \"host-gcc\", \"windows-only\"]\n        },\n        {\n            \"name\": \"make-x86_64-pc-windows-gnu-gcc\",\n            \"inherits\": [\"make\", \"host-gcc\", \"windows-only\"]\n        },\n        {\n            \"name\": \"x86_64-unknown-linux-gnu-clang\",\n            \"inherits\": [\"x86_64-unknown-linux-gnu\"],\n            \"toolchainFile\": \"${sourceDir}/.github/scripts/toolchains/${presetName}.cmake\"\n        },\n        {\n            \"name\": \"x86_64-unknown-linux-gnu-gcc\",\n            \"inherits\": [\"x86_64-unknown-linux-gnu\"],\n            \"toolchainFile\": \"${sourceDir}/.github/scripts/toolchains/${presetName}.cmake\"\n        },\n        {\n            \"name\": \"i686-unknown-linux-gnu-clang\",\n            \"inherits\": [\"i686-unknown-linux-gnu\"],\n            \"toolchainFile\": \"${sourceDir}/.github/scripts/toolchains/${presetName}.cmake\"\n        },\n        {\n            \"name\": \"i686-unknown-linux-gnu-gcc\",\n            \"inherits\": [\"i686-unknown-linux-gnu\"],\n            \"toolchainFile\": \"${sourceDir}/.github/scripts/toolchains/${presetName}.cmake\"\n        },\n        {\n            \"name\": \"aarch64-unknown-linux-gnu-clang\",\n            \"inherits\": [\"aarch64-unknown-linux-gnu\"],\n            \"toolchainFile\": \"${sourceDir}/.github/scripts/toolchains/${presetName}.cmake\"\n        },\n        {\n            \"name\": \"aarch64-unknown-linux-gnu-gcc\",\n            \"inherits\": [\"aarch64-unknown-linux-gnu\"],\n            \"toolchainFile\": \"${sourceDir}/.github/scripts/toolchains/${presetName}.cmake\"\n        },\n        {\n            \"name\": \"x86_64-apple-darwin-clang\",\n            \"inherits\": [\"x86_64-apple-darwin\", \"clang\"],\n            \"toolchainFile\": \"${sourceDir}/.github/scripts/toolchains/${presetName}.cmake\"\n        },\n        {\n            \"name\": \"aarch64-apple-darwin-clang\",\n            \"inherits\": [\"aarch64-apple-darwin\"],\n            \"toolchainFile\": \"${sourceDir}/.github/scripts/toolchains/${presetName}.cmake\"\n        }\n    ]\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2018 Andrew Gaspar\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Corrosion\n[![Build Status](https://github.com/corrosion-rs/corrosion/actions/workflows/test.yaml/badge.svg)](https://github.com/corrosion-rs/corrosion/actions?query=branch%3Amaster)\n[![Documentation](https://img.shields.io/badge/docs-latest-blue.svg)](https://corrosion-rs.github.io/corrosion/)\n![License](https://img.shields.io/badge/license-MIT-blue)\n\nCorrosion, formerly known as cmake-cargo, is a tool for integrating Rust into an existing CMake\nproject. Corrosion can automatically import executables, static libraries, and dynamic libraries\nfrom a workspace or package manifest (`Cargo.toml` file).\n\n## Features\n- Automatic Import of Executable, Static, and Shared Libraries from Rust Crate\n- Easy Installation of Rust Executables\n- Trivially Link Rust Executables to C/C++ Libraries in Tree\n- Multi-Config Generator Support\n- Simple Cross-Compilation\n\n## Sample Usage with FetchContent\n\nUsing the CMake `FetchContent` module allows you to easily integrate corrosion into your build.\nOther methods including installing corrosion or adding it as a subdirectory are covered in the\n[setup chapter](https://corrosion-rs.github.io/corrosion/setup_corrosion.html) of the \ncorrosion [documentation](https://corrosion-rs.github.io/corrosion/).\n\n```cmake\ninclude(FetchContent)\n\nFetchContent_Declare(\n    Corrosion\n    GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git\n    GIT_TAG v0.6 # Optionally specify a commit hash, version tag or branch here\n)\nFetchContent_MakeAvailable(Corrosion)\n\n# Import targets defined in a package or workspace manifest `Cargo.toml` file\ncorrosion_import_crate(MANIFEST_PATH rust-lib/Cargo.toml)\n\nadd_executable(your_cpp_bin main.cpp)\ntarget_link_libraries(your_cpp_bin PUBLIC rust-lib)\n```\n\n## Requirements\n\n### v0.6 Release\n\n- CMake 3.22 or newer\n\n### v0.5 Release (Critical backports only)\n\n- CMake 3.15 or newer. Some features may only be available on more recent CMake versions\n- Rust 1.46 or newer. Some platforms / features may require more recent Rust versions\n"
  },
  {
    "path": "RELEASES.md",
    "content": "# v0.6.1 (2025-01-17)\n\n## Fixes\n\n- Fix building shared libraries for iOS.\n- Fix host linker detection for iOS and add the `CORROSION_HOST_TARGET_LINKER` cache variable,\n  to allow users to override the linker used for the host build (required for build-scripts and proc-macros).\n\n# v0.6.0 (2025-11-23)\n\n### Breaking Changes\n\n- Corrosion now requires CMake 3.22. See also the \n  [v0.4.0 Release notes](#040-lts-2023-06-01) for more details.\n- Removed native tooling and the corresponding option `CORROSION_NATIVE_TOOLING`.\n  Corrosion now always uses pure CMake.\n- Fix Corrosion placing artifacts into the wrong directory when:\n  1. using a Multi-Config Generator (e.g Visual Studio or XCode) AND\n  2. `OUTPUT_DIRECTORY_<CONFIG>` is not set AND \n  3. `OUTPUT_DIRECTORY` is set AND\n  4. `OUTPUT_DIRECTORY` does not contain a generator expression\n\n  Corrosion now places artifacts into a `$<CONFIG>` subdirectory of the\n  specified `OUTPUT_DIRECTORY`. This matches the [documented behavior][doc-cmake-rt-output-dir]\n  of CMake for regular CMake targets. ([#568]).\n\n### New features\n\n- Support using the `$<CONFIG>` generator expression in `OUTPUT_DIRECTORY`. [#459]\n- Add `OVERRIDE_CRATE_TYPE` option to corrosion_import_crate, allowing users to override\n  the crate-types of Rust libraries (e.g. force building as a staticlib instead of an rlib).\n- Support *-windows-gnullvm targets. \n- experimental support in corrosion_install for installing libraries and header files\n- Add `CORROSION_TOOLS_RUST_TOOLCHAIN` cache variable which allows users to select a different\n  rust toolchain for compiling build-tools used by corrosion (currently cbindgen and cxxbridge).\n  This mainly allows using a newer toolchain for such build-tools then for the actual project.\n- Initial support for iOS targets [#636](https://github.com/corrosion-rs/corrosion/pull/636)\n\n[doc-cmake-rt-output-dir]: https://cmake.org/cmake/help/latest/prop_tgt/RUNTIME_OUTPUT_DIRECTORY.html\n[#459]: https://github.com/corrosion-rs/corrosion/pull/459\n[#568]: https://github.com/corrosion-rs/corrosion/pull/568\n\n# v0.5.1 (2024-12-29)\n\n### Fixes\n\n- Update FindRust to support `rustup` v1.28.0. Support for older rustup versions is retained,\n  so updating corrosion quickly is recommended to all rustup users.\n\n\n# v0.5.0 (2024-05-11)\n\n### Breaking Changes\n\n- Dashes (`-`) in names of imported CMake **library** targets are now replaced with underscores (`_`).\n  See [issue #501] for details. Users on older Corrosion versions will experience the same\n  change when using Rust 1.79 or newer. `bin` targets are not affected by this change.\n\n[issue #501]: https://github.com/corrosion-rs/corrosion/issues/501\n\n# v0.4.10 (2024-05-11)\n\n### New features\n\n- `corrosion_experimental_cbindgen()` can now be called multiple times on the same Rust target,\n  as long as the output header name differs. This may be useful to generate separate C and C++\n  bindings. [#507]\n- If `corrosion_link_libraries()` is called on a Rust static library target, then\n  `target_link_libraries()` is called to propagate the dependencies to C/C++ consumers.\n  Previously a warning was emitted in this case and the arguments ignored. [#506]\n\n### Fixes\n\n- Combine `-framework` flags on macos to avoid linker deduplication errors [#455]\n- `corrosion_experimental_cbindgen()` will now correctly use the package name, instead of assuming that\n  the package and crate name are identical. ([11e27c])\n- Set the `AR_<triple>` variable for `cc-rs` (except for msvc targets) [#456]\n- Fix hostbuild when cross-compiling to windows [#477]\n- Consider vworks executable suffix [#504]\n- `corrosion_experimental_cbindgen()` now forwards the Rust target-triple (e.g. `aarch64-unknown-linux-gnu`)\n  to cbindgen via the `TARGET` environment variable. The `hostbuild` property is considered. [#507]\n- Fix linking errors with Rust >= 1.79 and `-msvc` targets.` [#511]\n\n\n[#455]: https://github.com/corrosion-rs/corrosion/pull/455\n[#456]: https://github.com/corrosion-rs/corrosion/pull/456\n[#477]: https://github.com/corrosion-rs/corrosion/pull/477\n[#504]: https://github.com/corrosion-rs/corrosion/pull/504\n[#506]: https://github.com/corrosion-rs/corrosion/pull/506\n[#507]: https://github.com/corrosion-rs/corrosion/pull/507\n[#511]: https://github.com/corrosion-rs/corrosion/pull/511\n[11e27c]: https://github.com/corrosion-rs/corrosion/pull/514/commits/11e27cde2cf32c7ed539c96eb03c2f10035de538\n\n# v0.4.9 (2024-05-01)\n\n### New Features \n\n- Automatically detect Rust target for OpenHarmony ([#510]).\n\n### Fixes\n\n- Make find_package portable ([#509]).\n\n[#510]: https://github.com/corrosion-rs/corrosion/pull/510\n[#509]: https://github.com/corrosion-rs/corrosion/pull/509\n\n# v0.4.8 (2024-04-03)\n\n### Fixes\n\n- Fix an internal error when passing both the `PROFILE` and `CRATES` option to\n  `corrosion_import_crate()` ([#496]).\n\n[#496]: https://github.com/corrosion-rs/corrosion/pull/496\n\n# v0.4.7 (2024-01-19)\n\n### Fixes\n\n- The C/C++ compiler passed from corrosion to `cc-rs` can now be overridden by users setting\n  `CC_<target>` (e.g. `CC_x86_64-unknown-linux-gnu=/path/to/my-compiler`) environment variables ([#475]).\n\n[#475]: https://github.com/corrosion-rs/corrosion/pull/475\n\n# v0.4.6 (2024-01-17)\n\n### Fixes\n\n- Fix hostbuild executables when cross-compiling from non-windows to windows targets.\n  (Only with CMake >= 3.19).\n\n# v0.4.5 (2023-11-30)\n\n### Fixes\n\n- Fix hostbuild executables when cross-compiling on windows to non-windows targets\n  (Only with CMake >= 3.19).\n\n# v0.4.4 (2023-10-06)\n\n### Fixes\n\n- Add `chimera` ([#445]) and `unikraft` ([#446]) to the list of known vendors\n\n[#445]: https://github.com/corrosion-rs/corrosion/pull/445\n[#446]: https://github.com/corrosion-rs/corrosion/pull/446\n\n# v0.4.3 (2023-09-09)\n\n### Fixes\n\n- Fix the PROFILE option with CMake < 3.19 [#427]\n- Relax vendor parsing for espressif targets (removes warnings)\n- Fix an issue detecting required link libraries with Rust >= 1.71\n  when the cmake build directory is located in a Cargo workspace.\n\n# 0.4.2 (2023-07-16)\n\n### Fixes\n\n- Fix an issue when cross-compiling with clang\n- Fix detecting required libraries with cargo 1.71 \n\n### New features\n\n- Users can now set `Rust_RESOLVE_RUSTUP_TOOLCHAINS` to `OFF`, which will result in Corrosion\n  not attempting to resolve rustc/cargo.\n\n# 0.4.1 (2023-06-03)\n\nThis is a bugfix release.\n\n### Fixes\n\n- Fixes a regression on multi-config Generators\n\n# 0.4.0 LTS (2023-06-01)\n\nNo changes compared to v0.4.0-beta2.\n\n## Announcements\n\nThe `v0.4.x` LTS series will be the last release to support older CMake and Rust versions.\nIf necessary, fixes will be backported to the v0.4 branch. New features will not be\nactively backported after the next major release, but community contributions are possible.\nThe `v0.4.x` series is currently planned to be maintained until the end of 2024.\n\nThe following major release will increase the minimum required CMake version to 3.22. The \nminimum supported Rust version will also be increased to make use of newly added flags, but \nthe exact version is not fixed yet. \n\n\n## Changes compared to v0.3.5:\n\n### Breaking Changes\n\n- The Visual Studio Generators now require at least CMake 3.20.\n  This was previously announced in the 0.3.0 release notes and is the same\n  requirement as for the other Multi-Config Generators.\n- The previously deprecated function `corrosion_set_linker_language()`\n  will now raise an error when called and may be removed without further\n  notice in future stable releases. Use `corrosion_set_linker()` instead.\n- Improved the FindRust target triple detection, which may cause different behavior in some cases.\n  The detection does not require an enabled language anymore and will always fall back\n  to the default host target triple. A warning is issued if target triple detection failed.\n\n### Potentially Breaking Changes\n\n- Corrosion now sets the `IMPORTED_NO_SONAME` property for shared rust libraries, since by\n  default they won't have an `soname` field.\n  If you add a rustflag like `-Clink-arg=-Wl,-soname,libmycrate.so` in your project,\n  you should set this property to false on the shared rust library.\n- Corrosion now uses a mechanism to determine which native libraries need to be linked with\n  Rust `staticlib` targets into C/C++ targets. The previous mechanism contained a hardcoded list.\n  The new mechanism asks `rustc` which libraries are needed at minimum for a given\n  target triple (with `std` support). This should not be a breaking change, but if you\n  do encounter a new linking issue when upgrading with `staticlib` targets, please open an\n  issue.\n\n### New features\n\n- `corrosion_import_crate()` has two new options `LOCKED` and `FROZEN` which pass the \n  `--locked` and `--frozen` flags to all invocations of cargo.\n- `FindRust` now provides cache variables containing information on the default host\n  target triple:\n  - `Rust_CARGO_HOST_ARCH`\n  - `Rust_CARGO_HOST_VENDOR`\n  - `Rust_CARGO_HOST_OS`\n  - `Rust_CARGO_HOST_ENV`\n\n### Other changes\n\n- When installing Corrosion with CMake >= 3.19, the legacy Generator tool is\n  no longer built and installed by default.\n- Corrosion now issues a warning when setting the linker or setting linker\n  options for a Rust static library.\n- Corrosion no longer enables the `C` language when CMake is in crosscompiling mode and\n  no languages where previously enabled. This is not considered a breaking change.\n- `corrosion_import_crate()` now warns about unexpected arguments.\n\n### Fixes\n\n- Fix building when the `dev` profile is explicitly set by the user.\n\n## Experimental features (may be changed or removed without a major version bump)\n\n- Experimental cxxbridge and cbindgen integration.\n- Add a helper function to parse the package version from a Cargo.toml file\n- Expose rustup toolchains discovered by `FindRust` in the following cache variables\n  which contain a list.\n  - `Rust_RUSTUP_TOOLCHAINS`: List of toolchains names\n  - `Rust_RUSTUP_TOOLCHAINS_VERSION`: List of `rustc` version of the toolchains\n  - `Rust_RUSTUP_TOOLCHAINS_RUSTC_PATH`: List of the path to `rustc`\n  - `Rust_RUSTUP_TOOLCHAINS_CARGO_PATH`: List of the path to `cargo`. Entries may be `NOTFOUND` if cargo\n    is not available for that toolchain.\n- Add target properties `INTERFACE_CORROSION_RUSTC` and `INTERFACE_CORROSION_CARGO`, which may\n  be set to paths to `rustc` and `cargo` respectively to override the toolchain for a specific\n  target.\n\n# 0.3.5 (2023-03-19)\n\n- Fix building the Legacy Generator on Rust toolchains < 1.56 ([#365])\n\n[#365]: https://github.com/corrosion-rs/corrosion/pull/365\n\n# 0.3.4 (2023-03-02)\n\n## Fixes\n\n- Fix hostbuild (when CMake/Cargo is configured for cross-compiling) if clang is used ([#338]).\n\n## Other\n\n- Pass `--no-deps` to cargo metadata ([#334]).\n- Bump the legacy generator dependencies\n\n[#334]: https://github.com/corrosion-rs/corrosion/pull/334\n[#338]: https://github.com/corrosion-rs/corrosion/pull/338\n\n\n# 0.3.3 (2023-02-17)\n\n## New features (Only available on CMake >= 3.19)\n\n- Add new `IMPORTED_CRATES` flag to `corrosion_import_crate()` to retrieve the list of imported crates in the current\n  scope ([#312](https://github.com/corrosion-rs/corrosion/pull/312)).\n\n## Fixes\n\n- Fix imported location target property when the rust target name contains dashes\n  and a custom OUTPUT_DIRECTORY was specified by the user ([#322](https://github.com/corrosion-rs/corrosion/pull/322)).\n- Fix building for custom rust target-triples ([#316](https://github.com/corrosion-rs/corrosion/pull/316))\n\n# 0.3.2 (2023-01-11)\n\n## New features (Only available on CMake >= 3.19)\n\n- Add new `CRATE_TYPES` flag to `corrosion_import_crate()` to restrict which\n  crate types should be imported ([#269](https://github.com/corrosion-rs/corrosion/pull/269)).\n- Add `NO_LINKER_OVERRIDE` flag to let Rust choose the default linker for the target\n  instead of what Corrosion thinks is the appropriate linker driver ([#272](https://github.com/corrosion-rs/corrosion/pull/272)).\n\n## Fixes\n\n- Fix clean target when cross-compiling ([#291](https://github.com/corrosion-rs/corrosion/pull/291)).\n- Don't set the linker for Rust static libraries ([#275](https://github.com/corrosion-rs/corrosion/pull/275)).\n- Minor fixes in FindRust [#297](https://github.com/corrosion-rs/corrosion/pull/297): \n  - fix a logic error in the version detection\n  - fix a logic error in `QUIET` mode when rustup is not found.\n\n# 0.3.1 (2022-12-13)\n\n### Fixes\n\n- Fix a regression in detecting the MSVC abi ([#256])\n- Fix an issue on macOS 13 which affected rust crates compiling C++ code in build scripts ([#254]).\n- Fix corrosion not respecting `CMAKE_<XYZ>_OUTPUT_DIRECTORY` values ([#268]).\n- Don't override rusts linker choice for the msvc abi (previously this was only skipped for msvc generators) ([#271])\n\n[#254]: https://github.com/corrosion-rs/corrosion/pull/254\n[#256]: https://github.com/corrosion-rs/corrosion/pull/256\n[#268]: https://github.com/corrosion-rs/corrosion/pull/268\n[#271]: https://github.com/corrosion-rs/corrosion/pull/271\n\n# 0.3.0 (2022-10-31)\n\n## Breaking\n\n- The minimum supported rust version (MSRV) was increased to 1.46, due to a cargo issue that recently\n  surfaced on CI when using crates.io. On MacOS 12 and Windows-2022 at least Rust 1.54 is required.\n- MacOS 10 and 11 are no longer officially supported and untested in CI.\n- The minimum required CMake version is now 3.15.\n- Adding a `PRE_BUILD` custom command on a `cargo-build_<target_name>` CMake target will no \n  longer work as expected. To support executing user defined commands before cargo build is\n  invoked users should use the newly added targets `cargo-prebuild` (before all cargo build invocations)\n  or `cargo-prebuild_<target_name>` as a dependency target. \n  Example: `add_dependencies(cargo-prebuild code_generator_target)`\n\n### Breaking: Removed previously deprecated functionality\n- Removed `add_crate()` function. Use `corrosio_import_crate()` instead.\n- Removed `cargo_link_libraries()` function. Use `corrosion_link_libraries()` instead.\n- Removed experimental CMake option `CORROSION_EXPERIMENTAL_PARSER`.\n  The corresponding stable option is `CORROSION_NATIVE_TOOLING` albeit with inverted semantics.\n- Previously Corrosion would set the `HOST_CC` and `HOST_CXX` environment variables when invoking \n  cargo build, if the environment variables `CC` and `CXX` outside of CMake where set.\n  However this did not work as expected in all cases and sometimes the `HOST_CC` variable would be set\n  to a cross-compiler for unknown reasons. For this reason `HOST_CC` and `HOST_CXX` are not set by\n  corrosion anymore, but users can still set them manually if required via `corrosion_set_env_vars()`.\n- The `CARGO_RUST_FLAGS` family of cache variables were removed. Corrosion does not internally use them\n  anymore.\n\n## Potentially breaking\n\n- The working directory when invoking `cargo build` was changed to the directory of the Manifest\n  file. This now allows cargo to pick up `.cargo/config.toml` files located in the source tree.\n  ([205](https://github.com/corrosion-rs/corrosion/pull/205))\n- Corrosion internally invokes `cargo build`. When passing arguments to `cargo build`, Corrosion\n  now uses the CMake `VERBATIM` option. In rare cases this may require you to change how you quote\n  parameters passed to corrosion (e.g. via `corrosion_add_target_rustflags()`).\n  For example setting a `cfg` option previously required double escaping the rustflag like this\n  `\"--cfg=something=\\\\\\\"value\\\\\\\"\"`, but now it can be passed to corrosion without any escapes:\n  `--cfg=something=\"value\"`.\n- Corrosion now respects the CMake `OUTPUT_DIRECTORY` target properties. More details in the \"New features\" section.\n\n## New features\n\n- Support setting rustflags for only the main target and none of its dependencies ([215](https://github.com/corrosion-rs/corrosion/pull/215)).\n  A new function `corrosion_add_target_local_rustflags(target_name rustc_flag [more_flags ...])`\n  is added for this purpose.\n  This is useful in cases where you only need rustflags on the main-crate, but need to set different\n  flags for different targets. Without \"local\" Rustflags this would require rebuilds of the\n  dependencies when switching targets.\n- Support explicitly selecting a linker ([208](https://github.com/corrosion-rs/corrosion/pull/208)).\n  The linker can be selected via `corrosion_set_linker(target_name linker)`.\n  Please note that this only has an effect for targets, where the final linker invocation is done\n  by cargo, i.e. targets where foreign code is linked into rust code and not the other way around.\n- Corrosion now respects the CMake `OUTPUT_DIRECTORY` target properties and copies build artifacts to the expected\n  locations ([217](https://github.com/corrosion-rs/corrosion/pull/217)), if the properties are set.\n  This feature requires at least CMake 3.19 and is enabled by default if supported. Please note that the `OUTPUT_NAME`\n  target properties are currently not supported.\n  Specifically, the following target properties are now respected:\n  -   [ARCHIVE_OUTPUT_DIRECTORY](https://cmake.org/cmake/help/latest/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY.html)\n  -   [LIBRARY_OUTPUT_DIRECTORY](https://cmake.org/cmake/help/latest/prop_tgt/LIBRARY_OUTPUT_DIRECTORY.html)\n  -   [RUNTIME_OUTPUT_DIRECTORY](https://cmake.org/cmake/help/latest/prop_tgt/RUNTIME_OUTPUT_DIRECTORY.html)\n  -   [PDB_OUTPUT_DIRECTORY](https://cmake.org/cmake/help/latest/prop_tgt/PDB_OUTPUT_DIRECTORY.html)\n- Corrosion now supports packages with potentially multiple binaries (bins) and a library (lib) at the\n  same time. The only requirement is that the names of all `bin`s and `lib`s in the whole project must be unique.\n  Users can set the names in the `Cargo.toml` by adding `name = <unique_name>` in the `[[bin]]` and `[lib]` tables.\n- FindRust now has improved support for the `VERSION` option of `find_package` and will now attempt to find a matching\n  toolchain version. Previously it was only checked if the default toolchain matched to required version.\n- For rustup managed toolchains a CMake error is issued with a helpful message if the required target for\n  the selected toolchain is not installed.\n\n## Fixes\n\n- Fix a CMake developer Warning when a Multi-Config Generator and Rust executable targets\n  ([#213](https://github.com/corrosion-rs/corrosion/pull/213)).\n- FindRust now respects the `QUIET` option to `find_package()` in most cases.\n\n## Deprecation notice\n\n- Support for the MSVC Generators with CMake toolchains before 3.20 is deprecated and will be removed in the next\n  release (v0.4). All other Multi-config Generators already require CMake 3.20.\n\n## Internal Changes\n\n- The CMake Generator written in Rust and `CorrosionGenerator.cmake` which are responsible for parsing \n  `cargo metadata` output to create corresponding CMake targets for all Rust targets now share most code.\n  This greatly simplified the CMake generator written in Rust and makes it much easier maintaining and adding\n  new features regardless of how `cargo metadata` is parsed.\n\n# 0.2.2 (2022-09-01)\n\n## Fixes\n\n- Do not use C++17 in the tests (makes tests work with older C++ compilers) ([184](https://github.com/corrosion-rs/corrosion/pull/184))\n- Fix finding cargo on NixOS ([192](https://github.com/corrosion-rs/corrosion/pull/192))\n- Fix issue with Rustflags test when using a Build type other than Debug and Release ([203](https://github.com/corrosion-rs/corrosion/pull/203)).\n\n# 0.2.1 (2022-05-07)\n\n## Fixes\n\n- Fix missing variables provided by corrosion, when corrosion is used as a subdirectory ([181](https://github.com/corrosion-rs/corrosion/pull/181)):\n  Public [Variables](https://github.com/corrosion-rs/corrosion#information-provided-by-corrosion) set\n  by Corrosion were not visible when using Corrosion as a subdirectory, due to the wrong scope of\n  the variables. This was fixed by promoting the respective variables to Cache variables.\n\n# 0.2.0 (2022-05-05)\n\n## Breaking changes\n\n- Removed the integrator build script ([#156](https://github.com/corrosion-rs/corrosion/pull/156)).\n  The build script provided by corrosion (for rust code that links in foreign code) is no longer necessary,\n  so users can just remove the dependency.\n\n## Deprecations\n\n- Direct usage of the following target properties has been deprecated. The names of the custom properties are\n  no longer considered part of the public API and may change in the future. Instead, please use the functions\n  provided by corrosion. Internally different property names are used depending on the CMake version.\n  - `CORROSION_FEATURES`, `CORROSION_ALL_FEATURES`, `CORROSION_NO_DEFAULT_FEATURES`. Instead please use\n    `corrosion_set_features()`. See the updated Readme for details.\n  - `CORROSION_ENVIRONMENT_VARIABLES`. Please use `corrosion_set_env_vars()` instead.\n  - `CORROSION_USE_HOST_BUILD`. Please use `corrosion_set_hostbuild()` instead.\n- The Minimum CMake version will likely be increased for the next major release. At the very least we want to drop\n  support for CMake 3.12, but requiring CMake 3.16 or even 3.18 is also on the table. If you are using a CMake version\n  that would be no longer supported by corrosion, please comment on issue\n  [#168](https://github.com/corrosion-rs/corrosion/issues/168), so that we can gauge the number of affected users.\n\n## New features\n\n- Add `NO_STD` option to `corrosion_import_crate` ([#154](https://github.com/corrosion-rs/corrosion/pull/154)).\n- Remove the requirement of building the Rust based generator crate for CMake >= 3.19. This makes using corrosion as\n  a subdirectory as fast as the installed version (since everything is done in CMake).\n  ([#131](https://github.com/corrosion-rs/corrosion/pull/131), [#161](https://github.com/corrosion-rs/corrosion/pull/161))\n  If you do choose to install Corrosion, then by default the old Generator is still compiled and installed, so you can\n  fall back to using it in case you use multiple cmake versions on the same machine for different projects.\n\n## Fixes\n\n- Fix Corrosion on MacOS 11 and 12 ([#167](https://github.com/corrosion-rs/corrosion/pull/167) and\n  [#164](https://github.com/corrosion-rs/corrosion/pull/164)).\n- Improve robustness of parsing the LLVM version (exported in `Rust_LLVM_VERSION`). It now also works for\n  Rust versions, where the LLVM version is reported as `MAJOR.MINOR`. ([#148](https://github.com/corrosion-rs/corrosion/pull/148))\n- Fix a bug which occurred when Corrosion was added multiple times via `add_subdirectory()`\n  ([#143](https://github.com/corrosion-rs/corrosion/pull/143)).\n- Set `CC_<target_triple_undercore>` and `CXX_<target_triple_undercore>` environment variables for the invocation of\n  `cargo build` to the compilers selected by CMake  (if any)\n  ([#138](https://github.com/corrosion-rs/corrosion/pull/138) and [#161](https://github.com/corrosion-rs/corrosion/pull/161)).\n  This should ensure that C dependencies built in cargo buildscripts via [cc-rs](https://github.com/alexcrichton/cc-rs)\n  use the same compiler as CMake built dependencies. Users can override the compiler by specifying the higher\n  priority environment variable variants with dashes instead of underscores (See cc-rs documentation for details).\n- Fix Ninja-Multiconfig Generator support for CMake versions >= 3.20. Previous CMake versions are missing a feature,\n  which prevents us from supporting the Ninja-Multiconfig generator. ([#137](https://github.com/corrosion-rs/corrosion/pull/137))\n\n\n# 0.1.0 (2022-02-01)\n\nThis is the first release of corrosion after it was moved to the new corrosion-rs organization.\nSince there are no previous releases, this is not a complete changelog but only lists changes since\nSeptember 2021.\n\n## New features\n- [Add --profile support for rust >= 1.57](https://github.com/corrosion-rs/corrosion/pull/130):\n  Allows users to specify a custom cargo profile with\n  `corrosion_import_crate(... PROFILE <profilename>)`.\n- [Add support for specifying per-target Rustflags](https://github.com/corrosion-rs/corrosion/pull/127):\n  Rustflags can be added via `corrosion_add_target_rustflags(<target_name> [rustflags1...])`\n- [Add `Rust_IS_NIGHTLY` and `Rust_LLVM_VERSION` variables](https://github.com/corrosion-rs/corrosion/pull/123):\n  This may be useful if you want to conditionally enabled features when using a nightly toolchain\n  or a specific LLVM Version.\n- [Let `FindRust` fail gracefully if rustc is not found](https://github.com/corrosion-rs/corrosion/pull/111):\n  This allows using `FindRust` in a more general setting (without corrosion).\n- [Add support for cargo feature selection](https://github.com/corrosion-rs/corrosion/pull/108):\n  See the [README](https://github.com/corrosion-rs/corrosion#cargo-feature-selection) for details on\n  how to select features.\n\n\n## Fixes\n- [Fix the cargo-clean target](https://github.com/corrosion-rs/corrosion/pull/129)\n- [Fix #84: CorrosionConfig.cmake looks in wrong place for Corrosion::Generator when CMAKE_INSTALL_LIBEXEC is an absolute path](https://github.com/corrosion-rs/corrosion/pull/122/commits/6f29af3ac53917ca2e0638378371e715a18a532d)\n- [Fix #116: (Option CORROSION_INSTALL_EXECUTABLE not working)](https://github.com/corrosion-rs/corrosion/commit/97d44018fac1b1a2a7c095288c628f5bbd9b3184)\n- [Fix building on Windows with rust >= 1.57](https://github.com/corrosion-rs/corrosion/pull/120)\n\n## Known issues:\n- Corrosion is currently not working on macos-11 and newer. See issue [#104](https://github.com/corrosion-rs/corrosion/issues/104).\n  Contributions are welcome.\n"
  },
  {
    "path": "cmake/Corrosion.cmake",
    "content": "cmake_minimum_required(VERSION 3.22)\n\nlist(APPEND CMAKE_MESSAGE_CONTEXT \"Corrosion\")\n\nmessage(DEBUG \"Using Corrosion ${Corrosion_VERSION} with CMake ${CMAKE_VERSION} \"\n        \"and the `${CMAKE_GENERATOR}` Generator\"\n)\n\nget_cmake_property(COR_IS_MULTI_CONFIG GENERATOR_IS_MULTI_CONFIG)\nset(COR_IS_MULTI_CONFIG \"${COR_IS_MULTI_CONFIG}\" CACHE BOOL \"Do not change this\" FORCE)\nmark_as_advanced(FORCE COR_IS_MULTI_CONFIG)\n\n\nif(NOT COR_IS_MULTI_CONFIG AND DEFINED CMAKE_CONFIGURATION_TYPES)\n    message(WARNING \"The Generator is ${CMAKE_GENERATOR}, which is not a multi-config \"\n        \"Generator, but CMAKE_CONFIGURATION_TYPES is set. Please don't set \"\n        \"CMAKE_CONFIGURATION_TYPES unless you are using a multi-config Generator.\"\n    )\nendif()\n\noption(CORROSION_VERBOSE_OUTPUT \"Enables verbose output from Corrosion and Cargo\" OFF)\n\nif(DEFINED CORROSION_RESPECT_OUTPUT_DIRECTORY AND NOT CORROSION_RESPECT_OUTPUT_DIRECTORY)\n    message(WARNING \"The option CORROSION_RESPECT_OUTPUT_DIRECTORY was removed.\"\n    \" Corrosion now always attempts to respect the output directory.\")\nendif()\n\noption(\n    CORROSION_NO_WARN_PARSE_TARGET_TRIPLE_FAILED\n    \"Surpresses a warning if the parsing the target triple failed.\"\n    OFF\n)\n\nif(CMAKE_HOST_SYSTEM_NAME STREQUAL \"Darwin\" AND CMAKE_SYSTEM_NAME STREQUAL \"iOS\")\n    if(DEFINED CORROSION_HOST_TARGET_LINKER)\n        set(_corrosion_host_linker \"${CORROSION_HOST_TARGET_LINKER}\")\n        message(DEBUG \"Using user provided CORROSION_HOST_TARGET_LINKER: ${CORROSION_HOST_TARGET_LINKER}\")\n    else()\n        set(_corrosion_host_linker \"/usr/bin/cc\")\n    endif()\n    set(CORROSION_HOST_TARGET_LINKER \"${_corrosion_host_linker}\"\n        CACHE STRING\n        \"The linker-driver corrosion will use to compile host-targets. Currently only used when cross-compiling for iOS.\"\n        FORCE)\nendif()\n\nfind_package(Rust REQUIRED)\n\nif(CMAKE_GENERATOR MATCHES \"Visual Studio\"\n        AND (NOT CMAKE_VS_PLATFORM_NAME STREQUAL CMAKE_VS_PLATFORM_NAME_DEFAULT)\n        AND Rust_VERSION VERSION_LESS \"1.54\")\n    message(FATAL_ERROR \"Due to a cargo issue, cross-compiling with a Visual Studio generator and rust versions\"\n            \" before 1.54 is not supported. Rust build scripts would be linked with the cross-compiler linker, which\"\n            \" causes the build to fail. Please upgrade your Rust version to 1.54 or newer.\")\nendif()\n\n#    message(STATUS \"Using Corrosion as a subdirectory\")\n\nget_property(\n    RUSTC_EXECUTABLE\n    TARGET Rust::Rustc PROPERTY IMPORTED_LOCATION\n)\n\nget_property(\n    CARGO_EXECUTABLE\n    TARGET Rust::Cargo PROPERTY IMPORTED_LOCATION\n)\n\nif(Rust_TOOLCHAIN_IS_RUSTUP_MANAGED AND DEFINED Rust_RUSTUP_TOOLCHAINS)\n    set(corrosion_tools_rust_toolchain_docstring \"Rust toolchain to use for building helper tools such as cbindgen or cxx-bridge\")\n    if(DEFINED CORROSION_TOOLS_RUST_TOOLCHAIN)\n        set(cor_default_tools_toolchain \"${CORROSION_TOOLS_RUST_TOOLCHAIN}\")\n    else()\n        set(cor_default_tools_toolchain \"${Rust_TOOLCHAIN}\")\n    endif()\n    set(CORROSION_TOOLS_RUST_TOOLCHAIN \"${cor_default_tools_toolchain}\" CACHE STRING\n        \"${corrosion_tools_rust_toolchain_docstring}\" FORCE)\n    set_property(CACHE CORROSION_TOOLS_RUST_TOOLCHAIN PROPERTY STRINGS \"${Rust_RUSTUP_TOOLCHAINS}\")\n    if(NOT \"$CACHE{CORROSION_TOOLS_RUST_TOOLCHAIN}\" IN_LIST Rust_RUSTUP_TOOLCHAINS)\n        if(\"$CACHE{CORROSION_TOOLS_RUST_TOOLCHAIN}-${Rust_CARGO_HOST_TARGET}\" IN_LIST Rust_RUSTUP_TOOLCHAINS)\n            set(CORROSION_TOOLS_RUST_TOOLCHAIN \"$CACHE{CORROSION_TOOLS_RUST_TOOLCHAIN}-${Rust_CARGO_HOST_TARGET}\"\n                CACHE PATH \"${corrosion_tools_rust_toolchain_docstring}\" FORCE)\n        else()\n            message(FATAL_ERROR \"CORROSION_TOOLS_RUST_TOOLCHAIN must be set to a valid rustup managed toolchain path.\"\n                    \"Rust_RUSTUP_TOOLCHAINS contains a list of valid installed toolchains.\"\n            )\n        endif()\n    endif()\n    foreach(toolchain tc_rustc tc_cargo IN ZIP_LISTS Rust_RUSTUP_TOOLCHAINS Rust_RUSTUP_TOOLCHAINS_RUSTC_PATH Rust_RUSTUP_TOOLCHAINS_CARGO_PATH)\n        if(\"${toolchain}\" STREQUAL $CACHE{CORROSION_TOOLS_RUST_TOOLCHAIN})\n            # Minimum CMake version 3.29 for `IS_EXECUTABLE`.\n            if(NOT (tc_cargo AND tc_rustc ))\n                message(FATAL_ERROR \"Failed to find executable rustc or cargo for toolchain `$CACHE{CORROSION_TOOLS_RUST_TOOLCHAIN}`\")\n            endif()\n            set(CORROSION_TOOLS_RUSTC \"${tc_rustc}\" CACHE INTERNAL \"\" FORCE)\n            set(CORROSION_TOOLS_CARGO \"${tc_cargo}\" CACHE INTERNAL \"\" FORCE)\n            break()\n        endif()\n    endforeach()\n    if(NOT DEFINED CACHE{CORROSION_TOOLS_CARGO})\n        message(FATAL_ERROR \"Internal error: Failed to find toolchain $CACHE{CORROSION_TOOLS_RUST_TOOLCHAIN} in \"\n                \"list of rustup managed toolchains: ${Rust_RUSTUP_TOOLCHAINS}\"\n        )\n    endif()\nelse()\n    # Fallback to the default project toolchain if rust is not rustup managed.\n    if(DEFINED CORROSION_TOOLS_RUST_TOOLCHAIN)\n        message(DEBUG \"Ignoring `CORROSION_TOOLS_RUST_TOOLCHAIN=${CORROSION_TOOLS_RUST_TOOLCHAIN}` \"\n            \"since the toolchains are not rustup managed. Falling back to the default rust toolchain\"\n            \" for this project.\"\n        )\n    endif()\n    set(CORROSION_TOOLS_RUSTC \"${RUSTC_EXECUTABLE}\" CACHE INTERNAL \"\" FORCE)\n    set(CORROSION_TOOLS_CARGO \"${CARGO_EXECUTABLE}\" CACHE INTERNAL \"\" FORCE)\nendif()\n\nfunction(_corrosion_bin_target_suffix target_name out_var_suffix)\n    get_target_property(hostbuild \"${target_name}\" ${_CORR_PROP_HOST_BUILD})\n    if((hostbuild AND CMAKE_HOST_WIN32)\n       OR ((NOT hostbuild) AND (Rust_CARGO_TARGET_OS STREQUAL \"windows\")))\n        set(_suffix \".exe\")\n    elseif(Rust_CARGO_TARGET_OS STREQUAL \"vxworks\")\n        set(_suffix \".vxe\")\n    else()\n        set(_suffix \"\")\n    endif()\n    set(${out_var_suffix} \"${_suffix}\" PARENT_SCOPE)\nendfunction()\n\nfunction(_handle_output_directory_genex input_path config_type output_path)\n    if(\"${config_type}\" STREQUAL \"\")\n        # Prevent new path from being `dir//file`, since that causes issues with the\n        # file dependency.\n        string(REPLACE \"/\\$<CONFIG>\" \"${config_type}\" curr_out_dir \"${input_path}\")\n        string(REPLACE \"\\$<CONFIG>\" \"${config_type}\" curr_out_dir \"${curr_out_dir}\")\n    else()\n        string(REPLACE \"\\$<CONFIG>\" \"${config_type}\" curr_out_dir \"${input_path}\")\n    endif()\n    string(GENEX_STRIP \"${curr_out_dir}\" stripped_out_dir)\n    if(\"${stripped_out_dir}\" STREQUAL \"${curr_out_dir}\")\n        set(\"${output_path}\" \"${curr_out_dir}\" PARENT_SCOPE)\n    else()\n        unset(\"${output_path}\" PARENT_SCOPE)\n        message(WARNING \"Encountered output directory path with unsupported genex. \"\n                \"Output dir: `${curr_out_dir}`\"\n                \"Note: Corrosion only supports the `\\$<CONFIG>` generator expression for output directories.\")\n    endif()\nendfunction()\n\n# Do not call this function directly!\n#\n# This function should be called deferred to evaluate target properties late in the configure stage.\n# IMPORTED_LOCATION does not support Generator expressions, so we must evaluate the output\n# directory target property value at configure time. This function must be deferred to the end of\n# the configure stage, so we can be sure that the output directory is not modified afterwards.\nfunction(_corrosion_set_imported_location_deferred target_name base_property output_directory_property filename)\n    # The output directory property is expected to be set on the exposed target (without postfix),\n    # but we need to set the imported location on the actual library target with postfix.\n    if(\"${target_name}\" MATCHES \"^(.+)-(static|shared)$\")\n        set(output_dir_prop_target_name \"${CMAKE_MATCH_1}\")\n    else()\n        set(output_dir_prop_target_name \"${target_name}\")\n    endif()\n\n    # Append .exe suffix for executable by-products if the target is windows or if it's a host\n    # build and the host is Windows.\n    get_target_property(target_type ${target_name} TYPE)\n    if(${target_type} STREQUAL \"EXECUTABLE\" AND (NOT \"${filename}\" MATCHES \"\\.pdb$\"))\n        _corrosion_bin_target_suffix(${target_name} \"suffix\")\n        string(APPEND filename \"${suffix}\")\n    endif()\n\n    get_target_property(output_directory \"${output_dir_prop_target_name}\" \"${output_directory_property}\")\n    message(DEBUG \"Output directory property (target ${output_dir_prop_target_name}): ${output_directory_property} dir: ${output_directory}\")\n\n    foreach(config_type ${CMAKE_CONFIGURATION_TYPES})\n        string(TOUPPER \"${config_type}\" config_type_upper)\n        get_target_property(output_dir_curr_config ${output_dir_prop_target_name}\n            \"${output_directory_property}_${config_type_upper}\"\n        )\n        if(output_dir_curr_config)\n            set(curr_out_dir \"${output_dir_curr_config}\")\n        elseif(output_directory)\n            string(GENEX_STRIP \"${output_directory}\" output_dir_no_genex)\n            # Only add config dir if there is no genex in here. See\n            # https://cmake.org/cmake/help/latest/prop_tgt/RUNTIME_OUTPUT_DIRECTORY.html\n            if(output_directory STREQUAL output_dir_no_genex)\n                set(curr_out_dir \"${output_directory}/${config_type}\")\n            else()\n                set(curr_out_dir \"${output_directory}\")\n            endif()\n        else()\n            set(curr_out_dir \"${CMAKE_CURRENT_BINARY_DIR}\")\n        endif()\n        _handle_output_directory_genex(\"${curr_out_dir}\" \"${config_type}\" sanitized_out_dir)\n        if(NOT DEFINED sanitized_out_dir)\n            message(FATAL_ERROR \"${output_directory_property} for target ${output_dir_prop_target_name} \"\n                    \"contained an unexpected Generator expression. Output dir: `${curr_out_dir}`\"\n                \"Note: Corrosion only supports the `\\$<CONFIG>` generator expression for output directories.\")\n        endif()\n\n        # For Multiconfig we want to specify the correct location for each configuration\n        set_property(\n            TARGET ${target_name}\n            PROPERTY \"${base_property}_${config_type_upper}\"\n                \"${sanitized_out_dir}/${filename}\"\n        )\n        set(base_output_directory \"${sanitized_out_dir}\")\n    endforeach()\n\n    if(NOT COR_IS_MULTI_CONFIG)\n        if(output_directory)\n            set(base_output_directory \"${output_directory}\")\n        else()\n            set(base_output_directory \"${CMAKE_CURRENT_BINARY_DIR}\")\n        endif()\n        _handle_output_directory_genex(\"${base_output_directory}\" \"${CMAKE_BUILD_TYPE}\" sanitized_output_directory)\n        if(NOT DEFINED sanitized_output_directory)\n            message(FATAL_ERROR \"${output_dir_prop_target_name} for target ${output_dir_prop_target_name} \"\n                    \"contained an unexpected Generator expression. Output dir: `${base_output_directory}`.\"\n                    \"Note: Corrosion only supports the `\\$<CONFIG>` generator expression for output directories.\")\n        endif()\n        set(base_output_directory \"${sanitized_output_directory}\")\n    endif()\n\n    message(DEBUG \"Setting ${base_property} for target ${target_name}\"\n                \" to `${base_output_directory}/${filename}`.\")\n\n    # IMPORTED_LOCATION must be set regardless of possible overrides. In the multiconfig case,\n    # the last configuration \"wins\" (IMPORTED_LOCATION is not documented to have Genex support).\n    set_property(\n            TARGET ${target_name}\n            PROPERTY \"${base_property}\" \"${base_output_directory}/${filename}\"\n        )\nendfunction()\n\n# Set the imported location of a Rust target.\n#\n# Rust targets are built via custom targets / custom commands. The actual artifacts are exposed\n# to CMake as imported libraries / executables that depend on the cargo_build command. For CMake\n# to find the built artifact we need to set the IMPORTED location to the actual location on disk.\n# Corrosion tries to copy the artifacts built by cargo to standard locations. The IMPORTED_LOCATION\n# is set to point to the copy, and not the original from the cargo build directory.\n#\n# Parameters:\n# - target_name: Name of the Rust target\n# - base_property: Name of the base property - i.e. `IMPORTED_LOCATION` or `IMPORTED_IMPLIB`.\n# - output_directory_property: Target property name that determines the standard location for the\n#    artifact.\n# - filename of the artifact.\nfunction(_corrosion_set_imported_location target_name base_property output_directory_property filename)\n        cmake_language(EVAL CODE \"\n            cmake_language(DEFER\n                CALL\n                _corrosion_set_imported_location_deferred\n                [[${target_name}]]\n                [[${base_property}]]\n                [[${output_directory_property}]]\n                [[${filename}]]\n            )\n        \")\nendfunction()\n\nfunction(_corrosion_copy_byproduct_deferred target_name output_dir_prop_names cargo_build_dir file_names)\n    if(ARGN)\n        message(FATAL_ERROR \"Unexpected additional arguments\")\n    endif()\n\n    foreach(output_dir_prop_name ${output_dir_prop_names})\n        get_target_property(output_dir ${target_name} \"${output_dir_prop_name}\")\n        if(output_dir)\n            break()\n        endif()\n    endforeach()\n\n    # A Genex expanding to the output directory depending on the configuration.\n    set(multiconfig_out_dir_genex \"\")\n\n    foreach(config_type ${CMAKE_CONFIGURATION_TYPES})\n        string(TOUPPER \"${config_type}\" config_type_upper)\n        foreach(output_dir_prop_name ${output_dir_prop_names})\n            get_target_property(output_dir_curr_config ${target_name} \"${output_dir_prop_name}_${config_type_upper}\")\n            if(output_dir_curr_config)\n                break()\n            endif()\n        endforeach()\n\n        if(output_dir_curr_config)\n            set(curr_out_dir \"${output_dir_curr_config}\")\n        elseif(output_dir)\n            string(GENEX_STRIP \"${output_dir}\" output_dir_no_genex)\n            # Only add config dir if there is no genex in here. See\n            # https://cmake.org/cmake/help/latest/prop_tgt/RUNTIME_OUTPUT_DIRECTORY.html\n            # Logic duplicated from _corrosion_set_imported_location_deferred\n            if(output_dir STREQUAL output_dir_no_genex)\n                set(curr_out_dir \"${output_dir}/${config_type}\")\n            else()\n                set(curr_out_dir \"${output_dir}\")\n            endif()\n        else()\n            # Fallback to the default directory. We do not append the configuration directory here\n            # and instead let CMake do this, since otherwise the resolving of dynamic library\n            # imported paths may fail.\n            set(curr_out_dir \"${CMAKE_CURRENT_BINARY_DIR}\")\n        endif()\n        set(multiconfig_out_dir_genex \"${multiconfig_out_dir_genex}$<$<CONFIG:${config_type}>:${curr_out_dir}>\")\n    endforeach()\n\n    if(COR_IS_MULTI_CONFIG)\n        set(output_dir \"${multiconfig_out_dir_genex}\")\n    else()\n        if(NOT output_dir)\n            # Fallback to default directory.\n            set(output_dir \"${CMAKE_CURRENT_BINARY_DIR}\")\n        endif()\n    endif()\n\n    # Append .exe suffix for executable by-products if the target is windows or if it's a host\n    # build and the host is Windows.\n    get_target_property(target_type \"${target_name}\" TYPE)\n    if (target_type STREQUAL \"EXECUTABLE\")\n        list(LENGTH file_names list_len)\n        if(NOT list_len EQUAL \"1\")\n            message(FATAL_ERROR\n                    \"Internal error: Exactly one filename should be passed for executable types.\")\n        endif()\n        _corrosion_bin_target_suffix(${target_name} \"suffix\")\n        if(suffix AND (NOT \"${file_names}\" MATCHES \"\\.pdb$\"))\n            # For executable targets we know / checked that only one file will be passed.\n            string(APPEND file_names \"${suffix}\")\n        endif()\n    endif()\n    set(src_file_names \"${file_names}\")\n    if(Rust_CARGO_TARGET_ENV STREQUAL \"gnullvm\")\n        # Workaround for cargo not exposing implibs yet.\n        list(TRANSFORM src_file_names PREPEND \"deps/\" REGEX \"\\.dll\\.a$\")\n    endif()\n    list(TRANSFORM src_file_names PREPEND \"${cargo_build_dir}/\")\n    list(TRANSFORM file_names PREPEND \"${output_dir}/\" OUTPUT_VARIABLE dst_file_names)\n    message(DEBUG \"Adding command to copy byproducts `${file_names}` to ${dst_file_names}\")\n    add_custom_command(TARGET _cargo-build_${target_name}\n                        POST_BUILD\n                        # output_dir may contain a Generator expression.\n                        COMMAND  ${CMAKE_COMMAND} -E make_directory \"${output_dir}\"\n                        COMMAND\n                        ${CMAKE_COMMAND} -E copy_if_different\n                            # tested to work with both multiple files and paths with spaces\n                            ${src_file_names}\n                            \"${output_dir}\"\n                        BYPRODUCTS ${dst_file_names}\n                        COMMENT \"Copying byproducts `${file_names}` to ${output_dir}\"\n                        VERBATIM\n                        COMMAND_EXPAND_LISTS\n    )\nendfunction()\n\n# Copy the artifacts generated by cargo to the appropriate destination.\n#\n# Parameters:\n# - target_name: The name of the Rust target\n# - output_dir_prop_names: The property name(s) controlling the destination (e.g.\n#   `LIBRARY_OUTPUT_DIRECTORY` or `PDB_OUTPUT_DIRECTORY;RUNTIME_OUTPUT_DIRECTORY`)\n# - cargo_build_dir: the directory cargo build places it's output artifacts in.\n# - filenames: the file names of any output artifacts as a list.\nfunction(_corrosion_copy_byproducts target_name output_dir_prop_names cargo_build_dir file_names)\n        cmake_language(EVAL CODE \"\n            cmake_language(DEFER\n                CALL\n                _corrosion_copy_byproduct_deferred\n                [[${target_name}]]\n                [[${output_dir_prop_names}]]\n                [[${cargo_build_dir}]]\n                [[${file_names}]]\n            )\n        \")\nendfunction()\n\n\n# Add targets for the static and/or shared libraries of the rust target.\n# The generated byproduct names are returned via the `OUT_<type>_BYPRODUCTS` arguments.\nfunction(_corrosion_add_library_target)\n    set(OPTIONS \"\")\n    set(ONE_VALUE_KEYWORDS\n        WORKSPACE_MANIFEST_PATH\n        TARGET_NAME\n        OUT_ARCHIVE_OUTPUT_BYPRODUCTS\n        OUT_SHARED_LIB_BYPRODUCTS\n        OUT_PDB_BYPRODUCT\n    )\n    set(MULTI_VALUE_KEYWORDS LIB_KINDS)\n    cmake_parse_arguments(PARSE_ARGV 0 CALT \"${OPTIONS}\" \"${ONE_VALUE_KEYWORDS}\" \"${MULTI_VALUE_KEYWORDS}\")\n\n    if(DEFINED CALT_UNPARSED_ARGUMENTS)\n        message(FATAL_ERROR \"Internal error - unexpected arguments: ${CALT_UNPARSED_ARGUMENTS}\")\n    elseif(DEFINED CALT_KEYWORDS_MISSING_VALUES)\n        message(FATAL_ERROR \"Internal error - the following keywords had no associated value(s):\"\n            \"${CALT_KEYWORDS_MISSING_VALUES}\")\n    endif()\n    list(TRANSFORM ONE_VALUE_KEYWORDS PREPEND CALT_ OUTPUT_VARIABLE required_arguments)\n    foreach(required_argument ${required_arguments} )\n        if(NOT DEFINED \"${required_argument}\")\n            message(FATAL_ERROR \"Internal error: Missing required argument ${required_argument}.\"\n                \"Complete argument list: ${ARGN}\"\n            )\n        endif()\n    endforeach()\n    if(\"staticlib\" IN_LIST CALT_LIB_KINDS)\n        set(has_staticlib TRUE)\n    endif()\n    if(\"cdylib\" IN_LIST CALT_LIB_KINDS)\n        set(has_cdylib TRUE)\n    endif()\n\n    if(NOT (has_staticlib OR has_cdylib))\n        message(FATAL_ERROR \"Unknown library type(s): ${CALT_LIB_KINDS}\")\n    endif()\n    set(workspace_manifest_path \"${CALT_WORKSPACE_MANIFEST_PATH}\")\n    set(target_name \"${CALT_TARGET_NAME}\")\n\n    set(is_windows \"\")\n    set(is_windows_gnu \"\")\n    set(is_windows_msvc \"\")\n    set(is_macos \"\")\n    set(is_ios \"\")\n    if(Rust_CARGO_TARGET_OS STREQUAL \"windows\")\n        set(is_windows TRUE)\n        if(Rust_CARGO_TARGET_ENV STREQUAL \"msvc\")\n            set(is_windows_msvc TRUE)\n        elseif(Rust_CARGO_TARGET_ENV STREQUAL \"gnu\" OR Rust_CARGO_TARGET_ENV STREQUAL \"gnullvm\")\n            set(is_windows_gnu TRUE)\n        endif()\n    elseif(Rust_CARGO_TARGET_OS STREQUAL \"darwin\")\n        set(is_macos TRUE)\n    elseif(Rust_CARGO_TARGET_OS STREQUAL \"ios\")\n        set(is_ios true)\n    endif()\n\n    # target file names\n    string(REPLACE \"-\" \"_\" lib_name \"${target_name}\")\n\n    if(is_windows_msvc)\n        set(static_lib_name \"${lib_name}.lib\")\n    else()\n        set(static_lib_name \"lib${lib_name}.a\")\n    endif()\n\n    if(is_windows)\n        set(dynamic_lib_name \"${lib_name}.dll\")\n    elseif(is_macos OR is_ios)\n        set(dynamic_lib_name \"lib${lib_name}.dylib\")\n    else()\n        set(dynamic_lib_name \"lib${lib_name}.so\")\n    endif()\n\n    if(is_windows_msvc)\n        set(implib_name \"${lib_name}.dll.lib\")\n    elseif(is_windows_gnu)\n        set(implib_name \"lib${lib_name}.dll.a\")\n    elseif(is_windows)\n        message(FATAL_ERROR \"Unknown windows environment - Can't determine implib name\")\n    endif()\n\n\n    set(pdb_name \"${lib_name}.pdb\")\n\n    set(archive_output_byproducts \"\")\n    if(has_staticlib)\n        list(APPEND archive_output_byproducts ${static_lib_name})\n    endif()\n\n    if(has_cdylib)\n        set(\"${CALT_OUT_SHARED_LIB_BYPRODUCTS}\" \"${dynamic_lib_name}\" PARENT_SCOPE)\n        if(is_windows)\n            list(APPEND archive_output_byproducts ${implib_name})\n        endif()\n        if(is_windows_msvc)\n            set(\"${CALT_OUT_PDB_BYPRODUCT}\" \"${pdb_name}\" PARENT_SCOPE)\n        endif()\n    endif()\n    set(\"${CALT_OUT_ARCHIVE_OUTPUT_BYPRODUCTS}\" \"${archive_output_byproducts}\" PARENT_SCOPE)\n\n    if(has_staticlib)\n        add_library(${target_name}-static STATIC IMPORTED GLOBAL)\n        add_dependencies(${target_name}-static cargo-build_${target_name})\n        set_target_properties(${target_name}-static PROPERTIES COR_FILE_NAME ${static_lib_name})\n\n        _corrosion_set_imported_location(\"${target_name}-static\" \"IMPORTED_LOCATION\"\n                \"ARCHIVE_OUTPUT_DIRECTORY\"\n                \"${static_lib_name}\")\n\n        # Todo: NO_STD target property?\n        if(NOT COR_NO_STD)\n            set_property(\n                    TARGET ${target_name}-static\n                    PROPERTY INTERFACE_LINK_LIBRARIES ${Rust_CARGO_TARGET_LINK_NATIVE_LIBS}\n            )\n            set_property(\n                    TARGET ${target_name}-static\n                    PROPERTY INTERFACE_LINK_OPTIONS ${Rust_CARGO_TARGET_LINK_OPTIONS}\n            )\n            if(is_macos)\n                set_property(TARGET ${target_name}-static\n                        PROPERTY INTERFACE_LINK_DIRECTORIES \"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib\"\n                        )\n            endif()\n        endif()\n    endif()\n\n    if(has_cdylib)\n        add_library(${target_name}-shared SHARED IMPORTED GLOBAL)\n        add_dependencies(${target_name}-shared cargo-build_${target_name})\n        set_target_properties(${target_name}-shared PROPERTIES COR_FILE_NAME ${dynamic_lib_name})\n\n        # Todo: (Not new issue): What about IMPORTED_SONAME and IMPORTED_NO_SYSTEM?\n        _corrosion_set_imported_location(\"${target_name}-shared\" \"IMPORTED_LOCATION\"\n                \"LIBRARY_OUTPUT_DIRECTORY\"\n                \"${dynamic_lib_name}\"\n        )\n        # In the future we would probably prefer to let Rust set the soname for packages >= 1.0.\n        # This is tracked in issue #333.\n        set_target_properties(${target_name}-shared PROPERTIES IMPORTED_NO_SONAME TRUE)\n\n        if(is_windows)\n            _corrosion_set_imported_location(\"${target_name}-shared\" \"IMPORTED_IMPLIB\"\n                    \"ARCHIVE_OUTPUT_DIRECTORY\"\n                    \"${implib_name}\"\n            )\n            set_target_properties(${target_name}-shared PROPERTIES COR_IMPLIB_FILE_NAME ${implib_name})\n        endif()\n\n        if(is_macos)\n            set_property(TARGET ${target_name}-shared\n                    PROPERTY INTERFACE_LINK_DIRECTORIES \"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib\"\n                    )\n        endif()\n    endif()\n\n    if(has_cdylib AND has_staticlib)\n        if(BUILD_SHARED_LIBS)\n            target_link_libraries(${target_name} INTERFACE ${target_name}-shared)\n        else()\n            target_link_libraries(${target_name} INTERFACE ${target_name}-static)\n        endif()\n    elseif(has_cdylib)\n        target_link_libraries(${target_name} INTERFACE ${target_name}-shared)\n    else()\n        target_link_libraries(${target_name} INTERFACE ${target_name}-static)\n    endif()\nendfunction()\n\nfunction(_corrosion_add_bin_target workspace_manifest_path bin_name out_bin_byproduct out_pdb_byproduct)\n    if(NOT bin_name)\n        message(FATAL_ERROR \"No bin_name in _corrosion_add_bin_target for target ${target_name}\")\n    endif()\n\n    string(REPLACE \"-\" \"_\" bin_name_underscore \"${bin_name}\")\n\n    set(pdb_name \"${bin_name_underscore}.pdb\")\n\n    if(Rust_CARGO_TARGET_ENV STREQUAL \"msvc\")\n        set(${out_pdb_byproduct} \"${pdb_name}\" PARENT_SCOPE)\n    endif()\n\n    # Potential .exe suffix will be added later, also depending on possible hostbuild\n    # target property\n    set(bin_filename \"${bin_name}\")\n    set(${out_bin_byproduct} \"${bin_filename}\" PARENT_SCOPE)\n    add_dependencies(${bin_name} cargo-build_${bin_name})\n\n    if(Rust_CARGO_TARGET_OS STREQUAL \"darwin\")\n        set_property(TARGET ${bin_name}\n                PROPERTY INTERFACE_LINK_DIRECTORIES \"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib\"\n                )\n    endif()\n\n    _corrosion_set_imported_location(\"${bin_name}\" \"IMPORTED_LOCATION\"\n                        \"RUNTIME_OUTPUT_DIRECTORY\"\n                        \"${bin_filename}\"\n    )\n\nendfunction()\n\n\ninclude(CorrosionGenerator)\n\n# Note: `cmake_language(GET_MESSAGE_LOG_LEVEL <output_variable>)` requires CMake 3.25,\n# so we offer our own option to control verbosity of downstream commands (e.g. cargo build)\nif (CORROSION_VERBOSE_OUTPUT)\n    set(_CORROSION_VERBOSE_OUTPUT_FLAG --verbose CACHE INTERNAL \"\")\nelse()\n    # We want to silence some less important commands by default.\n    set(_CORROSION_QUIET_OUTPUT_FLAG --quiet CACHE INTERNAL \"\")\nendif()\n\nset(_CORROSION_CARGO_VERSION ${Rust_CARGO_VERSION} CACHE INTERNAL \"cargo version used by corrosion\")\nset(_CORROSION_RUST_CARGO_TARGET ${Rust_CARGO_TARGET} CACHE INTERNAL \"target triple used by corrosion\")\nset(_CORROSION_RUST_CARGO_HOST_TARGET ${Rust_CARGO_HOST_TARGET} CACHE INTERNAL \"host triple used by corrosion\")\nset(_CORROSION_RUSTC \"${RUSTC_EXECUTABLE}\" CACHE INTERNAL  \"Path to rustc used by corrosion\")\nset(_CORROSION_CARGO \"${CARGO_EXECUTABLE}\" CACHE INTERNAL \"Path to cargo used by corrosion\")\n\nstring(REPLACE \"-\" \"_\" _CORROSION_RUST_CARGO_TARGET_UNDERSCORE \"${Rust_CARGO_TARGET}\")\nset(_CORROSION_RUST_CARGO_TARGET_UNDERSCORE \"${_CORROSION_RUST_CARGO_TARGET_UNDERSCORE}\" CACHE INTERNAL \"lowercase target triple with underscores\")\nstring(TOUPPER \"${_CORROSION_RUST_CARGO_TARGET_UNDERSCORE}\" _CORROSION_TARGET_TRIPLE_UPPER)\nset(_CORROSION_RUST_CARGO_TARGET_UPPER\n        \"${_CORROSION_TARGET_TRIPLE_UPPER}\"\n        CACHE INTERNAL\n        \"target triple in uppercase with underscore\"\n)\n\n# We previously specified some Custom properties as part of our public API, however the chosen names prevented us from\n# supporting CMake versions before 3.19. In order to both support older CMake versions and not break existing code\n# immediately, we are using a different property name depending on the CMake version. However users avoid using\n# any of the properties directly, as they are no longer part of the public API and are to be considered deprecated.\n# Instead use the corrosion_set_... functions as documented in the Readme.\nset(_CORR_PROP_FEATURES CORROSION_FEATURES CACHE INTERNAL \"\")\nset(_CORR_PROP_ALL_FEATURES CORROSION_ALL_FEATURES CACHE INTERNAL \"\")\nset(_CORR_PROP_NO_DEFAULT_FEATURES CORROSION_NO_DEFAULT_FEATURES CACHE INTERNAL \"\")\nset(_CORR_PROP_ENV_VARS CORROSION_ENVIRONMENT_VARIABLES CACHE INTERNAL \"\")\nset(_CORR_PROP_HOST_BUILD CORROSION_USE_HOST_BUILD CACHE INTERNAL \"\")\n\n# Add custom command to build one target in a package (crate)\n#\n# A target may be either a specific bin\nfunction(_add_cargo_build out_cargo_build_out_dir)\n    set(options NO_LINKER_OVERRIDE)\n    set(one_value_args PACKAGE TARGET MANIFEST_PATH WORKSPACE_MANIFEST_PATH)\n    set(multi_value_args BYPRODUCTS TARGET_KINDS)\n    cmake_parse_arguments(\n        ACB\n        \"${options}\"\n        \"${one_value_args}\"\n        \"${multi_value_args}\"\n        ${ARGN}\n    )\n\n    if(DEFINED ACB_UNPARSED_ARGUMENTS)\n        message(FATAL_ERROR \"Internal error - unexpected arguments: \"\n            ${ACB_UNPARSED_ARGUMENTS})\n    elseif(DEFINED ACB_KEYWORDS_MISSING_VALUES)\n        message(FATAL_ERROR \"Internal error - missing values for the following arguments: \"\n                ${ACB_KEYWORDS_MISSING_VALUES})\n    endif()\n\n    set(package_name \"${ACB_PACKAGE}\")\n    set(target_name \"${ACB_TARGET}\")\n    set(path_to_toml \"${ACB_MANIFEST_PATH}\")\n    set(target_kinds \"${ACB_TARGET_KINDS}\")\n    set(workspace_manifest_path \"${ACB_WORKSPACE_MANIFEST_PATH}\")\n    set(build_byproducts \"${ACB_BYPRODUCTS}\")\n\n    unset(cargo_rustc_crate_types)\n    if(NOT target_kinds)\n        message(FATAL_ERROR \"TARGET_KINDS not specified\")\n    elseif(\"staticlib\" IN_LIST target_kinds OR \"cdylib\" IN_LIST target_kinds)\n        set(cargo_rustc_filter \"--lib\")\n        if(\"${Rust_VERSION}\" VERSION_GREATER_EQUAL \"1.64\")\n            # https://doc.rust-lang.org/1.64.0/cargo/commands/cargo-rustc.html\n            # `--crate-type` is documented since Rust 1.64 for `cargo rustc`.\n            # We just unconditionally set it when available, to support overriding the crate type.\n            # Due to https://github.com/rust-lang/cargo/issues/14498 we can't use one argument and pass a\n            # comma seperated list. Instead we use multiple arguments.\n            set(cargo_rustc_crate_types \"${target_kinds}\")\n            list(TRANSFORM cargo_rustc_crate_types PREPEND \"--crate-type=\")\n        endif()\n    elseif(\"bin\" IN_LIST target_kinds)\n        set(cargo_rustc_filter \"--bin=${target_name}\")\n    else()\n        message(FATAL_ERROR \"TARGET_KINDS contained unknown kind `${target_kind}`\")\n    endif()\n\n    if (NOT IS_ABSOLUTE \"${path_to_toml}\")\n        set(path_to_toml \"${CMAKE_SOURCE_DIR}/${path_to_toml}\")\n    endif()\n    get_filename_component(workspace_toml_dir ${path_to_toml} DIRECTORY )\n\n    if (CMAKE_VS_PLATFORM_NAME)\n        set(build_dir \"${CMAKE_VS_PLATFORM_NAME}/$<CONFIG>\")\n    elseif(COR_IS_MULTI_CONFIG)\n        set(build_dir \"$<CONFIG>\")\n    else()\n        unset(build_dir)\n    endif()\n\n    # If a CMake sysroot is specified, forward it to the linker rustc invokes, too. CMAKE_SYSROOT is documented\n    # to be passed via --sysroot, so we assume that when it's set, the linker supports this option in that style.\n    if(CMAKE_CROSSCOMPILING AND CMAKE_SYSROOT)\n        set(corrosion_link_args \"--sysroot=${CMAKE_SYSROOT}\")\n    endif()\n\n    if(COR_ALL_FEATURES)\n        set(all_features_arg --all-features)\n    endif()\n    if(COR_NO_DEFAULT_FEATURES)\n        set(no_default_features_arg --no-default-features)\n    endif()\n    if(COR_NO_USES_TERMINAL)\n        unset(cor_uses_terminal)\n    else()\n        set(cor_uses_terminal USES_TERMINAL)\n    endif()\n\n    set(global_rustflags_target_property \"$<TARGET_GENEX_EVAL:${target_name},$<TARGET_PROPERTY:${target_name},INTERFACE_CORROSION_RUSTFLAGS>>\")\n    set(local_rustflags_target_property  \"$<TARGET_GENEX_EVAL:${target_name},$<TARGET_PROPERTY:${target_name},INTERFACE_CORROSION_LOCAL_RUSTFLAGS>>\")\n\n    # todo: this probably should be TARGET_GENEX_EVAL\n    set(features_target_property \"$<GENEX_EVAL:$<TARGET_PROPERTY:${target_name},${_CORR_PROP_FEATURES}>>\")\n    set(features_genex \"$<$<BOOL:${features_target_property}>:--features=$<JOIN:${features_target_property},$<COMMA>>>\")\n\n    # target property overrides corrosion_import_crate argument\n    set(all_features_target_property \"$<GENEX_EVAL:$<TARGET_PROPERTY:${target_name},${_CORR_PROP_ALL_FEATURES}>>\")\n    set(all_features_arg \"$<$<BOOL:${all_features_target_property}>:--all-features>\")\n\n    set(no_default_features_target_property \"$<GENEX_EVAL:$<TARGET_PROPERTY:${target_name},${_CORR_PROP_NO_DEFAULT_FEATURES}>>\")\n    set(no_default_features_arg \"$<$<BOOL:${no_default_features_target_property}>:--no-default-features>\")\n\n    set(build_env_variable_genex \"$<GENEX_EVAL:$<TARGET_PROPERTY:${target_name},${_CORR_PROP_ENV_VARS}>>\")\n    set(hostbuild_override \"$<BOOL:$<TARGET_PROPERTY:${target_name},${_CORR_PROP_HOST_BUILD}>>\")\n    set(if_not_host_build_condition \"$<NOT:${hostbuild_override}>\")\n\n    set(corrosion_link_args \"$<${if_not_host_build_condition}:${corrosion_link_args}>\")\n    # We always set `--target`, so that cargo always places artifacts into a directory with the\n    # target triple.\n    set(cargo_target_option \"--target=$<IF:${hostbuild_override},${_CORROSION_RUST_CARGO_HOST_TARGET},${_CORROSION_RUST_CARGO_TARGET}>\")\n\n    # The target may be a filepath to custom target json file. For host targets we assume that they are built-in targets.\n    _corrosion_strip_target_triple(\"${_CORROSION_RUST_CARGO_TARGET}\" stripped_target_triple)\n    _corrosion_strip_target_triple(\"${_CORROSION_RUST_CARGO_TARGET_UPPER}\" stripped_target_triple_upper)\n    set(target_artifact_dir \"$<IF:${hostbuild_override},${_CORROSION_RUST_CARGO_HOST_TARGET},${stripped_target_triple}>\")\n\n    set(flags_genex \"$<GENEX_EVAL:$<TARGET_PROPERTY:${target_name},INTERFACE_CORROSION_CARGO_FLAGS>>\")\n\n    set(explicit_linker_property \"$<TARGET_PROPERTY:${target_name},INTERFACE_CORROSION_LINKER>\")\n    set(explicit_linker_defined \"$<BOOL:${explicit_linker_property}>\")\n\n    set(cargo_profile_target_property \"$<TARGET_GENEX_EVAL:${target_name},$<TARGET_PROPERTY:${target_name},INTERFACE_CORROSION_CARGO_PROFILE>>\")\n\n    # Option to override the rustc/cargo binary to something other than the global default\n    set(rustc_override \"$<TARGET_PROPERTY:${target_name},INTERFACE_CORROSION_RUSTC>\")\n    set(cargo_override \"$<TARGET_PROPERTY:${target_name},INTERFACE_CORROSION_CARGO>\")\n    set(rustc_bin \"$<IF:$<BOOL:${rustc_override}>,${rustc_override},${_CORROSION_RUSTC}>\")\n    set(cargo_bin \"$<IF:$<BOOL:${cargo_override}>,${cargo_override},${_CORROSION_CARGO}>\")\n\n\n    # Rust will add `-lSystem` as a flag for the linker on macOS. Adding the -L flag via RUSTFLAGS only fixes the\n    # problem partially - buildscripts still break, since they won't receive the RUSTFLAGS. This seems to only be a\n    # problem if we specify the linker ourselves (which we do, since this is necessary for e.g. linking C++ code).\n    # We can however set `LIBRARY_PATH`, which is propagated to the build-script-build properly.\n    if(NOT CMAKE_CROSSCOMPILING AND CMAKE_SYSTEM_NAME STREQUAL \"Darwin\")\n        # not needed anymore on macos 13 (and causes issues)\n        if(${CMAKE_SYSTEM_VERSION} VERSION_LESS 22)\n        set(cargo_library_path \"LIBRARY_PATH=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib\")\n        endif()\n    elseif(CMAKE_CROSSCOMPILING AND CMAKE_HOST_SYSTEM_NAME STREQUAL \"Darwin\")\n        if(${CMAKE_HOST_SYSTEM_VERSION} VERSION_LESS 22)\n            set(cargo_library_path \"$<${hostbuild_override}:LIBRARY_PATH=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib>\")\n        endif()\n    endif()\n\n    set(cargo_profile_set \"$<BOOL:${cargo_profile_target_property}>\")\n    # In the default case just specify --release or nothing to stay compatible with\n    # older rust versions.\n    set(default_profile_option \"$<$<NOT:$<OR:$<CONFIG:Debug>,$<CONFIG:>>>:--release>\")\n    # evaluates to either `--profile=<custom_profile>`, `--release` or nothing (for debug).\n    set(cargo_profile \"$<IF:${cargo_profile_set},--profile=${cargo_profile_target_property},${default_profile_option}>\")\n\n    # If the profile name is `dev` change the dir name to `debug`.\n    set(is_dev_profile \"$<STREQUAL:${cargo_profile_target_property},dev>\")\n    set(profile_dir_override \"$<${is_dev_profile}:debug>\")\n    set(profile_dir_is_overridden \"$<BOOL:${profile_dir_override}>\")\n    set(custom_profile_build_type_dir \"$<IF:${profile_dir_is_overridden},${profile_dir_override},${cargo_profile_target_property}>\")\n\n    set(default_build_type_dir \"$<IF:$<OR:$<CONFIG:Debug>,$<CONFIG:>>,debug,release>\")\n    set(build_type_dir \"$<IF:${cargo_profile_set},${custom_profile_build_type_dir},${default_build_type_dir}>\")\n\n    # We set a target folder based on the manifest path so if you build multiple workspaces (or standalone projects\n    # without workspace) they won't collide if they use a common dependency. This would confuse cargo and trigger\n    # unnecessary rebuilds\n    cmake_path(GET workspace_manifest_path PARENT_PATH parent_path)\n    cmake_path(GET parent_path PARENT_PATH grandparent_path)\n    string(REPLACE \"${grandparent_path}/\" \"\" cargo_folder_name \"${parent_path}\")\n    string(SHA1 cargo_path_hash ${workspace_manifest_path})\n    # Include a hash of the full path in case there are multiple projects with the same folder name\n    string(SUBSTRING \"${cargo_path_hash}\" 0 5 cargo_path_hash)\n    cmake_path(APPEND CMAKE_BINARY_DIR ${build_dir} cargo \"${cargo_folder_name}_${cargo_path_hash}\"\n               OUTPUT_VARIABLE cargo_target_dir)\n    set(cargo_build_dir \"${cargo_target_dir}/${target_artifact_dir}/${build_type_dir}\")\n    set(\"${out_cargo_build_out_dir}\" \"${cargo_build_dir}\" PARENT_SCOPE)\n\n    set(corrosion_cc_rs_flags)\n\n    if(CMAKE_C_COMPILER)\n        # This variable is read by cc-rs (often used in build scripts) to determine the c-compiler.\n        # It can still be overridden if the user sets the non underscore variant via the environment variables\n        # on the target.\n        list(APPEND corrosion_cc_rs_flags \"CC_${stripped_target_triple}=${CMAKE_C_COMPILER}\")\n    endif()\n    if(CMAKE_CXX_COMPILER)\n        list(APPEND corrosion_cc_rs_flags \"CXX_${stripped_target_triple}=${CMAKE_CXX_COMPILER}\")\n    endif()\n    # cc-rs doesn't seem to support `llvm-ar` (commandline syntax), wo we might as well just use\n    # the default AR.\n    if(CMAKE_AR AND NOT (Rust_CARGO_TARGET_ENV STREQUAL \"msvc\"))\n        list(APPEND corrosion_cc_rs_flags \"AR_${stripped_target_triple}=${CMAKE_AR}\")\n    endif()\n\n    # When using XCode to target iOS / iOSSimulator, `cc` will be a compiler that targets iOS.\n    # (Presumably this is because XCode modifies PATH).\n    # This causes linker errors, because Rust compiles build-scripts and proc-macros for the host-platform, and\n    # assumes `cc` is a valid linker driver for the host platform (but in this case `cc` targets iOS).\n    # To work around this we explicitly set the linker for the host platform.\n    unset(cargo_host_target_linker)\n    if(CMAKE_HOST_SYSTEM_NAME STREQUAL \"Darwin\" AND CMAKE_SYSTEM_NAME STREQUAL \"iOS\")\n        string(TOUPPER \"${Rust_CARGO_HOST_TARGET_CACHED}\" host_target_upper)\n        string(REPLACE \"-\" \"_\" host_target_upper_underscore \"${host_target_upper}\")\n        set(cargo_host_target_linker \"CARGO_TARGET_${host_target_upper_underscore}_LINKER=$CACHE{CORROSION_HOST_TARGET_LINKER}\")\n        message(DEBUG \"Setting `${cargo_host_target_linker}` for target ${target_name} to workaround a hostbuild\"\n            \" issue when building targets for iOS.\"\n        )\n    endif()\n\n    # Since we instruct cc-rs to use the compiler found by CMake, it is likely one that requires also\n    # specifying the target sysroot to use. CMake's generator makes sure to pass --sysroot with\n    # CMAKE_OSX_SYSROOT. Fortunately the compilers Apple ships also respect the SDKROOT environment\n    # variable, which we can set for use when cc-rs invokes the compiler.\n    if(CMAKE_HOST_SYSTEM_NAME STREQUAL \"Darwin\" AND CMAKE_OSX_SYSROOT)\n        list(APPEND corrosion_cc_rs_flags \"SDKROOT=${CMAKE_OSX_SYSROOT}\")\n    endif()\n\n    # Ensure that cc-rs targets same Apple platform version as the CMake build\n    if(CMAKE_SYSTEM_NAME STREQUAL \"Darwin\" AND CMAKE_OSX_DEPLOYMENT_TARGET)\n        list(APPEND corrosion_cc_rs_flags \"MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}\")\n    endif()\n\n    corrosion_add_target_local_rustflags(\"${target_name}\" \"$<$<BOOL:${corrosion_link_args}>:-Clink-args=${corrosion_link_args}>\")\n\n    # todo: this should probably also be guarded by if_not_host_build_condition.\n    if(COR_NO_STD)\n        corrosion_add_target_local_rustflags(\"${target_name}\" \"-Cdefault-linker-libraries=no\")\n    else()\n        corrosion_add_target_local_rustflags(\"${target_name}\" \"-Cdefault-linker-libraries=yes\")\n    endif()\n\n    set(global_joined_rustflags \"$<JOIN:${global_rustflags_target_property}, >\")\n    set(global_rustflags_genex \"$<$<BOOL:${global_rustflags_target_property}>:RUSTFLAGS=${global_joined_rustflags}>\")\n    set(local_rustflags_delimiter \"$<$<BOOL:${local_rustflags_target_property}>:-->\")\n    set(local_rustflags_genex \"$<$<BOOL:${local_rustflags_target_property}>:${local_rustflags_target_property}>\")\n\n    set(deps_link_languages_prop \"$<TARGET_PROPERTY:_cargo-build_${target_name},CARGO_DEPS_LINKER_LANGUAGES>\")\n    set(deps_link_languages \"$<TARGET_GENEX_EVAL:_cargo-build_${target_name},${deps_link_languages_prop}>\")\n    set(target_uses_cxx  \"$<IN_LIST:CXX,${deps_link_languages}>\")\n    unset(default_linker)\n    # With the MSVC ABI rustc only supports directly invoking the linker - Invoking cl as the linker driver is not supported.\n    if(NOT (Rust_CARGO_TARGET_ENV STREQUAL \"msvc\" OR COR_NO_LINKER_OVERRIDE))\n        set(default_linker \"$<IF:$<BOOL:${target_uses_cxx}>,${CMAKE_CXX_COMPILER},${CMAKE_C_COMPILER}>\")\n    endif()\n    # Used to set a linker for a specific target-triple.\n    set(cargo_target_linker_var \"CARGO_TARGET_${stripped_target_triple_upper}_LINKER\")\n    set(linker \"$<IF:${explicit_linker_defined},${explicit_linker_property},${default_linker}>\")\n    set(cargo_target_linker $<$<BOOL:${linker}>:${cargo_target_linker_var}=${linker}>)\n\n    if(Rust_CROSSCOMPILING AND (CMAKE_C_COMPILER_TARGET OR CMAKE_CXX_COMPILER_TARGET))\n        set(linker_target_triple \"$<IF:$<BOOL:${target_uses_cxx}>,${CMAKE_CXX_COMPILER_TARGET},${CMAKE_C_COMPILER_TARGET}>\")\n        set(rustflag_linker_arg \"-Clink-args=--target=${linker_target_triple}\")\n        set(rustflag_linker_arg \"$<${if_not_host_build_condition}:${rustflag_linker_arg}>\")\n        # Skip adding the linker argument, if the linker is explicitly set, since the\n        # explicit_linker_property will not be set when this function runs.\n        # Passing this rustflag is necessary for clang.\n        corrosion_add_target_local_rustflags(\"${target_name}\" \"$<$<NOT:${explicit_linker_defined}>:${rustflag_linker_arg}>\")\n    endif()\n\n    message(DEBUG \"TARGET ${target_name} produces byproducts ${build_byproducts}\")\n    message(DEBUG \"corrosion_cc_rs_flags: ${corrosion_cc_rs_flags}\")\n\n    add_custom_target(\n        _cargo-build_${target_name}\n        # Build crate\n        COMMAND\n            ${CMAKE_COMMAND} -E env\n                \"${build_env_variable_genex}\"\n                \"${global_rustflags_genex}\"\n                \"${cargo_target_linker}\"\n                \"${cargo_host_target_linker}\"\n                \"${corrosion_cc_rs_flags}\"\n                \"${cargo_library_path}\"\n                \"CORROSION_BUILD_DIR=${CMAKE_CURRENT_BINARY_DIR}\"\n                \"CARGO_BUILD_RUSTC=${rustc_bin}\"\n            \"${cargo_bin}\"\n                rustc\n                ${cargo_rustc_filter}\n                ${cargo_target_option}\n                ${_CORROSION_VERBOSE_OUTPUT_FLAG}\n                ${all_features_arg}\n                ${no_default_features_arg}\n                ${features_genex}\n                --package ${package_name}\n                ${cargo_rustc_crate_types}\n                --manifest-path \"${path_to_toml}\"\n                --target-dir \"${cargo_target_dir}\"\n                ${cargo_profile}\n                ${flags_genex}\n                # Any arguments to cargo must be placed before this line\n                ${local_rustflags_delimiter}\n                ${local_rustflags_genex}\n\n        # Note: `BYPRODUCTS` may not contain **target specific** generator expressions.\n        # This means we cannot use `${cargo_build_dir}`, since it currently uses `$<TARGET_PROPERTY>`\n        # to determine the correct target directory, depending on if the hostbuild target property is\n        # set or not.\n        # BYPRODUCTS  \"${cargo_build_dir}/${build_byproducts}\"\n        \n        # Set WORKING_DIRECTORY to the directory containing the manifest, so that configuration files\n        # such as `.cargo/config.toml` or `toolchain.toml` are applied as expected. Cargo searches for\n        # configuration files by walking upward from the current directory.\n        WORKING_DIRECTORY \"${workspace_toml_dir}\"\n        ${cor_uses_terminal}\n        COMMAND_EXPAND_LISTS\n        VERBATIM\n    )\n\n    # User exposed custom target, that depends on the internal target.\n    # Corrosion post build steps are added on the internal target, which\n    # ensures that they run before any user defined post build steps on this\n    # target.\n    add_custom_target(\n        cargo-build_${target_name}\n        ALL\n    )\n    add_dependencies(cargo-build_${target_name} _cargo-build_${target_name})\n\n    # Add custom target before actual build that user defined custom commands (e.g. code generators) can\n    # use as a hook to do something before the build. This mainly exists to not expose the `_cargo-build` targets.\n    add_custom_target(cargo-prebuild_${target_name})\n    add_dependencies(_cargo-build_${target_name} cargo-prebuild_${target_name})\n    if(NOT TARGET cargo-prebuild)\n        add_custom_target(cargo-prebuild)\n    endif()\n    add_dependencies(cargo-prebuild cargo-prebuild_${target_name})\n\n    add_custom_target(\n        cargo-clean_${target_name}\n        COMMAND\n            \"${cargo_bin}\" clean ${cargo_target_option}\n            -p ${package_name} --manifest-path \"${path_to_toml}\"\n        # Set WORKING_DIRECTORY to the directory containing the manifest, so that configuration files\n        # such as `.cargo/config.toml` or `toolchain.toml` are applied as expected. Cargo searches for\n        # configuration files by walking upward from the current directory.\n        WORKING_DIRECTORY \"${workspace_toml_dir}\"\n        ${cor_uses_terminal}\n    )\n\n    if (NOT TARGET cargo-clean)\n        add_custom_target(cargo-clean)\n    endif()\n    add_dependencies(cargo-clean cargo-clean_${target_name})\nendfunction()\n\n#[=======================================================================[.md:\nANCHOR: corrosion-import-crate\n```cmake\ncorrosion_import_crate(\n        MANIFEST_PATH <path/to/cargo.toml>\n        [ALL_FEATURES]\n        [NO_DEFAULT_FEATURES]\n        [NO_STD]\n        [NO_LINKER_OVERRIDE]\n        [NO_USES_TERMINAL]\n        [LOCKED]\n        [FROZEN]\n        [PROFILE <cargo-profile>]\n        [IMPORTED_CRATES <variable-name>]\n        [CRATE_TYPES <crate_type1> ... <crate_typeN>]\n        [OVERRIDE_CRATE_TYPE <crate_name>=<crate_type1,crate_type2,...> ...]\n        [CRATES <crate1> ... <crateN>]\n        [FEATURES <feature1> ... <featureN>]\n        [FLAGS <flag1> ... <flagN>]\n)\n```\n* **MANIFEST_PATH**: Path to a [Cargo.toml Manifest] file.\n* **ALL_FEATURES**: Equivalent to [--all-features] passed to cargo build\n* **NO_DEFAULT_FEATURES**: Equivalent to [--no-default-features] passed to cargo build\n* **NO_STD**:  Disable linking of standard libraries (required for no_std crates).\n* **NO_LINKER_OVERRIDE**: Will let Rust/Cargo determine which linker to use instead of corrosion (when linking is invoked by Rust)\n* **NO_USES_TERMINAL**: Don't pass the `USES_TERMINAL` flag when creating the custom CMake targets.\n* **LOCKED**: Pass [`--locked`] to cargo build and cargo metadata.\n* **FROZEN**: Pass [`--frozen`] to cargo build and cargo metadata.\n* **PROFILE**: Specify cargo build profile (`dev`/`release` or a [custom profile]; `bench` and `test` are not supported)\n* **IMPORTED_CRATES**: Save the list of imported crates into the variable with the provided name in the current scope.\n* **CRATE_TYPES**: Only import the specified crate types. Valid values: `staticlib`, `cdylib`, `bin`.\n* **OVERRIDE_CRATE_TYPE**: Override the crate-types of a cargo crate with the given comma-separated values.\n                           Internally uses the `rustc` flag [`--crate-type`] to override the crate-type.\n                           Valid values for the crate types are the library types `staticlib` and `cdylib`.\n* **CRATES**: Only import the specified crates from a workspace. Values: Crate names.\n* **FEATURES**: Enable the specified features. Equivalent to [--features] passed to `cargo build`.\n* **FLAGS**:  Arbitrary flags to `cargo build`.\n\n[custom profile]: https://doc.rust-lang.org/cargo/reference/profiles.html#custom-profiles\n[--all-features]: https://doc.rust-lang.org/cargo/reference/features.html#command-line-feature-options\n[--no-default-features]: https://doc.rust-lang.org/cargo/reference/features.html#command-line-feature-options\n[--features]: https://doc.rust-lang.org/cargo/reference/features.html#command-line-feature-options\n[`--locked`]: https://doc.rust-lang.org/cargo/commands/cargo.html#manifest-options\n[`--frozen`]: https://doc.rust-lang.org/cargo/commands/cargo.html#manifest-options\n[`--crate-type`]: https://doc.rust-lang.org/rustc/command-line-arguments.html#--crate-type-a-list-of-types-of-crates-for-the-compiler-to-emit\n[Cargo.toml Manifest]: https://doc.rust-lang.org/cargo/appendix/glossary.html#manifest\n\nANCHOR_END: corrosion-import-crate\n#]=======================================================================]\nfunction(corrosion_import_crate)\n    set(OPTIONS\n        ALL_FEATURES\n        NO_DEFAULT_FEATURES\n        NO_STD\n        NO_LINKER_OVERRIDE\n        NO_USES_TERMINAL\n        LOCKED\n        FROZEN)\n    set(ONE_VALUE_KEYWORDS MANIFEST_PATH PROFILE IMPORTED_CRATES)\n    set(MULTI_VALUE_KEYWORDS CRATE_TYPES CRATES FEATURES FLAGS OVERRIDE_CRATE_TYPE)\n    cmake_parse_arguments(COR \"${OPTIONS}\" \"${ONE_VALUE_KEYWORDS}\" \"${MULTI_VALUE_KEYWORDS}\" ${ARGN})\n    list(APPEND CMAKE_MESSAGE_CONTEXT \"corrosion_import_crate\")\n\n    if(DEFINED COR_UNPARSED_ARGUMENTS)\n        message(AUTHOR_WARNING \"Unexpected arguments: \" ${COR_UNPARSED_ARGUMENTS}\n            \"\\nCorrosion will ignore these unexpected arguments.\"\n            )\n    endif()\n    if(DEFINED COR_KEYWORDS_MISSING_VALUES)\n        message(DEBUG \"Note: the following keywords passed to corrosion_import_crate had no associated value(s): \"\n            ${COR_KEYWORDS_MISSING_VALUES}\n        )\n    endif()\n    if (NOT DEFINED COR_MANIFEST_PATH)\n        message(FATAL_ERROR \"MANIFEST_PATH is a required keyword to corrosion_add_crate\")\n    endif()\n    _corrosion_option_passthrough_helper(NO_LINKER_OVERRIDE COR no_linker_override)\n    _corrosion_option_passthrough_helper(LOCKED COR locked)\n    _corrosion_option_passthrough_helper(FROZEN COR frozen)\n    _corrosion_arg_passthrough_helper(CRATES COR crate_allowlist)\n    _corrosion_arg_passthrough_helper(CRATE_TYPES COR crate_types)\n\n    if(COR_PROFILE)\n        if(Rust_VERSION VERSION_LESS 1.57.0)\n            message(FATAL_ERROR \"Selecting custom profiles via `PROFILE` requires at least rust 1.57.0, but you \"\n                        \"have ${Rust_VERSION}.\"\n        )\n        # The profile name could be part of a Generator expression, so this won't catch all occurences.\n        # Since it is hard to add an error message for genex, we don't do that here.\n        elseif(\"${COR_PROFILE}\" STREQUAL \"test\" OR \"${COR_PROFILE}\" STREQUAL \"bench\")\n            message(FATAL_ERROR \"Corrosion does not support building Rust crates with the cargo profiles\"\n                    \" `test` or `bench`. These profiles add a hash to the output artifact name that we\"\n                    \" cannot predict. Please consider using a custom cargo profile which inherits from the\"\n                    \" built-in profile instead.\"\n            )\n        endif()\n    endif()\n\n    # intended to be used with foreach(... ZIP_LISTS ...), meaning\n    # that the crate_types at index i of `override_crate_type_types_list` are\n    # for the package_name at index i of `override_crate_type_package_name_list`.\n    # It would really be nice if CMake had structs or dicts.\n    unset(override_crate_type_package_name_list)\n    unset(override_crate_type_types_list)\n    unset(OVERRIDE_CRATE_TYPE_ARGS)\n    if(DEFINED COR_OVERRIDE_CRATE_TYPE)\n        string(JOIN \" \" usage_help\n               \"Each argument to OVERRIDE_CRATE_TYPE must be of the form `<package_name>=<crate_type(s)>.\"\n               \"The package_name must be a valid cargo package name and the crate_type must be \"\n               \"a comma-seperated list with valid values being `staticlib`, `cdylib` and `bin`\"\n        )\n        foreach(entry IN LISTS COR_OVERRIDE_CRATE_TYPE)\n            string(REPLACE \"=\" \";\" key_val_list ${entry})\n            list(LENGTH key_val_list key_val_list_len)\n            if(NOT key_val_list_len EQUAL \"2\")\n                message(FATAL_ERROR \"Invalid argument: `${entry}` for parameter OVERRIDE_CRATE_TYPE!\\n\"\n                    \"${usage_help}\"\n                )\n            endif()\n            list(GET key_val_list \"0\" package_name)\n            list(GET key_val_list \"1\" crate_types)\n            list(APPEND override_crate_type_package_name_list \"${package_name}\")\n            list(APPEND override_crate_type_types_list \"${crate_types}\")\n        endforeach()\n        list(LENGTH override_crate_type_package_name_list num_override_packages)\n        list(LENGTH override_crate_type_types_list num_override_packages2)\n        if(\"${Rust_VERSION}\" VERSION_LESS \"1.64\")\n            message(WARNING \"OVERRIDE_CRATE_TYPE requires at Rust 1.64 or newer. Ignoring the option\")\n        elseif(NOT num_override_packages EQUAL num_override_packages2)\n            message(WARNING \"Internal error while parsing OVERRIDE_CRATE_TYPE arguments.\\n\"\n                    \"Corrosion will ignore this argument and continue.\"\n            )\n        else()\n            # Pass by ref: we intentionally pass the list names here!\n            set(override_crate_types_arg \"OVERRIDE_CRATE_TYPE_ARGS\" \"override_crate_type_package_name_list\" \"override_crate_type_types_list\")\n        endif()\n    endif()\n\n    if (NOT IS_ABSOLUTE \"${COR_MANIFEST_PATH}\")\n        set(COR_MANIFEST_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${COR_MANIFEST_PATH})\n    endif()\n\n    set(additional_cargo_flags ${COR_FLAGS})\n\n    if(COR_LOCKED AND NOT \"--locked\" IN_LIST additional_cargo_flags)\n        list(APPEND additional_cargo_flags  \"--locked\")\n    endif()\n    if(COR_FROZEN AND NOT \"--frozen\" IN_LIST additional_cargo_flags)\n        list(APPEND additional_cargo_flags  \"--frozen\")\n    endif()\n\n    set(imported_crates \"\")\n\n    _generator_add_cargo_targets(\n        MANIFEST_PATH\n            \"${COR_MANIFEST_PATH}\"\n        IMPORTED_CRATES\n            imported_crates\n        ${crate_allowlist}\n        ${crate_types}\n        ${no_linker_override}\n        ${override_crate_types_arg}\n    )\n\n    # Not target props yet:\n    # NO_STD\n    # NO_LINKER_OVERRIDE # We could simply zero INTERFACE_CORROSION_LINKER if this is set.\n    # LOCKED / FROZEN get merged into FLAGS after cargo metadata.\n\n    # Initialize the target properties with the arguments to corrosion_import_crate.\n    set_target_properties(\n            ${imported_crates}\n            PROPERTIES\n                \"${_CORR_PROP_ALL_FEATURES}\" \"${COR_ALL_FEATURES}\"\n                \"${_CORR_PROP_NO_DEFAULT_FEATURES}\" \"${COR_NO_DEFAULT_FEATURES}\"\n                \"${_CORR_PROP_FEATURES}\" \"${COR_FEATURES}\"\n                INTERFACE_CORROSION_CARGO_PROFILE \"${COR_PROFILE}\"\n                INTERFACE_CORROSION_CARGO_FLAGS \"${additional_cargo_flags}\"\n    )\n\n    # _CORR_PROP_ENV_VARS\n    if(DEFINED COR_IMPORTED_CRATES)\n        set(${COR_IMPORTED_CRATES} ${imported_crates} PARENT_SCOPE)\n    endif()\nendfunction()\n\nfunction(corrosion_set_linker target_name linker)\n    if(NOT linker)\n        message(FATAL_ERROR \"The linker passed to `corrosion_set_linker` may not be empty\")\n    elseif(NOT TARGET \"${target_name}\")\n        message(FATAL_ERROR \"The target `${target_name}` does not exist.\")\n    endif()\n    if(MSVC)\n        message(WARNING \"Explicitly setting the linker with the MSVC toolchain is currently not supported and ignored\")\n    endif()\n\n    if(TARGET \"${target_name}-static\" AND NOT TARGET \"${target_name}-shared\")\n        message(WARNING \"The target ${target_name} builds a static library.\"\n            \"The linker is never invoked for a static library so specifying a linker has no effect.\"\n        )\n    endif()\n\n    set_property(\n        TARGET ${target_name}\n        PROPERTY INTERFACE_CORROSION_LINKER \"${linker}\"\n    )\nendfunction()\n\nfunction(corrosion_set_hostbuild target_name)\n    # Configure the target to be compiled for the Host target and ignore any cross-compile configuration.\n    set_property(\n            TARGET ${target_name}\n            PROPERTY ${_CORR_PROP_HOST_BUILD} 1\n    )\nendfunction()\n\n# Add flags for rustc (RUSTFLAGS) which affect the target and all of it's Rust dependencies\n#\n# Additional rustflags may be passed as optional parameters after rustflag.\n# Please note, that if you import multiple targets from a package or workspace, but set different\n# Rustflags via this function, the Rust dependencies will have to be rebuilt when changing targets.\n# Consider `corrosion_add_target_local_rustflags()` as an alternative to avoid this.\nfunction(corrosion_add_target_rustflags target_name rustflag)\n    # Additional rustflags may be passed as optional parameters after rustflag.\n    set_property(\n            TARGET ${target_name}\n            APPEND\n            PROPERTY INTERFACE_CORROSION_RUSTFLAGS ${rustflag} ${ARGN}\n    )\nendfunction()\n\n# Add flags for rustc (RUSTFLAGS) which only affect the target, but none of it's (Rust) dependencies\n#\n# Additional rustflags may be passed as optional parameters after rustc_flag.\nfunction(corrosion_add_target_local_rustflags target_name rustc_flag)\n    # Set Rustflags via `cargo rustc` which only affect the current crate, but not dependencies.\n    set_property(\n            TARGET ${target_name}\n            APPEND\n            PROPERTY INTERFACE_CORROSION_LOCAL_RUSTFLAGS ${rustc_flag} ${ARGN}\n    )\nendfunction()\n\nfunction(corrosion_set_env_vars target_name env_var)\n    # Additional environment variables may be passed as optional parameters after env_var.\n    set_property(\n        TARGET ${target_name}\n        APPEND\n        PROPERTY ${_CORR_PROP_ENV_VARS} ${env_var} ${ARGN}\n    )\nendfunction()\n\nfunction(corrosion_set_cargo_flags target_name)\n    # corrosion_set_cargo_flags(<target_name> [<flag1> ... ])\n\n    set_property(\n            TARGET ${target_name}\n            APPEND\n            PROPERTY INTERFACE_CORROSION_CARGO_FLAGS ${ARGN}\n    )\nendfunction()\n\nfunction(corrosion_set_features target_name)\n    # corrosion_set_features(<target_name> [ALL_FEATURES=Bool] [NO_DEFAULT_FEATURES] [FEATURES <feature1> ... ])\n    set(options NO_DEFAULT_FEATURES)\n    set(one_value_args ALL_FEATURES)\n    set(multi_value_args FEATURES)\n    cmake_parse_arguments(\n            PARSE_ARGV 1\n            SET\n            \"${options}\"\n            \"${one_value_args}\"\n            \"${multi_value_args}\"\n    )\n\n    if(DEFINED SET_ALL_FEATURES)\n        set_property(\n                TARGET ${target_name}\n                PROPERTY ${_CORR_PROP_ALL_FEATURES} ${SET_ALL_FEATURES}\n        )\n    endif()\n    if(SET_NO_DEFAULT_FEATURES)\n        set_property(\n                TARGET ${target_name}\n                PROPERTY ${_CORR_PROP_NO_DEFAULT_FEATURES} 1\n        )\n    endif()\n    if(SET_FEATURES)\n        set_property(\n                TARGET ${target_name}\n                APPEND\n                PROPERTY ${_CORR_PROP_FEATURES} ${SET_FEATURES}\n        )\n    endif()\nendfunction()\n\nfunction(corrosion_link_libraries target_name)\n    if(TARGET \"${target_name}-static\")\n        message(DEBUG \"The target ${target_name} builds a static Rust library.\"\n                \"Calling `target_link_libraries()` instead.\"\n        )\n        target_link_libraries(\"${target_name}-static\" INTERFACE ${ARGN})\n        if(NOT TARGET \"${target_name}-shared\")\n            # Early return, since Rust won't invoke the linker for static libraries\n            return()\n        endif()\n    endif()\n    foreach(library ${ARGN})\n        set_property(\n            TARGET _cargo-build_${target_name}\n            APPEND\n            PROPERTY CARGO_DEPS_LINKER_LANGUAGES\n            $<TARGET_PROPERTY:${library},LINKER_LANGUAGE>\n        )\n\n        if (TARGET \"${library}\")\n            # This works fine, except when compiling for ios. See https://cmake.org/pipermail/cmake/2016-March/063050.html\n            # XCODE_EMIT_EFFECTIVE_PLATFORM_NAME=OFF is supposed to prevent emitting EFFECTIVE_PLATFORM_NAME, but even\n            # with CMake 4.1 and the variable set to off EFFECTIVE_PLATFORM_NAME still leaks into generator expressions,\n            # and is not correctly replaced at build time\n            set(linker_dir \"$<TARGET_LINKER_FILE_DIR:${library}>\")\n            # Probably should also affect other apple OSs with a simulator\n            if(CMAKE_SYSTEM_NAME STREQUAL \"iOS\")\n                unset(platform_name)\n                message(CHECK_START \"corrosion_link_libraries: Attempting to replace EFFECTIVE_PLATFORM_NAME\")\n                if(CMAKE_OSX_SYSROOT MATCHES \"iphoneos\")\n                    set(platform_name \"-iphoneos\")\n                elseif(CMAKE_OSX_SYSROOT MATCHES \"iphonesimulator\")\n                    set(platform_name \"-iphonesimulator\")\n                else()\n                    # Todo: CMAKE_OSX_SYSROOT can be not set - how do we handle that?\n                    message(CHECK_FAIL \"Failed to determine platform name for iOS target from sysroot ${CMAKE_OSX_SYSROOT}\")\n                endif()\n                if(DEFINED platform_name)\n                    # This is a hack to fix $EFFECTIVE_PLATFORM_NAME not expanding in TARGET_LINKER_FILE_DIR\n                    set(linker_dir \"$<PATH:REPLACE_FILENAME,${linker_dir},$<CONFIG>${platform_name}>\")\n                    message(CHECK_PASS \"done\")\n                endif()\n            endif()\n            corrosion_add_target_local_rustflags(${target_name}\n                \"-L${linker_dir}\"\n                \"-l$<TARGET_LINKER_FILE_BASE_NAME:${library}>\"\n            )\n            add_dependencies(_cargo-build_${target_name} ${library})\n        elseif(IS_ABSOLUTE \"${library}\")\n            # Linking via full path (See https://doc.rust-lang.org/rustc/command-line-arguments.html#linking-modifiers-verbatim)\n            corrosion_add_target_local_rustflags(${target_name} \"-Clink-arg=${library}\")\n        else()\n            # We have to assume ${library} is a non-CMake library name\n            corrosion_add_target_local_rustflags(${target_name} \"-l${library}\")\n        endif()\n    endforeach()\nendfunction()\n\n#[=======================================================================[.md:\nANCHOR: corrosion-install\n** EXPERIMENTAL **: This function is currently still considered experimental\n  and is not officially released yet. Feedback and Suggestions are welcome.\n\n```cmake\ncorrosion_install(TARGETS <target1> ... <targetN> [EXPORT <export-name>]\n                  [[ARCHIVE|LIBRARY|RUNTIME|PUBLIC_HEADER]\n                   [DESTINATION <dir>]\n                   [PERMISSIONS <permissions...>]\n                   [CONFIGURATIONS [Debug|Release|<other-configuration>]]\n                  ] [...])\n```\n* **TARGETS**: Target or targets to install.\n* **EXPORT**: Creates an export that can be installed with `install(EXPORT)`. <export-name> must be globally unique.\n             Also creates a file at ${CMAKE_BINARY_DIR}/corrosion/<export-name>Corrosion.cmake that must be included in the installed config file.\n* **ARCHIVE**/**LIBRARY**/**RUNTIME**/PUBLIC_HEADER: Designates that the following settings only apply to that specific type of object.\n* **DESTINATION**: The subdirectory within the CMAKE_INSTALL_PREFIX that a specific object should be placed. Defaults to values from GNUInstallDirs.\n* **PERMISSIONS**: The permissions of files copied into the install prefix.\n\nAny `PUBLIC` or `INTERFACE` [file sets] will be installed.\n\n[file sets]: https://cmake.org/cmake/help/latest/command/target_sources.html#file-sets\n\nANCHOR_END: corrosion-install\n#]=======================================================================]\nfunction(corrosion_install)\n    # Default install dirs\n    include(GNUInstallDirs)\n\n    # Parse arguments to corrosion_install\n    list(GET ARGN 0 INSTALL_TYPE)\n    list(REMOVE_AT ARGN 0)\n\n    # The different install types that are supported. Some targets may have more than one of these\n    # types. For example, on Windows, a shared library will have both an ARCHIVE component and a\n    # RUNTIME component.\n    set(INSTALL_TARGET_TYPES ARCHIVE LIBRARY RUNTIME PRIVATE_HEADER PUBLIC_HEADER)\n\n    # Arguments to each install target type\n    set(OPTIONS)\n    set(ONE_VALUE_ARGS DESTINATION)\n    set(MULTI_VALUE_ARGS PERMISSIONS CONFIGURATIONS)\n    set(TARGET_ARGS ${OPTIONS} ${ONE_VALUE_ARGS} ${MULTI_VALUE_ARGS})\n\n    if (INSTALL_TYPE STREQUAL \"TARGETS\")\n        # Extract targets\n        set(INSTALL_TARGETS)\n        list(LENGTH ARGN ARGN_LENGTH)\n        set(DELIMITERS EXPORT ${INSTALL_TARGET_TYPES} ${TARGET_ARGS})\n        while(ARGN_LENGTH)\n            # If we hit another keyword, stop - we've found all the targets\n            list(GET ARGN 0 FRONT)\n            if (FRONT IN_LIST DELIMITERS)\n                break()\n            endif()\n\n            list(APPEND INSTALL_TARGETS ${FRONT})\n            list(REMOVE_AT ARGN 0)\n\n            # Update ARGN_LENGTH\n            list(LENGTH ARGN ARGN_LENGTH)\n        endwhile()\n\n        # Check if there are any args left before proceeding\n        list(LENGTH ARGN ARGN_LENGTH)\n        if (ARGN_LENGTH)\n            list(GET ARGN 0 FRONT)\n            if (FRONT STREQUAL \"EXPORT\")\n                list(REMOVE_AT ARGN 0) # Pop \"EXPORT\"\n\n                list(GET ARGN 0 EXPORT_NAME)\n                list(REMOVE_AT ARGN 0) # Pop <export-name>\n                set(EXTRA_TARGETS_EXPORT_NAME ${EXPORT_NAME}Corrosion.cmake)\n                set(EXPORT_NAME EXPORT ${EXPORT_NAME})\n                set(EXPORT_FILE_PATH \"${CMAKE_BINARY_DIR}/corrosion/${EXTRA_TARGETS_EXPORT_NAME}\")\n                # Remove first, since otherwise we will append to the file on every reconfigure.\n                # Assumes that the corrosion_install will only be called once for a given EXPORT_NAME.\n                file(REMOVE \"${EXPORT_FILE_PATH}\")\n            endif()\n        else()\n            # Prevent variable set in user code from interfering\n            set(EXPORT_NAME)\n        endif()\n\n        # Loop over all arguments and get options for each install target type\n        list(LENGTH ARGN ARGN_LENGTH)\n        while(ARGN_LENGTH)\n            # Check if we're dealing with arguments for a specific install target type, or with\n            # default options for all target types.\n            list(GET ARGN 0 FRONT)\n            if (FRONT IN_LIST INSTALL_TARGET_TYPES)\n                set(INSTALL_TARGET_TYPE ${FRONT})\n                list(REMOVE_AT ARGN 0)\n            else()\n                set(INSTALL_TARGET_TYPE DEFAULT)\n            endif()\n\n            # Gather the arguments to this install type\n            set(ARGS)\n            list(LENGTH ARGN ARGN_LENGTH)\n            while(ARGN_LENGTH)\n                # If the next keyword is an install target type, then break - arguments have been\n                # gathered.\n                list(GET ARGN 0 FRONT)\n                if (FRONT IN_LIST INSTALL_TARGET_TYPES)\n                    break()\n                endif()\n\n                list(APPEND ARGS ${FRONT})\n                list(REMOVE_AT ARGN 0)\n\n                list(LENGTH ARGN ARGN_LENGTH)\n            endwhile()\n\n            # Parse the arguments and register the file install\n            cmake_parse_arguments(\n                COR \"${OPTIONS}\" \"${ONE_VALUE_ARGS}\" \"${MULTI_VALUE_ARGS}\" ${ARGS})\n\n            if (COR_DESTINATION)\n                set(COR_INSTALL_${INSTALL_TARGET_TYPE}_DESTINATION ${COR_DESTINATION})\n            endif()\n\n            if (COR_PERMISSIONS)\n                set(COR_INSTALL_${INSTALL_TARGET_TYPE}_PERMISSIONS ${COR_PERMISSIONS})\n            endif()\n\n            if (COR_CONFIGURATIONS)\n                set(COR_INSTALL_${INSTALL_TARGET_TYPE}_CONFIGURATIONS ${COR_CONFIGURATIONS})\n            endif()\n\n            # Update ARG_LENGTH\n            list(LENGTH ARGN ARGN_LENGTH)\n        endwhile()\n\n        # Default permissions for all files\n        set(DEFAULT_PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)\n\n        # Loop through each install target and register file installations\n        foreach(INSTALL_TARGET ${INSTALL_TARGETS})\n            if(NOT TARGET ${INSTALL_TARGET})\n                message(FATAL_ERROR \"Install target ${INSTALL_TARGET} is not a valid target\")\n            endif()\n            # Don't both implementing target type differentiation using generator expressions since\n            # TYPE cannot change after target creation\n            get_property(\n                TARGET_TYPE\n                TARGET ${INSTALL_TARGET} PROPERTY TYPE\n            )\n\n            # Install executable files first\n            if (TARGET_TYPE STREQUAL \"EXECUTABLE\")\n                if (DEFINED COR_INSTALL_RUNTIME_DESTINATION)\n                    set(DESTINATION ${COR_INSTALL_RUNTIME_DESTINATION})\n                elseif (DEFINED COR_INSTALL_DEFAULT_DESTINATION)\n                    set(DESTINATION ${COR_INSTALL_DEFAULT_DESTINATION})\n                else()\n                    set(DESTINATION ${CMAKE_INSTALL_BINDIR})\n                endif()\n\n                if (DEFINED COR_INSTALL_RUNTIME_PERMISSIONS)\n                    set(PERMISSIONS ${COR_INSTALL_RUNTIME_PERMISSIONS})\n                elseif (DEFINED COR_INSTALL_DEFAULT_PERMISSIONS)\n                    set(PERMISSIONS ${COR_INSTALL_DEFAULT_PERMISSIONS})\n                else()\n                    set(\n                        PERMISSIONS\n                        ${DEFAULT_PERMISSIONS} OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)\n                endif()\n\n                if (DEFINED COR_INSTALL_RUNTIME_CONFIGURATIONS)\n                    set(CONFIGURATIONS CONFIGURATIONS ${COR_INSTALL_RUNTIME_CONFIGURATIONS})\n                elseif (DEFINED COR_INSTALL_DEFAULT_CONFIGURATIONS)\n                    set(CONFIGURATIONS CONFIGURATIONS ${COR_INSTALL_DEFAULT_CONFIGURATIONS})\n                else()\n                    set(CONFIGURATIONS)\n                endif()\n\n                install(\n                    FILES $<TARGET_FILE:${INSTALL_TARGET}>\n                    DESTINATION ${DESTINATION}\n                    PERMISSIONS ${PERMISSIONS}\n                    ${CONFIGURATIONS}\n                )\n            elseif(TARGET_TYPE STREQUAL \"INTERFACE_LIBRARY\")\n                if(TARGET ${INSTALL_TARGET}-static)\n                    if (DEFINED COR_INSTALL_ARCHIVE_DESTINATION)\n                        set(DESTINATION ${COR_INSTALL_ARCHIVE_DESTINATION})\n                    elseif (DEFINED COR_INSTALL_DEFAULT_DESTINATION)\n                        set(DESTINATION ${COR_INSTALL_DEFAULT_DESTINATION})\n                    else()\n                        set(DESTINATION ${CMAKE_INSTALL_LIBDIR})\n                    endif()\n\n                    if (DEFINED COR_INSTALL_ARCHIVE_PERMISSIONS)\n                        set(PERMISSIONS ${COR_INSTALL_ARCHIVE_PERMISSIONS})\n                    elseif (DEFINED COR_INSTALL_DEFAULT_PERMISSIONS)\n                        set(PERMISSIONS ${COR_INSTALL_DEFAULT_PERMISSIONS})\n                    else()\n                        set(PERMISSIONS ${DEFAULT_PERMISSIONS})\n                    endif()\n\n                    if (DEFINED COR_INSTALL_ARCHIVE_CONFIGURATIONS)\n                        set(CONFIGURATIONS CONFIGURATIONS ${COR_INSTALL_ARCHIVE_CONFIGURATIONS})\n                    elseif (DEFINED COR_INSTALL_DEFAULT_CONFIGURATIONS)\n                        set(CONFIGURATIONS CONFIGURATIONS ${COR_INSTALL_DEFAULT_CONFIGURATIONS})\n                    else()\n                        set(CONFIGURATIONS)\n                    endif()\n\n                    install(\n                            FILES $<TARGET_PROPERTY:${INSTALL_TARGET}-static,IMPORTED_LOCATION>\n                            DESTINATION ${DESTINATION}\n                            PERMISSIONS ${PERMISSIONS}\n                            ${CONFIGURATIONS}\n                    )\n\n                    if(EXPORT_NAME)\n                        get_target_property(COR_FILE_NAME ${INSTALL_TARGET}-static COR_FILE_NAME)\n                        file(APPEND \"${EXPORT_FILE_PATH}\"\n\"\nadd_library(${INSTALL_TARGET}-static STATIC IMPORTED)\nset_target_properties(${INSTALL_TARGET}-static\n    PROPERTIES\n    IMPORTED_LOCATION \\\"\\${PACKAGE_PREFIX_DIR}/${DESTINATION}/${COR_FILE_NAME}\\\"\n)\n\"\n                        )\n                    endif()\n                endif()\n\n                if(TARGET ${INSTALL_TARGET}-shared)\n                    if (DEFINED COR_INSTALL_LIBRARY_DESTINATION)\n                        set(DESTINATION ${COR_INSTALL_LIBRARY_DESTINATION})\n                    elseif (DEFINED COR_INSTALL_DEFAULT_DESTINATION)\n                        set(DESTINATION ${COR_INSTALL_DEFAULT_DESTINATION})\n                    else()\n                        set(DESTINATION ${CMAKE_INSTALL_LIBDIR})\n                    endif()\n\n                    if (DEFINED COR_INSTALL_LIBRARY_PERMISSIONS)\n                        set(PERMISSIONS ${COR_INSTALL_LIBRARY_PERMISSIONS})\n                    elseif (DEFINED COR_INSTALL_DEFAULT_PERMISSIONS)\n                        set(PERMISSIONS ${COR_INSTALL_DEFAULT_PERMISSIONS})\n                    else()\n                        set(\n                            PERMISSIONS\n                            ${DEFAULT_PERMISSIONS} OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE\n                        )\n                    endif()\n\n                    if (DEFINED COR_INSTALL_LIBRARY_CONFIGURATIONS)\n                        set(CONFIGURATIONS CONFIGURATIONS ${COR_INSTALL_LIBRARY_CONFIGURATIONS})\n                    elseif (DEFINED COR_INSTALL_DEFAULT_CONFIGURATIONS)\n                        set(CONFIGURATIONS CONFIGURATIONS ${COR_INSTALL_DEFAULT_CONFIGURATIONS})\n                    else()\n                        set(CONFIGURATIONS)\n                    endif()\n\n                    install(\n                            IMPORTED_RUNTIME_ARTIFACTS ${INSTALL_TARGET}-shared\n                            PERMISSIONS ${PERMISSIONS}\n                            DESTINATION ${DESTINATION}\n                            ${CONFIGURATIONS}\n                    )\n\n                    if(EXPORT_NAME)\n                        get_target_property(COR_FILE_NAME ${INSTALL_TARGET}-shared COR_FILE_NAME)\n                        file(APPEND \"${EXPORT_FILE_PATH}\"\n\"\nadd_library(${INSTALL_TARGET}-shared SHARED IMPORTED)\nset_target_properties(${INSTALL_TARGET}-shared\n    PROPERTIES\n    IMPORTED_LOCATION \\\"\\${PACKAGE_PREFIX_DIR}/${DESTINATION}/${COR_FILE_NAME}\\\"\n)\n\"\n                            )\n\n                            get_target_property(COR_IMPLIB_FILE_NAME ${INSTALL_TARGET}-shared COR_IMPLIB_FILE_NAME)\n                            if (NOT COR_IMPLIB_FILE_NAME MATCHES .*-NOTFOUND)\n                                file(APPEND \"${EXPORT_FILE_PATH}\"\n\"\nset_target_properties(${INSTALL_TARGET}-shared\n    PROPERTIES\n    IMPORTED_IMPLIB \\\"\\${PACKAGE_PREFIX_DIR}/${DESTINATION}/${COR_IMPLIB_FILE_NAME}\\\"\n)\"\n                                )\n                            endif()\n                    endif()\n                endif()\n            else()\n                message(FATAL_ERROR \"Unknown target type ${TARGET_TYPE} for install target ${INSTALL_TARGET}\")\n            endif()\n\n            # Executables can also have export tables, so they _might_ also need header files\n            if (DEFINED COR_INSTALL_PUBLIC_HEADER_DESTINATION)\n                set(DESTINATION ${COR_INSTALL_PUBLIC_HEADER_DESTINATION})\n            elseif (DEFINED COR_INSTALL_DEFAULT_DESTINATION)\n                set(DESTINATION ${COR_INSTALL_DEFAULT_DESTINATION})\n            else()\n                set(DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})\n            endif()\n\n            if (DEFINED COR_INSTALL_PUBLIC_HEADER_PERMISSIONS)\n                set(PERMISSIONS ${COR_INSTALL_PUBLIC_HEADER_PERMISSIONS})\n            elseif (DEFINED COR_INSTALL_DEFAULT_PERMISSIONS)\n                set(PERMISSIONS ${COR_INSTALL_DEFAULT_PERMISSIONS})\n            else()\n                # Directories need OWNER_EXECUTE in order to be deletable by owner\n                set(PERMISSIONS ${DEFAULT_PERMISSIONS} OWNER_EXECUTE)\n            endif()\n\n            if (DEFINED COR_INSTALL_PUBLIC_HEADER_CONFIGURATIONS)\n                set(CONFIGURATIONS CONFIGURATIONS ${COR_INSTALL_PUBLIC_HEADER_CONFIGURATIONS})\n            elseif (DEFINED COR_INSTALL_DEFAULT_CONFIGURATIONS)\n                set(CONFIGURATIONS CONFIGURATIONS ${COR_INSTALL_DEFAULT_CONFIGURATIONS})\n            else()\n                set(CONFIGURATIONS)\n            endif()\n\n            get_target_property(FILE_SET ${INSTALL_TARGET} INTERFACE_HEADER_SETS)\n            if(NOT FILE_SET OR FILE_SET MATCHES .*-NOTFOUND)\n                set(TARGET_HAS_FILE_SET FALSE)\n            else()\n                set(TARGET_HAS_FILE_SET TRUE)\n            endif()\n\n            if(NOT TARGET_HAS_FILE_SET)\n                if(EXPORT_NAME)\n                    # We still need to generate a EXPORT but we can't do that with install(DIRECTORY)\n                    install(TARGETS ${INSTALL_TARGET} ${EXPORT_NAME})\n                endif()\n\n                set(PUBLIC_HEADER_PROPERTIES INCLUDE_DIRECTORIES PUBLIC_INCLUDE_DIRECTORIES INTERFACE_INCLUDE_DIRECTORIES)\n                foreach(PUBLIC_HEADER_PROPERTY ${PUBLIC_HEADER_PROPERTIES})\n                    get_target_property(PUBLIC_HEADER ${INSTALL_TARGET} ${PUBLIC_HEADER_PROPERTY})\n\n                    if(NOT PUBLIC_HEADER MATCHES .*-NOTFOUND)\n                        foreach(INCLUDE_DIRECTORY ${PUBLIC_HEADER})\n                            install(\n                                    DIRECTORY ${INCLUDE_DIRECTORY}\n                                    DESTINATION .\n                                    FILE_PERMISSIONS ${PERMISSIONS}\n                                    DIRECTORY_PERMISSIONS ${PERMISSIONS}\n                                    ${CONFIGURATIONS}\n                            )\n                        endforeach()\n                    endif()\n                endforeach()\n            else()\n                install(\n                        TARGETS ${INSTALL_TARGET}\n                        ${EXPORT_NAME}\n                        FILE_SET HEADERS\n                        DESTINATION ${DESTINATION}\n                        PERMISSIONS ${PERMISSIONS}\n                        ${CONFIGURATIONS}\n                )\n            endif()\n        endforeach()\n\n    elseif(INSTALL_TYPE STREQUAL \"EXPORT\")\n        message(FATAL_ERROR \"install(EXPORT ...) not yet implemented\")\n    else()\n        message(FATAL_ERROR \"Unknown arg: ${INSTALL_TYPE}\")\n    endif()\nendfunction()\n\nfunction(_corrosion_check_cxx_version_helper manifest_dir cxx_name out_required_version)\n    execute_process(COMMAND ${CMAKE_COMMAND} -E env\n                    \"CARGO_BUILD_RUSTC=${_CORROSION_RUSTC}\"\n                    ${_CORROSION_CARGO} tree -i \"${cxx_name}\"\n                    # Usage of `cxx` could be gated behind a feature. Features can use Generator expressions,\n                    # so we can't really know what features we will enable when building at this point.\n                    # Features should be additive though, so simply enabling all-features should work for\n                    # dependency resolution.\n                    --all-features\n                    --target all\n                    --depth=0\n                    WORKING_DIRECTORY \"${manifest_dir}\"\n                    RESULT_VARIABLE cxx_version_result\n                    OUTPUT_VARIABLE cxx_version_output\n                    ERROR_VARIABLE cxx_version_error\n    )\n    if(NOT \"${cxx_version_result}\" EQUAL \"0\")\n        message(DEBUG \"`cargo tree -i ${cxx_name}` returned an error: ${cxx_version_error}\")\n        set(\"${out_required_version}\" \"${cxx_name}-NOTFOUND\" PARENT_SCOPE)\n        return()\n    endif()\n    if(cxx_version_output MATCHES \"${cxx_name} v([0-9]+.[0-9]+.[0-9]+)\")\n        set(\"${out_required_version}\" \"${CMAKE_MATCH_1}\" PARENT_SCOPE)\n    else()\n        message(DEBUG \"Failed to parse `cargo tree -i ${cxx_name}` output: ${cxx_version_output}\")\n        set(\"${out_required_version}\" \"${cxx_name}-NOTFOUND\" PARENT_SCOPE)\n    endif()\nendfunction()\n\nfunction(_corrosion_check_cxx_version manifest_dir out_required_version)\n    # cxxbridge-cmd is known to be available in lockfiles since cxx 1.0.131.\n    # We include `cxx` as a fallback to support older versions too. `cxxbridge` should always\n    # be exactly the same version as `cxx`, so falling back to `cxx` version should not cause issues.\n    foreach(cxxbridge_name cxxbridge-cmd cxx)\n        unset(cxx_required_version)\n        _corrosion_check_cxx_version_helper(\"${manifest_dir}\"\n                                            \"${cxxbridge_name}\"\n                                            cxx_required_version)\n        if(cxx_required_version)\n            set(\"${out_required_version}\" \"${cxx_required_version}\" PARENT_SCOPE)\n            break()\n        else()\n            set(\"${out_required_version}\" \"cxx-NOTFOUND\" PARENT_SCOPE)\n        endif()\n    endforeach()\n\nendfunction()\n\n\n\n#[=======================================================================[.md:\n** EXPERIMENTAL **: This function is currently still considered experimental\n  and is not officially released yet. Feedback and Suggestions are welcome.\n\nANCHOR: corrosion_add_cxxbridge\n\n```cmake\ncorrosion_add_cxxbridge(cxx_target\n        CRATE <imported_target_name>\n        REGEN_TARGET <regen_target_name>\n        [FILES <file1.rs> <file2.rs>]\n)\n```\n\nAdds build-rules to create C++ bindings using the [cxx] crate.\n\n### Arguments:\n* `cxxtarget`: Name of the C++ library target for the bindings, which corrosion will create.\n* **FILES**: Input Rust source file containing #[cxx::bridge].\n* **CRATE**: Name of an imported Rust target. Note: Parameter may be renamed before release\n* **REGEN_TARGET**: Name of a custom target that will regenerate the cxx bindings **without** recompiling. Note: Parameter may be renamed before release\n\n#### Currently missing arguments\n\nThe following arguments to cxxbridge **currently** have no way to be passed by the user:\n- `--cfg`\n- `--cxx-impl-annotations`\n- `--include`\n\nThe created rules approximately do the following:\n- Check which version of `cxx` the Rust crate specified by the `CRATE` argument depends on.\n- Check if the exact same version of `cxxbridge-cmd` is installed (available in `PATH`)\n- If not, create a rule to build the exact same version of `cxxbridge-cmd`.\n- Create rules to run `cxxbridge` and generate\n  - The `rust/cxx.h` header\n  - A header and source file for each of the files specified in `FILES`\n- The generated sources (and header include directories) are added to the `cxxtarget` CMake\n  library target.\n\n### Limitations\n\nWe currently require the `CRATE` argument to be a target imported by Corrosion, however,\nCorrosion does not import `rlib` only libraries. As a workaround users can add\n`staticlib` to their list of crate kinds. In the future this may be solved more properly,\nby either adding an option to also import Rlib targets (without build rules) or by\nadding a `MANIFEST_PATH` argument to this function, specifying where the crate is.\n\n### Contributing\n\nSpecifically some more realistic test / demo projects and feedback about limitations would be\nwelcome.\n\n[cxx]: https://github.com/dtolnay/cxx\n\nANCHOR_END: corrosion_add_cxxbridge\n#]=======================================================================]\nfunction(corrosion_add_cxxbridge cxx_target)\n    set(OPTIONS)\n    set(ONE_VALUE_KEYWORDS CRATE REGEN_TARGET)\n    set(MULTI_VALUE_KEYWORDS FILES)\n    cmake_parse_arguments(PARSE_ARGV 1 _arg \"${OPTIONS}\" \"${ONE_VALUE_KEYWORDS}\" \"${MULTI_VALUE_KEYWORDS}\")\n\n    set(required_keywords CRATE FILES)\n    foreach(keyword ${required_keywords})\n        if(NOT DEFINED \"_arg_${keyword}\")\n            message(FATAL_ERROR \"Missing required parameter `${keyword}`.\")\n        elseif(\"${_arg_${keyword}}\" STREQUAL \"\")\n            message(FATAL_ERROR \"Required parameter `${keyword}` may not be set to an empty string.\")\n        endif()\n    endforeach()\n\n    if(DEFINED _arg_UNPARSED_ARGUMENTS)\n        message(AUTHOR_WARNING \"corrosion_add_cxxbridge was called with the following unknown arguments: \"\n                \"`${_arg_UNPARSED_ARGUMENTS}`\\n\"\n                \"Unknown arguments will be ignored.\"\n        )\n    endif()\n\n    get_target_property(manifest_path \"${_arg_CRATE}\" INTERFACE_COR_PACKAGE_MANIFEST_PATH)\n\n    if(NOT EXISTS \"${manifest_path}\")\n        message(FATAL_ERROR \"Internal error: No package manifest found at ${manifest_path}\")\n    endif()\n\n    get_filename_component(manifest_dir ${manifest_path} DIRECTORY)\n\n    _corrosion_check_cxx_version(\"${manifest_dir}\" cxx_required_version)\n\n    if(NOT cxx_required_version)\n        message(FATAL_ERROR\n                \"Failed to find a dependency on `cxxbridge-cmd` / `cxx` for crate ${_arg_CRATE}\"\n        )\n    endif()\n\n    # First check if a suitable version of cxxbridge is installed\n    find_program(INSTALLED_CXXBRIDGE cxxbridge PATHS \"$ENV{HOME}/.cargo/bin/\")\n    mark_as_advanced(INSTALLED_CXXBRIDGE)\n    if(INSTALLED_CXXBRIDGE)\n        execute_process(COMMAND ${INSTALLED_CXXBRIDGE} --version OUTPUT_VARIABLE cxxbridge_version_output)\n        if(cxxbridge_version_output MATCHES \"cxxbridge ([0-9]+.[0-9]+.[0-9]+)\")\n            set(cxxbridge_version \"${CMAKE_MATCH_1}\")\n        else()\n            set(cxxbridge_version \"\")\n        endif()\n    endif()\n\n    set(cxxbridge \"\")\n    if(cxxbridge_version)\n        if(cxxbridge_version VERSION_EQUAL cxx_required_version)\n            set(cxxbridge \"${INSTALLED_CXXBRIDGE}\")\n            if(NOT TARGET \"cxxbridge_v${cxx_required_version}\")\n                # Add an empty target.\n                add_custom_target(\"cxxbridge_v${cxx_required_version}\"\n                    )\n            endif()\n        endif()\n    endif()\n\n    # No suitable version of cxxbridge was installed, so use custom target to build correct version.\n    if(NOT cxxbridge)\n        if(NOT TARGET \"cxxbridge_v${cxx_required_version}\")\n            unset(executable_postfix)\n            if(Rust_CARGO_HOST_OS STREQUAL \"windows\")\n                set(executable_postfix \".exe\")\n            endif()\n\n            add_custom_command(OUTPUT \"${CMAKE_BINARY_DIR}/corrosion/cxxbridge_v${cxx_required_version}/bin/cxxbridge${executable_postfix}\"\n                COMMAND\n                ${CMAKE_COMMAND} -E make_directory \"${CMAKE_BINARY_DIR}/corrosion/cxxbridge_v${cxx_required_version}\"\n                COMMAND\n                    ${CMAKE_COMMAND} -E env\n                        \"CARGO_BUILD_RUSTC=$CACHE{CORROSION_TOOLS_RUSTC}\"\n                    $CACHE{CORROSION_TOOLS_CARGO} install\n                    cxxbridge-cmd\n                    --version \"${cxx_required_version}\"\n                    --locked\n                    --root \"${CMAKE_BINARY_DIR}/corrosion/cxxbridge_v${cxx_required_version}\"\n                    --quiet\n                    # todo: use --target-dir to potentially reuse artifacts\n                COMMENT \"Building cxxbridge (version ${cxx_required_version}) with Rust toolchain $CACHE{CORROSION_TOOLS_RUST_TOOLCHAIN}\"\n                )\n            add_custom_target(\"cxxbridge_v${cxx_required_version}\"\n                DEPENDS \"${CMAKE_BINARY_DIR}/corrosion/cxxbridge_v${cxx_required_version}/bin/cxxbridge${executable_postfix}\"\n                )\n        endif()\n        set(cxxbridge \"${CMAKE_BINARY_DIR}/corrosion/cxxbridge_v${cxx_required_version}/bin/cxxbridge${executable_postfix}\")\n    endif()\n\n\n    # The generated folder structure will be of the following form\n    #\n    #    CMAKE_CURRENT_BINARY_DIR\n    #        corrosion_generated\n    #            cxxbridge\n    #                <cxx_target>\n    #                    include\n    #                        <cxx_target>\n    #                            <headers>\n    #                        rust\n    #                            cxx.h\n    #                    src\n    #                        <sourcefiles>\n    #            cbindgen\n    #                ...\n    #            other\n    #                ...\n\n    set(corrosion_generated_dir \"${CMAKE_CURRENT_BINARY_DIR}/corrosion_generated\")\n    set(generated_dir \"${corrosion_generated_dir}/cxxbridge/${cxx_target}\")\n    set(header_placement_dir \"${generated_dir}/include/${cxx_target}\")\n    set(source_placement_dir \"${generated_dir}/src\")\n\n    add_library(${cxx_target} STATIC)\n    target_include_directories(${cxx_target}\n        PUBLIC\n            $<BUILD_INTERFACE:${generated_dir}/include>\n            $<INSTALL_INTERFACE:include>\n    )\n\n    # cxx generated code is using c++11 features in headers, so propagate c++11 as minimal requirement\n    target_compile_features(${cxx_target} PUBLIC cxx_std_11)\n\n    if (TARGET \"${_arg_CRATE}-static\")\n        target_link_libraries(${cxx_target} PRIVATE \"${_arg_CRATE}-static\")\n        target_link_libraries(\"${_arg_CRATE}-static\" INTERFACE ${cxx_target})\n    endif()\n    if (TARGET \"${_arg_CRATE}-shared\")\n        target_link_libraries(${cxx_target} PRIVATE \"${_arg_CRATE}-shared\")\n        target_link_libraries(\"${_arg_CRATE}-shared\" INTERFACE ${cxx_target})\n    endif()\n\n    file(MAKE_DIRECTORY \"${generated_dir}/include/rust\")\n    add_custom_command(\n            OUTPUT \"${generated_dir}/include/rust/cxx.h\"\n            COMMAND\n            ${cxxbridge} --header --output \"${generated_dir}/include/rust/cxx.h\"\n            DEPENDS \"cxxbridge_v${cxx_required_version}\"\n            COMMENT \"Generating rust/cxx.h header\"\n    )\n\n    set(GENERATED_SOURCES \"\")\n    set(GENERATED_HEADERS \"${generated_dir}/include/rust/cxx.h\")\n\n    foreach(filepath ${_arg_FILES})\n        get_filename_component(filename ${filepath} NAME_WE)\n        get_filename_component(directory ${filepath} DIRECTORY)\n        set(directory_component \"\")\n        if(directory)\n            set(directory_component \"${directory}/\")\n        endif()\n        # todo: convert potentially absolute paths to relative paths..\n        set(cxx_header ${directory_component}${filename}.h)\n        set(cxx_source ${directory_component}${filename}.cpp)\n\n        # todo: not all projects may use the `src` directory.\n        set(rust_source_path \"${manifest_dir}/src/${filepath}\")\n\n        file(MAKE_DIRECTORY \"${header_placement_dir}/${directory}\" \"${source_placement_dir}/${directory}\")\n\n        add_custom_command(\n            OUTPUT\n            \"${header_placement_dir}/${cxx_header}\"\n            \"${source_placement_dir}/${cxx_source}\"\n            COMMAND\n                ${cxxbridge} ${rust_source_path} --header --output \"${header_placement_dir}/${cxx_header}\"\n            COMMAND\n                ${cxxbridge} ${rust_source_path}\n                    --output \"${source_placement_dir}/${cxx_source}\"\n                    --include \"${cxx_target}/${cxx_header}\"\n            DEPENDS \"cxxbridge_v${cxx_required_version}\" \"${rust_source_path}\"\n            COMMENT \"Generating cxx bindings for crate ${_arg_CRATE} and file src/${filepath}\"\n        )\n\n        list(APPEND GENERATED_SOURCES \"${source_placement_dir}/${cxx_source}\")\n        list(APPEND GENERATED_HEADERS \"${header_placement_dir}/${cxx_header}\")\n    endforeach()\n    target_sources(${cxx_target} PRIVATE ${GENERATED_SOURCES})\n    # Make sure to export the headers with PUBLIC.\n    # This ensures that any target that depends on cxx_target also has these files as a dependency\n    # CMake will then make sure to generate the files before building either target, which is important\n    # in the presence of circular dependencies\n    target_sources(${cxx_target} PUBLIC ${GENERATED_HEADERS})\n\n    if(DEFINED _arg_REGEN_TARGET)\n        # Add only the headers to the regen target, as the sources are actually not needed\n        # For the IDE to pick everything up\n        add_custom_target(${_arg_REGEN_TARGET}\n            DEPENDS ${GENERATED_HEADERS}\n            COMMENT \"Generated cxx bindings for crate ${_arg_CRATE}\")\n    endif()\n\nendfunction()\n\n#[=======================================================================[.md:\nANCHOR: corrosion_cbindgen\n\nA helper function which uses [cbindgen] to generate C/C++ bindings for a Rust crate.\nIf `cbindgen` is not in `PATH` the helper function will automatically try to download\n`cbindgen` and place the built binary into `CMAKE_BINARY_DIR`. The binary is shared\nbetween multiple invocations of this function.\n\nThe function comes with two different signatures. It's recommended to use the `TARGET` based signature when possible.\n\n### Auto mode (With a Rust target imported by corrosion)\n```cmake\ncorrosion_experimental_cbindgen(\n        TARGET <imported_target_name>\n        HEADER_NAME <output_header_name>\n        [CBINDGEN_VERSION <version>]\n        [FLAGS <flag1> ... <flagN>]\n)\n```\n\n### Auto-mode specific Arguments\n\n\n* **TARGET**: The name of an imported Rust library target, for which bindings should be generated.\n              If the target is not imported by Corrosion, because the crate only produces an\n              `rlib`, you can instead use the second signature and manually pass `MANIFEST_DIRECTORY`,\n              `CARGO_PACKAGE` and `BINDINGS_TARGET`\n\n### Manual mode (Without a Rust target imported by corrosion)\n```cmake\ncorrosion_experimental_cbindgen(\n        MANIFEST_DIRECTORY <package_manifest_directory>\n        CARGO_PACKAGE <package_name>\n        BINDINGS_TARGET <cmake_library>\n        [TARGET_TRIPLE <rust_target_triple>]\n        HEADER_NAME <output_header_name>\n        [CBINDGEN_VERSION <version>]\n        [FLAGS <flag1> ... <flagN>]\n)\n```\n\n### Manual-mode specific Arguments\n\n* **MANIFEST_DIRECTORY**: Manual mode only.\n    Directory of the package defining the library crate bindings should be generated for.\n    If you want to avoid specifying `MANIFEST_DIRECTORY` you could add a `staticlib` target to your package\n    manifest as a workaround to make corrosion import the crate.\n\n* **CARGO_PACKAGE**: Manual mode only.\n    The name of the cargo package that bindings should be generated for.\n    Note: This corresponds to the `cbindgen` `--crate` option, which actually wants a package name.\n\n* **BINDINGS_TARGET**: Manual mode only.\n    Name of an `INTERFACE` CMake target that the generated bindings should be attached to.\n    In auto mode, the generated headers will be attached to the imported rust CMake crate,\n    and corrosion will take care of adding the necessary build dependencies.\n    In manual mode, this target likely doesn't exist, so the user needs to specify an INTERFACE CMake\n    target, which the header files should be attached to. The user must create this target themselves and\n    ensure to add any necessary dependencies (e.g. via `add_dependencies()`) to ensure that consumers of the\n    `INTERFACE` library are not linked before the Rust library has been built.\n\n* **TARGET_TRIPLE**: Manual mode only.\n    Rust target triple (e.g. `x86_64-unknown-linux-gnu`) that cbindgen should use when generating the bindings.\n    Defaults to target triple that corrosion was confiured to compile for.\n\n### Common Arguments\n\n* **HEADER_NAME**: The name of the generated header file. This will be the name which you include in your C/C++ code\n                    (e.g. `#include \"myproject/myheader.h\" if you specify `HEADER_NAME \"myproject/myheader.h\"`.\n* **CBINDGEN_VERSION**: Version requirement for cbindgen. Exact semantics to be specified. Currently not implemented.\n* **FLAGS**: Arbitrary other flags for `cbindgen`. Run `cbindgen --help` to see the possible flags.\n\n[cbindgen]: https://github.com/mozilla/cbindgen\n\n### Current limitations\n\n- Cbindgens (optional) macro expansion feature internally actually builds the crate / runs the build script.\n  For this to work as expected in all cases, we probably need to set all the same environment variables\n  as when corrosion builds the crate. However the crate is a **library**, so we would need to figure out which\n  target builds it - and if there are multiple, potentially generate bindings per-target?\n  Alternatively we could add support of setting some environment variables on rlibs, and pulling that\n  information in when building the actual corrosion targets\n  Alternatively we could restrict corrosions support of this feature to actual imported staticlib/cdylib targets.\nANCHOR_END: corrosion_cbindgen\n#]=======================================================================]\nfunction(corrosion_experimental_cbindgen)\n    set(OPTIONS \"\")\n    set(ONE_VALUE_KEYWORDS\n            TARGET\n            MANIFEST_DIRECTORY\n            CARGO_PACKAGE\n            BINDINGS_TARGET\n            TARGET_TRIPLE\n            HEADER_NAME\n            CBINDGEN_VERSION\n    )\n    set(MULTI_VALUE_KEYWORDS \"FLAGS\")\n    cmake_parse_arguments(PARSE_ARGV 0 CCN \"${OPTIONS}\" \"${ONE_VALUE_KEYWORDS}\" \"${MULTI_VALUE_KEYWORDS}\")\n\n    set(required_keywords HEADER_NAME)\n    foreach(keyword ${required_keywords})\n        if(NOT DEFINED \"CCN_${keyword}\")\n            message(FATAL_ERROR \"Missing required parameter `${keyword}`.\")\n        elseif(\"${CCN_${keyword}}\" STREQUAL \"\")\n            message(FATAL_ERROR \"Required parameter `${keyword}` may not be set to an empty string.\")\n        endif()\n    endforeach()\n    if(NOT (DEFINED CCN_TARGET\n            OR (DEFINED CCN_MANIFEST_DIRECTORY AND DEFINED CCN_BINDINGS_TARGET\n                AND DEFINED CCN_BINDINGS_TARGET)\n            )\n    )\n        message(FATAL_ERROR \"Unknown signature for corrosion_experimental_cbindgen.\\n\"\n                \"Either the `TARGET` or the `MANIFEST_DIRECTORY` based signature must be chosen.\\n\"\n                \"Please view the documentation for details on the function signature.\\n\"\n                \"Passed arguments where: `${ARGV}`\"\n        )\n    endif()\n\n    if(DEFINED CCN_UNPARSED_ARGUMENTS)\n        message(AUTHOR_WARNING \"corrosion_experimental_cbindgen was called with the following unknown arguments: \"\n                \"`${CCN_UNPARSED_ARGUMENTS}`\\n\"\n                \"Unknown arguments will be ignored.\"\n        )\n    endif()\n    unset(package_manifest_dir)\n\n\n    if(TARGET \"${CCN_TARGET}\")\n        set(cbindgen_bindings_target \"${CCN_TARGET}\")\n        set(hostbuild_override \"$<BOOL:$<TARGET_PROPERTY:${CCN_TARGET},${_CORR_PROP_HOST_BUILD}>>\")\n        set(cbindgen_target_triple \"$<IF:${hostbuild_override},${_CORROSION_RUST_CARGO_HOST_TARGET},${_CORROSION_RUST_CARGO_TARGET}>\")\n\n        get_target_property(package_manifest_path \"${CCN_TARGET}\" INTERFACE_COR_PACKAGE_MANIFEST_PATH)\n        if(NOT EXISTS \"${package_manifest_path}\")\n            message(FATAL_ERROR \"Internal error: No package manifest found at ${package_manifest_path}\")\n        endif()\n        get_filename_component(package_manifest_dir \"${package_manifest_path}\" DIRECTORY)\n        get_target_property(rust_cargo_package \"${CCN_TARGET}\" COR_CARGO_PACKAGE_NAME )\n        if(NOT rust_cargo_package)\n            message(FATAL_ERROR \"Internal Error: Could not determine cargo package name for cbindgen. \")\n        endif()\n        # todo: as an optimization we could cache the cargo metadata output (but --no-deps makes that slightly more complicated)\n    else()\n        if(NOT DEFINED CCN_MANIFEST_DIRECTORY)\n            message(FATAL_ERROR\n                \"Internal error: There should have been a fatal error already if neither TARGET or \"\n                    \"MANIFEST_DIRECTORY are specfied.\")\n        endif()\n        cmake_path(ABSOLUTE_PATH CCN_MANIFEST_DIRECTORY NORMALIZE OUTPUT_VARIABLE package_manifest_dir)\n        if(DEFINED CCN_TARGET_TRIPLE)\n            set(cbindgen_target_triple \"${CCN_TARGET_TRIPLE}\")\n        else()\n            set(cbindgen_target_triple \"${Rust_CARGO_TARGET}\")\n        endif()\n        set(rust_cargo_package \"${CCN_CARGO_PACKAGE}\")\n        set(cbindgen_bindings_target \"${CCN_BINDINGS_TARGET}\")\n        get_target_property(type \"${cbindgen_bindings_target}\" TYPE)\n        if(NOT ${type} STREQUAL \"INTERFACE_LIBRARY\")\n            message(AUTHOR_WARNING \"The CMake target for the cbindgen generated files is expected to be\"\n                \" an `INTERFACE` library, but was `${type}` instead.\"\n            )\n        endif()\n    endif()\n\n    message(STATUS \"Using package `${rust_cargo_package}` as crate for cbindgen\")\n\n    set(output_header_name \"${CCN_HEADER_NAME}\")\n\n    find_program(installed_cbindgen cbindgen)\n\n    # Install the newest cbindgen version into our build tree.\n    if(installed_cbindgen)\n        set(cbindgen \"${installed_cbindgen}\")\n    else()\n        set(local_cbindgen_install_dir \"${CMAKE_BINARY_DIR}/corrosion/cbindgen\")\n        unset(executable_postfix)\n        if(Rust_CARGO_HOST_OS STREQUAL \"windows\")\n            set(executable_postfix \".exe\")\n        endif()\n        set(cbindgen \"${local_cbindgen_install_dir}/bin/cbindgen${executable_postfix}\")\n\n        if(NOT TARGET \"_corrosion_cbindgen\")\n            file(MAKE_DIRECTORY \"${local_cbindgen_install_dir}\")\n\n            add_custom_command(OUTPUT \"${cbindgen}\"\n                COMMAND ${CMAKE_COMMAND}\n                -E env\n                \"CARGO_BUILD_RUSTC=$CACHE{CORROSION_TOOLS_RUSTC}\"\n                $CACHE{CORROSION_TOOLS_CARGO} install\n                    cbindgen\n                    --locked\n                    --root \"${local_cbindgen_install_dir}\"\n                    ${_CORROSION_QUIET_OUTPUT_FLAG}\n                COMMENT \"Building cbindgen with Rust toolchain $CACHE{CORROSION_TOOLS_RUST_TOOLCHAIN}\"\n                VERBATIM\n                )\n            add_custom_target(\"_corrosion_cbindgen\"\n                DEPENDS \"${cbindgen}\"\n                )\n        endif()\n    endif()\n\n    set(corrosion_generated_dir \"${CMAKE_CURRENT_BINARY_DIR}/corrosion_generated\")\n    set(generated_dir \"${corrosion_generated_dir}/cbindgen/${cbindgen_bindings_target}\")\n    set(header_placement_dir \"${generated_dir}/include\")\n    set(depfile_placement_dir \"${generated_dir}/depfile\")\n    set(generated_depfile \"${depfile_placement_dir}/${output_header_name}.d\")\n    set(generated_header \"${header_placement_dir}/${output_header_name}\")\n\n    if(CMAKE_VERSION VERSION_GREATER_EQUAL \"3.23\")\n        target_sources(${cbindgen_bindings_target}\n            INTERFACE\n            FILE_SET HEADERS\n            BASE_DIRS \"${header_placement_dir}\"\n            FILES \"${header_placement_dir}/${output_header_name}\"\n        )\n    else()\n        # Note: not clear to me how install would best work before CMake 3.23\n        target_include_directories(${cbindgen_bindings_target}\n            INTERFACE\n            $<BUILD_INTERFACE:${header_placement_dir}>\n            $<INSTALL_INTERFACE:include>\n            )\n    endif()\n\n    # This may be different from $header_placement_dir since the user specified HEADER_NAME may contain\n    # relative directories.\n    get_filename_component(generated_header_dir \"${generated_header}\" DIRECTORY)\n    file(MAKE_DIRECTORY \"${generated_header_dir}\")\n\n    unset(depfile_cbindgen_arg)\n    get_filename_component(generated_depfile_dir \"${generated_depfile}\" DIRECTORY)\n    file(MAKE_DIRECTORY \"${generated_depfile_dir}\")\n    set(depfile_cbindgen_arg \"--depfile=${generated_depfile}\")\n\n    add_custom_command(\n        OUTPUT\n        \"${generated_header}\"\n        COMMAND\n        \"${CMAKE_COMMAND}\" -E env\n            TARGET=\"${cbindgen_target_triple}\"\n            # cbindgen invokes cargo-metadata and checks the CARGO environment variable\n            CARGO=\"${_CORROSION_CARGO}\"\n            RUSTC=\"${_CORROSION_RUSTC}\"\n            \"${cbindgen}\"\n                    --output \"${generated_header}\"\n                    --crate \"${rust_cargo_package}\"\n                    ${depfile_cbindgen_arg}\n                    ${CCN_FLAGS}\n        COMMENT \"Generate cbindgen bindings for package ${rust_cargo_package} and output header ${generated_header}\"\n        DEPFILE \"${generated_depfile}\"\n        COMMAND_EXPAND_LISTS\n        WORKING_DIRECTORY \"${package_manifest_dir}\"\n    )\n\n    if(NOT installed_cbindgen)\n        add_custom_command(\n            OUTPUT \"${generated_header}\"\n            APPEND\n            DEPENDS _corrosion_cbindgen\n        )\n    endif()\n\n    if(NOT TARGET \"_corrosion_cbindgen_${cbindgen_bindings_target}_bindings\")\n        add_custom_target(_corrosion_cbindgen_${cbindgen_bindings_target}_bindings\n                COMMENT \"Generate cbindgen bindings for package ${rust_cargo_package}\"\n        )\n    endif()\n    # Users might want to call cbindgen multiple times, e.g. to generate separate C++ and C header files.\n    string(MAKE_C_IDENTIFIER \"${output_header_name}\" header_identifier )\n    add_custom_target(\"_corrosion_cbindgen_${cbindgen_bindings_target}_bindings_${header_identifier}\"\n            DEPENDS \"${generated_header}\"\n            COMMENT \"Generate ${generated_header} for ${cbindgen_bindings_target}\"\n    )\n    add_dependencies(\"_corrosion_cbindgen_${cbindgen_bindings_target}_bindings\" \"_corrosion_cbindgen_${cbindgen_bindings_target}_bindings_${header_identifier}\")\n    add_dependencies(${cbindgen_bindings_target} \"_corrosion_cbindgen_${cbindgen_bindings_target}_bindings\")\n    if(TARGET \"${CCN_TARGET}\")\n        add_dependencies(cargo-build_${CCN_TARGET} \"_corrosion_cbindgen_${cbindgen_bindings_target}_bindings\")\n    endif()\nendfunction()\n\n# Parse the version of a Rust package from it's package manifest (Cargo.toml)\nfunction(corrosion_parse_package_version package_manifest_path out_package_version)\n    if(NOT EXISTS \"${package_manifest_path}\")\n        message(FATAL_ERROR \"Package manifest `${package_manifest_path}` does not exist.\")\n    endif()\n\n    file(READ \"${package_manifest_path}\" package_manifest)\n\n    # Find the package table. It may contain arrays, so match until \\n\\[, which should mark the next\n    # table. Note: backslashes must be doubled to escape the backslash for the bracket. LF is single\n    # backslash however. On windows the line also ends in \\n, so matching against \\n\\[ is sufficient\n    # to detect an opening bracket on a new line.\n    set(package_table_regex \"\\\\[package\\\\](.*)\\n\\\\[\")\n\n    string(REGEX MATCH \"${package_table_regex}\" _package_table \"${package_manifest}\")\n\n    if(CMAKE_MATCH_COUNT EQUAL \"1\")\n        set(package_table \"${CMAKE_MATCH_1}\")\n    else()\n        message(DEBUG\n                \"Failed to find `[package]` table in package manifest `${package_manifest_path}`.\\n\"\n                \"Matches: ${CMAKE_MATCH_COUNT}\\n\"\n        )\n        set(${out_package_version}\n            \"NOTFOUND\"\n            PARENT_SCOPE\n        )\n    endif()\n    # Match `version = \"0.3.2\"`, `\"version\" = \"0.3.2\" Contains one matching group for the version\n    set(version_regex \"[\\r]?\\n[\\\"']?version[\\\"']?[ \\t]*=[ \\t]*[\\\"']([0-9\\.]+)[\\\"']\")\n\n    string(REGEX MATCH \"${version_regex}\" _version \"${package_table}\")\n\n    if(\"${package_table}\" MATCHES \"${version_regex}\")\n        set(${out_package_version}\n            \"${CMAKE_MATCH_1}\"\n            PARENT_SCOPE\n        )\n    else()\n        message(DEBUG \"Failed to extract package version from manifest `${package_manifest_path}`.\")\n        set(${out_package_version}\n            \"NOTFOUND\"\n            PARENT_SCOPE\n        )\n    endif()\nendfunction()\n\nfunction(_corrosion_initialize_properties target_name)\n    # Initialize the `<XYZ>_OUTPUT_DIRECTORY` properties based on `CMAKE_<XYZ>_OUTPUT_DIRECTORY`.\n    foreach(output_var RUNTIME_OUTPUT_DIRECTORY ARCHIVE_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY PDB_OUTPUT_DIRECTORY)\n        if (DEFINED \"CMAKE_${output_var}\")\n            set_property(TARGET ${target_name} PROPERTY \"${output_var}\" \"${CMAKE_${output_var}}\")\n        endif()\n\n        foreach(config_type ${CMAKE_CONFIGURATION_TYPES})\n            string(TOUPPER \"${config_type}\" config_type_upper)\n            if (DEFINED \"CMAKE_${output_var}_${config_type_upper}\")\n                set_property(TARGET ${target_name} PROPERTY \"${output_var}_${config_type_upper}\" \"${CMAKE_${output_var}_${config_type_upper}}\")\n            endif()\n        endforeach()\n    endforeach()\nendfunction()\n\n# Helper macro to pass through an optional `OPTION` argument parsed via `cmake_parse_arguments`\n# to another function that takes the same OPTION.\n# If the option was set, then the variable <var_name> will be set to the same option name again,\n# otherwise <var_name> will be unset.\nmacro(_corrosion_option_passthrough_helper option_name prefix var_name)\n    if(${${prefix}_${option_name}})\n        set(\"${var_name}\" \"${option_name}\")\n    else()\n        unset(\"${var_name}\")\n    endif()\nendmacro()\n\n# Helper macro to pass through an optional argument with value(s), parsed via `cmake_parse_arguments`,\n# to another function that takes the same keyword + associated values.\n# If the argument was given, then the variable <var_name> will be a list of the argument name and the values,\n# which will be expanded, when calling the function (assuming no quotes).\nmacro(_corrosion_arg_passthrough_helper arg_name prefix var_name)\n    if(DEFINED \"${prefix}_${arg_name}\")\n        set(\"${var_name}\" \"${arg_name}\" \"${${prefix}_${arg_name}}\")\n    else()\n        unset(\"${var_name}\")\n    endif()\nendmacro()\n\nlist(POP_BACK CMAKE_MESSAGE_CONTEXT)\n"
  },
  {
    "path": "cmake/CorrosionConfig.cmake.in",
    "content": "@PACKAGE_INIT@\n\nif (Corrosion_FOUND)\n    return()\nendif()\n\nlist(APPEND CMAKE_MODULE_PATH \"${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_DATADIR@/cmake\")\n\ninclude(Corrosion)\n"
  },
  {
    "path": "cmake/CorrosionGenerator.cmake",
    "content": "function(_cargo_metadata out manifest)\n    set(OPTIONS LOCKED FROZEN)\n    set(ONE_VALUE_KEYWORDS \"\")\n    set(MULTI_VALUE_KEYWORDS \"\")\n    cmake_parse_arguments(PARSE_ARGV 2 CM \"${OPTIONS}\" \"${ONE_VALUE_KEYWORDS}\" \"${MULTI_VALUE_KEYWORDS}\")\n\n    list(APPEND CMAKE_MESSAGE_CONTEXT \"_cargo_metadata\")\n\n    if(DEFINED CM_UNPARSED_ARGUMENTS)\n        message(FATAL_ERROR \"Internal error - unexpected arguments: ${CM_UNPARSED_ARGUMENTS}\")\n    elseif(DEFINED CM_KEYWORDS_MISSING_VALUES)\n        message(FATAL_ERROR \"Internal error - the following keywords had no associated value(s):\"\n            \"${CM_KEYWORDS_MISSING_VALUES}\")\n    endif()\n\n    set(cargo_locked \"\")\n    set(cargo_frozen \"\")\n    if(LOCKED)\n        set(cargo_locked \"--locked\")\n    endif()\n    if(FROZEN)\n        set(cargo_frozen \"--frozen\")\n    endif()\n    \n    get_filename_component(workspace_toml_dir \"${manifest}\" DIRECTORY)\n    \n    execute_process(\n        COMMAND\n            ${CMAKE_COMMAND} -E env\n                \"CARGO_BUILD_RUSTC=${_CORROSION_RUSTC}\"\n                \"${_CORROSION_CARGO}\"\n                    metadata\n                        --manifest-path \"${manifest}\"\n                        --format-version 1\n                        # We don't care about non-workspace dependencies\n                        --no-deps\n                        ${cargo_locked}\n                        ${cargo_frozen}\n        # Set WORKING_DIRECTORY to the directory containing the manifest, so that configuration files\n        # such as `.cargo/config.toml` or `toolchain.toml` are applied as expected. Cargo searches for\n        # configuration files by walking upward from the current directory.\n        WORKING_DIRECTORY \"${workspace_toml_dir}\"\n        OUTPUT_VARIABLE json\n        COMMAND_ERROR_IS_FATAL ANY\n    )\n\n    set(${out} \"${json}\" PARENT_SCOPE)\nendfunction()\n\n# Add targets (crates) of one package\nfunction(_generator_add_package_targets)\n    set(OPTIONS NO_LINKER_OVERRIDE)\n    set(ONE_VALUE_KEYWORDS\n        WORKSPACE_MANIFEST_PATH\n        PACKAGE_MANIFEST_PATH\n        PACKAGE_NAME\n        PACKAGE_VERSION\n        TARGETS_JSON\n        OUT_CREATED_TARGETS)\n    set(MULTI_VALUE_KEYWORDS CRATE_TYPES OVERRIDE_CRATE_TYPE_ARGS)\n    cmake_parse_arguments(PARSE_ARGV 0 GAPT \"${OPTIONS}\" \"${ONE_VALUE_KEYWORDS}\" \"${MULTI_VALUE_KEYWORDS}\")\n\n    if(DEFINED GAPT_UNPARSED_ARGUMENTS)\n        message(FATAL_ERROR \"Internal error - unexpected arguments: ${GAPT_UNPARSED_ARGUMENTS}\")\n    elseif(DEFINED GAPT_KEYWORDS_MISSING_VALUES)\n        message(FATAL_ERROR \"Internal error - the following keywords had no associated value(s):\"\n                    \"${GAPT_KEYWORDS_MISSING_VALUES}\")\n    endif()\n\n    _corrosion_option_passthrough_helper(NO_LINKER_OVERRIDE GAPT no_linker_override)\n\n    set(workspace_manifest_path \"${GAPT_WORKSPACE_MANIFEST_PATH}\")\n    set(package_manifest_path \"${GAPT_PACKAGE_MANIFEST_PATH}\")\n    set(package_name \"${GAPT_PACKAGE_NAME}\")\n    set(package_version \"${GAPT_PACKAGE_VERSION}\")\n    set(targets \"${GAPT_TARGETS_JSON}\")\n    set(out_created_targets \"${GAPT_OUT_CREATED_TARGETS}\")\n    set(crate_types \"${GAPT_CRATE_TYPES}\")\n    if(DEFINED GAPT_OVERRIDE_CRATE_TYPE_ARGS)\n        list(GET GAPT_OVERRIDE_CRATE_TYPE_ARGS 0 override_crate_name_list_ref)\n        list(GET GAPT_OVERRIDE_CRATE_TYPE_ARGS 1 override_crate_types_list_ref)\n    endif()\n\n    set(corrosion_targets \"\")\n\n    file(TO_CMAKE_PATH \"${package_manifest_path}\" manifest_path)\n\n    string(JSON targets_len LENGTH \"${targets}\")\n    math(EXPR targets_len-1 \"${targets_len} - 1\")\n\n    message(DEBUG \"Found ${targets_len} targets in package ${package_name}\")\n\n    foreach(ix RANGE ${targets_len-1})\n        string(JSON target GET \"${targets}\" ${ix})\n        string(JSON target_name GET \"${target}\" \"name\")\n        string(JSON target_kind GET \"${target}\" \"kind\")\n        string(JSON target_kind_len LENGTH \"${target_kind}\")\n\n        math(EXPR target_kind_len-1 \"${target_kind_len} - 1\")\n        set(kinds)\n        unset(override_package_crate_type)\n        # OVERRIDE_CRATE_TYPE is more specific than the CRATE_TYPES argument to corrosion_import_crate, and thus takes\n        # priority.\n        if(DEFINED GAPT_OVERRIDE_CRATE_TYPE_ARGS)\n            foreach(override_crate_name override_crate_types IN ZIP_LISTS ${override_crate_name_list_ref} ${override_crate_types_list_ref})\n                if(\"${override_crate_name}\" STREQUAL \"${target_name}\")\n                    message(DEBUG \"Forcing crate ${target_name} to crate-type(s): ${override_crate_types}.\")\n                    # Convert to CMake list\n                    string(REPLACE \",\" \";\" kinds \"${override_crate_types}\")\n                    break()\n                endif()\n            endforeach()\n        else()\n            foreach(ix RANGE ${target_kind_len-1})\n                string(JSON kind GET \"${target_kind}\" ${ix})\n                if(NOT crate_types OR ${kind} IN_LIST crate_types)\n                    list(APPEND kinds ${kind})\n                endif()\n            endforeach()\n        endif()\n        if(TARGET \"${target_name}\"\n            AND (\"staticlib\" IN_LIST kinds OR \"cdylib\" IN_LIST kinds OR \"bin\" IN_LIST kinds)\n            )\n            message(WARNING \"Failed to import Rust crate ${target_name} (kind: `${target_kind}`) because a target \"\n                \"with the same name already exists. Skipping this target.\\n\"\n                \"Help: If you are importing a package which exposes both a `lib` and \"\n                \"a `bin` target, please consider explicitly naming the targets in your `Cargo.toml` manifest.\\n\"\n                \"Note: If you have multiple different packages which have targets with the same name, please note that \"\n                \"this is currently not supported by Corrosion. Feel free to open an issue on Github to request \"\n                \"supporting this scenario.\"\n                )\n            # Skip this target to prevent a hard error.\n            continue()\n        endif()\n\n        if(\"staticlib\" IN_LIST kinds OR \"cdylib\" IN_LIST kinds)\n            # Explicitly set library names have always been forbidden from using dashes (by cargo).\n            # Starting with Rust 1.79, names inherited from the package name will have dashes replaced\n            # by underscores too. Corrosion will thus replace dashes with underscores, to make the target\n            # name consistent independent of the Rust version. `bin` target names are not affected.\n            # See https://github.com/corrosion-rs/corrosion/issues/501 for more details.\n            string(REPLACE \"\\-\" \"_\" target_name \"${target_name}\")\n\n            set(archive_byproducts \"\")\n            set(shared_lib_byproduct \"\")\n            set(pdb_byproduct \"\")\n\n            add_library(${target_name} INTERFACE)\n            _corrosion_initialize_properties(${target_name})\n            _corrosion_add_library_target(\n                WORKSPACE_MANIFEST_PATH \"${workspace_manifest_path}\"\n                TARGET_NAME \"${target_name}\"\n                LIB_KINDS ${kinds}\n                OUT_ARCHIVE_OUTPUT_BYPRODUCTS archive_byproducts\n                OUT_SHARED_LIB_BYPRODUCTS shared_lib_byproduct\n                OUT_PDB_BYPRODUCT pdb_byproduct\n            )\n\n            set(byproducts \"\")\n            list(APPEND byproducts \"${archive_byproducts}\" \"${shared_lib_byproduct}\" \"${pdb_byproduct}\")\n\n            set(cargo_build_out_dir \"\")\n            _add_cargo_build(\n                cargo_build_out_dir\n                PACKAGE ${package_name}\n                TARGET ${target_name}\n                MANIFEST_PATH \"${manifest_path}\"\n                WORKSPACE_MANIFEST_PATH \"${workspace_manifest_path}\"\n                TARGET_KINDS \"${kinds}\"\n                BYPRODUCTS \"${byproducts}\"\n                # Optional\n                ${no_linker_override}\n            )\n            if(archive_byproducts)\n                _corrosion_copy_byproducts(\n                    ${target_name} ARCHIVE_OUTPUT_DIRECTORY \"${cargo_build_out_dir}\" \"${archive_byproducts}\"\n                )\n            endif()\n            if(shared_lib_byproduct)\n                _corrosion_copy_byproducts(\n                    ${target_name} LIBRARY_OUTPUT_DIRECTORY \"${cargo_build_out_dir}\" \"${shared_lib_byproduct}\"\n                )\n            endif()\n            if(pdb_byproduct)\n                _corrosion_copy_byproducts(\n                    ${target_name} \"PDB_OUTPUT_DIRECTORY;LIBRARY_OUTPUT_DIRECTORY\" \"${cargo_build_out_dir}\" \"${pdb_byproduct}\"\n                )\n            endif()\n            list(APPEND corrosion_targets ${target_name})\n            set_property(TARGET \"${target_name}\" PROPERTY COR_CARGO_PACKAGE_NAME \"${package_name}\" )\n        # Note: \"bin\" is mutually exclusive with \"staticlib/cdylib\", since `bin`s are seperate crates from libraries.\n        elseif(\"bin\" IN_LIST kinds)\n            set(bin_byproduct \"\")\n            set(pdb_byproduct \"\")\n            add_executable(${target_name} IMPORTED GLOBAL)\n            _corrosion_initialize_properties(${target_name})\n            _corrosion_add_bin_target(\"${workspace_manifest_path}\" \"${target_name}\"\n                \"bin_byproduct\" \"pdb_byproduct\"\n            )\n\n            set(byproducts \"\")\n            list(APPEND byproducts \"${bin_byproduct}\" \"${pdb_byproduct}\")\n\n            set(cargo_build_out_dir \"\")\n            _add_cargo_build(\n                cargo_build_out_dir\n                PACKAGE \"${package_name}\"\n                TARGET \"${target_name}\"\n                MANIFEST_PATH \"${manifest_path}\"\n                WORKSPACE_MANIFEST_PATH \"${workspace_manifest_path}\"\n                TARGET_KINDS \"bin\"\n                BYPRODUCTS \"${byproducts}\"\n                # Optional\n                ${no_linker_override}\n            )\n            _corrosion_copy_byproducts(\n                    ${target_name} RUNTIME_OUTPUT_DIRECTORY \"${cargo_build_out_dir}\" \"${bin_byproduct}\"\n            )\n            if(pdb_byproduct)\n                _corrosion_copy_byproducts(\n                        ${target_name} \"PDB_OUTPUT_DIRECTORY;RUNTIME_OUTPUT_DIRECTORY\" \"${cargo_build_out_dir}\" \"${pdb_byproduct}\"\n                )\n            endif()\n            list(APPEND corrosion_targets ${target_name})\n            set_property(TARGET \"${target_name}\" PROPERTY COR_CARGO_PACKAGE_NAME \"${package_name}\" )\n        else()\n            # ignore other kinds (like examples, tests, build scripts, ...)\n        endif()\n    endforeach()\n\n    if(NOT corrosion_targets)\n        message(DEBUG \"No relevant targets found in package ${package_name} - Ignoring\")\n    else()\n        set_target_properties(${corrosion_targets} PROPERTIES INTERFACE_COR_PACKAGE_MANIFEST_PATH \"${package_manifest_path}\")\n    endif()\n    set(${out_created_targets} \"${corrosion_targets}\" PARENT_SCOPE)\n\nendfunction()\n\n# Add all cargo targets defined in the packages defined in the Cargo.toml manifest at\n# `MANIFEST_PATH`.\nfunction(_generator_add_cargo_targets)\n    set(options NO_LINKER_OVERRIDE)\n    set(one_value_args MANIFEST_PATH IMPORTED_CRATES)\n    set(multi_value_args CRATES CRATE_TYPES OVERRIDE_CRATE_TYPE_ARGS)\n    cmake_parse_arguments(\n        GGC\n        \"${options}\"\n        \"${one_value_args}\"\n        \"${multi_value_args}\"\n        ${ARGN}\n    )\n    list(APPEND CMAKE_MESSAGE_CONTEXT \"_add_cargo_targets\")\n\n    _corrosion_option_passthrough_helper(NO_LINKER_OVERRIDE GGC no_linker_override)\n    _corrosion_arg_passthrough_helper(CRATE_TYPES GGC crate_types)\n    _corrosion_arg_passthrough_helper(OVERRIDE_CRATE_TYPE_ARGS GGC override_crate_types)\n\n    _cargo_metadata(json \"${GGC_MANIFEST_PATH}\")\n    string(JSON packages GET \"${json}\" \"packages\")\n    string(JSON workspace_members GET \"${json}\" \"workspace_members\")\n\n    string(JSON pkgs_len LENGTH \"${packages}\")\n    math(EXPR pkgs_len-1 \"${pkgs_len} - 1\")\n\n    string(JSON ws_mems_len LENGTH ${workspace_members})\n    math(EXPR ws_mems_len-1 \"${ws_mems_len} - 1\")\n\n    set(created_targets \"\")\n    set(available_package_names \"\")\n    foreach(ix RANGE ${pkgs_len-1})\n        string(JSON pkg GET \"${packages}\" ${ix})\n        string(JSON pkg_id GET \"${pkg}\" \"id\")\n        string(JSON pkg_name GET \"${pkg}\" \"name\")\n        string(JSON pkg_manifest_path GET \"${pkg}\" \"manifest_path\")\n        string(JSON pkg_version GET \"${pkg}\" \"version\")\n        list(APPEND available_package_names \"${pkg_name}\")\n\n        if(DEFINED GGC_CRATES)\n            if(NOT pkg_name IN_LIST GGC_CRATES)\n                continue()\n            endif()\n        endif()\n\n        # probably this loop is not necessary at all, since when using --no-deps, the\n        # contents of packages should already be only workspace members!\n        unset(pkg_is_ws_member)\n        foreach(ix RANGE ${ws_mems_len-1})\n            string(JSON ws_mem GET \"${workspace_members}\" ${ix})\n            if(ws_mem STREQUAL pkg_id)\n                set(pkg_is_ws_member YES)\n                break()\n            endif()\n        endforeach()\n\n        if(NOT DEFINED pkg_is_ws_member)\n            # Since we pass `--no-deps` to cargo metadata now,  I think this situation can't happen, but lets check for\n            # it anyway, just to discover any potential issues.\n            # If nobody complains for a while, it should be safe to remove this check and the previous loop, which\n            # should speed up the configuration process.\n            message(WARNING \"The package `${pkg_name}` unexpectedly is not part of the workspace.\"\n                \"Please open an issue at corrosion with some background information on the package\"\n            )\n        endif()\n\n        string(JSON targets GET \"${pkg}\" \"targets\")\n\n        _generator_add_package_targets(\n            WORKSPACE_MANIFEST_PATH \"${GGC_MANIFEST_PATH}\"\n            PACKAGE_MANIFEST_PATH \"${pkg_manifest_path}\"\n            PACKAGE_NAME \"${pkg_name}\"\n            PACKAGE_VERSION \"${pkg_version}\"\n            TARGETS_JSON \"${targets}\"\n            OUT_CREATED_TARGETS curr_created_targets\n            ${no_linker_override}\n            ${crate_types}\n            ${override_crate_types}\n        )\n        list(APPEND created_targets \"${curr_created_targets}\")\n    endforeach()\n\n    if(NOT created_targets)\n        set(crates_error_message \"\")\n        if(DEFINED GGC_CRATES)\n            set(crates_error_message \"\\n`corrosion_import_crate()` was called with the `CRATES` \"\n                \"parameter set to `${GGC_CRATES}`. Corrosion will only attempt to import packages matching \"\n                    \"names from this list.\"\n            )\n        endif()\n        message(FATAL_ERROR\n                \"Found no targets in ${pkgs_len} packages.\"\n                ${crates_error_message}.\n                \"\\nPlease keep in mind that corrosion will only import Rust `bin` targets or\"\n                \"`staticlib` or `cdylib` library targets.\"\n                \"The following packages were found in the Manifest: ${available_package_names}\"\n        )\n    else()\n        message(DEBUG \"Corrosion created the following CMake targets: ${created_targets}\")\n    endif()\n\n    if(GGC_IMPORTED_CRATES)\n        set(${GGC_IMPORTED_CRATES} \"${created_targets}\" PARENT_SCOPE)\n    endif()\nendfunction()\n"
  },
  {
    "path": "cmake/FindRust.cmake",
    "content": "#[=======================================================================[.rst:\nFindRust\n--------\n\nFind Rust\n\nThis module finds an installed rustc compiler and the cargo build tool. If Rust\nis managed by rustup it determines the available toolchains and returns a\nconcrete Rust version, not a rustup proxy.\n\n#]=======================================================================]\n\ncmake_minimum_required(VERSION 3.12)\n\noption(\n        Rust_RUSTUP_INSTALL_MISSING_TARGET\n        \"Use Rustup to automatically install missing targets instead of giving up\"\n        OFF\n)\n\n# search for Cargo here and set up a bunch of cool flags and stuff\ninclude(FindPackageHandleStandardArgs)\n\nlist(APPEND CMAKE_MESSAGE_CONTEXT \"FindRust\")\n\n# Print error message and return. Should not be used from inside functions\nmacro(_findrust_failed)\n    if(\"${Rust_FIND_REQUIRED}\")\n        message(FATAL_ERROR ${ARGN})\n    elseif(NOT \"${Rust_FIND_QUIETLY}\")\n        message(WARNING ${ARGN})\n    endif()\n    set(Rust_FOUND \"\")\n    return()\nendmacro()\n\n# Checks if the actual version of a Rust toolchain matches the VERSION requirements specified in find_package.\nfunction(_findrust_version_ok ACTUAL_VERSION OUT_IS_OK)\n    if(DEFINED Rust_FIND_VERSION_RANGE)\n        if(Rust_FIND_VERSION_RANGE_MAX STREQUAL \"INCLUDE\")\n            set(COMPARSION_OPERATOR \"VERSION_LESS_EQUAL\")\n        elseif(Rust_FIND_VERSION_RANGE_MAX STREQUAL \"EXCLUDE\")\n            set(COMPARSION_OPERATOR \"VERSION_LESS\")\n        else()\n            message(FATAL_ERROR \"Unexpected value in `<PackageName>_FIND_VERSION_RANGE_MAX`: \"\n                    \"`${Rust_FIND_VERSION_RANGE_MAX}`.\")\n        endif()\n        if((\"${ACTUAL_VERSION}\" VERSION_GREATER_EQUAL \"${Rust_FIND_VERSION_RANGE_MIN}\")\n                AND\n            ( \"${ACTUAL_VERSION}\" ${COMPARSION_OPERATOR} \"${Rust_FIND_VERSION_RANGE_MAX}\" )\n        )\n            set(\"${OUT_IS_OK}\" TRUE PARENT_SCOPE)\n        else()\n            set(\"${OUT_IS_OK}\" FALSE PARENT_SCOPE)\n        endif()\n    elseif(DEFINED Rust_FIND_VERSION)\n        if(Rust_VERSION_EXACT)\n            set(COMPARISON_OPERATOR VERSION_EQUAL)\n        else()\n            set(COMPARISON_OPERATOR VERSION_GREATER_EQUAL)\n        endif()\n        if(_TOOLCHAIN_${_TOOLCHAIN_SELECTED}_VERSION \"${COMPARISON_OPERATOR}\" Rust_FIND_VERSION)\n            set(\"${OUT_IS_OK}\" TRUE PARENT_SCOPE)\n        else()\n            set(\"${OUT_IS_OK}\" FALSE PARENT_SCOPE)\n        endif()\n    else()\n        # if no VERSION requirement was specified, the version is always okay.\n        set(\"${OUT_IS_OK}\" TRUE PARENT_SCOPE)\n    endif()\nendfunction()\n\nfunction(_corrosion_strip_target_triple input_triple_or_path output_triple)\n    # If the target_triple is a path to a custom target specification file, then strip everything\n    # except the filename from `target_triple`.\n    get_filename_component(target_triple_ext \"${input_triple_or_path}\" EXT)\n    set(target_triple \"${input_triple_or_path}\")\n    if(target_triple_ext)\n        if(target_triple_ext STREQUAL \".json\")\n            get_filename_component(target_triple \"${input_triple_or_path}\"  NAME_WE)\n        endif()\n    endif()\n    set(${output_triple} \"${target_triple}\" PARENT_SCOPE)\nendfunction()\n\nfunction(_corrosion_parse_target_triple target_triple out_arch out_vendor out_os out_env)\n    _corrosion_strip_target_triple(${target_triple} target_triple)\n\n    # The vendor part may be left out from the target triple, and since `env` is also optional,\n    # we determine if vendor is present by matching against a list of known vendors.\n    set(known_vendors\n        \"apple\"\n        \"esp[a-z0-9]*\" # espressif, e.g. riscv32imc-esp-espidf or xtensa-esp32s3-none-elf\n        \"fortanix\"\n        \"kmc\"\n        \"pc\"\n        \"nintendo\"\n        \"nvidia\"\n        \"openwrt\"\n        \"alpine\"\n        \"chimera\"\n        \"unikraft\"\n        \"unknown\"\n        \"uwp\" # aarch64-uwp-windows-msvc\n        \"wrs\" # e.g. aarch64-wrs-vxworks\n        \"sony\"\n        \"sun\"\n        )\n    # todo: allow users to add additional vendors to the list via a cmake variable.\n    list(JOIN known_vendors \"|\" known_vendors_joined)\n    # vendor is optional - We detect if vendor is present by matching against a known list of\n    # vendors. The next field is the OS, which we assume to always be present, while the last field\n    # is again optional and contains the environment.\n    string(REGEX MATCH\n        \"^([a-z0-9_\\.]+)-((${known_vendors_joined})-)?([a-z0-9_]+)(-([a-z0-9_]+))?$\"\n        whole_match\n        \"${target_triple}\"\n        )\n    if((NOT whole_match) AND (NOT CORROSION_NO_WARN_PARSE_TARGET_TRIPLE_FAILED))\n        message(WARNING \"Failed to parse target-triple `${target_triple}`.\"\n            \"Corrosion determines some information about the output artifacts based on OS \"\n            \"specified in the Rust target-triple.\\n\"\n            \"Currently this is relevant for windows and darwin (mac) targets, since file \"\n            \"extensions differ.\\n\"\n            \"Note: If you are targeting a different OS you can suppress this warning by\"\n            \" setting the CMake cache variable \"\n            \"`CORROSION_NO_WARN_PARSE_TARGET_TRIPLE_FAILED`.\"\n            \"Please consider opening an issue on github if you you need to add a new vendor to the list.\"\n            )\n    endif()\n\n    message(DEBUG \"Parsed Target triple: arch: ${CMAKE_MATCH_1}, vendor: ${CMAKE_MATCH_3}, \"\n        \"OS: ${CMAKE_MATCH_4}, env: ${CMAKE_MATCH_6}\")\n\n    set(\"${out_arch}\" \"${CMAKE_MATCH_1}\" PARENT_SCOPE)\n    set(\"${out_vendor}\" \"${CMAKE_MATCH_3}\" PARENT_SCOPE)\n    set(\"${out_os}\" \"${CMAKE_MATCH_4}\" PARENT_SCOPE)\n    set(\"${out_env}\" \"${CMAKE_MATCH_6}\" PARENT_SCOPE)\nendfunction()\n\nfunction(_corrosion_determine_libs_new target_triple out_libs out_flags)\n    set(package_dir \"${CMAKE_BINARY_DIR}/corrosion/required_libs\")\n    # Cleanup on reconfigure to get a cleans state (in case we change something in the future)\n    file(REMOVE_RECURSE \"${package_dir}\")\n    file(MAKE_DIRECTORY \"${package_dir}\")\n    set(manifest \"[package]\\nname = \\\"required_libs\\\"\\nedition = \\\"2018\\\"\\nversion = \\\"0.1.0\\\"\\n\")\n    string(APPEND manifest \"\\n[lib]\\ncrate-type=[\\\"staticlib\\\"]\\npath = \\\"lib.rs\\\"\\n\")\n    string(APPEND manifest \"\\n[workspace]\\n\")\n    file(WRITE \"${package_dir}/Cargo.toml\" \"${manifest}\")\n    file(WRITE \"${package_dir}/lib.rs\" \"pub fn add(left: usize, right: usize) -> usize {left + right}\\n\")\n\n    execute_process(\n        COMMAND ${CMAKE_COMMAND} -E env\n            \"CARGO_BUILD_RUSTC=${Rust_COMPILER_CACHED}\"\n        ${Rust_CARGO_CACHED} rustc --verbose --color never --target=${target_triple} -- --print=native-static-libs\n        WORKING_DIRECTORY \"${CMAKE_BINARY_DIR}/corrosion/required_libs\"\n        RESULT_VARIABLE cargo_build_result\n        ERROR_VARIABLE cargo_build_error_message\n    )\n    if(cargo_build_result)\n        message(DEBUG \"Determining required native libraries - failed: ${cargo_build_result}.\")\n        message(TRACE \"The cargo build error was: ${cargo_build_error_message}\")\n        message(DEBUG \"Note: This is expected for Rust targets without std support\")\n        return()\n    else()\n        # The pattern starts with `native-static-libs:` and goes to the end of the line.\n        if(cargo_build_error_message MATCHES \"native-static-libs: ([^\\r\\n]+)\\r?\\n\")\n            string(REPLACE \" \" \";\" \"libs_list\" \"${CMAKE_MATCH_1}\")\n            set(stripped_lib_list \"\")\n            set(flag_list \"\")\n\n            set(was_last_framework OFF)\n            foreach(lib ${libs_list})\n                # merge -framework;lib -> \"-framework lib\" as CMake does de-duplication of link libraries, and -framework prefix is required\n                if (lib STREQUAL \"-framework\")\n                    set(was_last_framework ON)\n                    continue()\n                endif()\n                if (was_last_framework)\n                    list(APPEND stripped_lib_list \"-framework ${lib}\")\n                    set(was_last_framework OFF)\n                    continue()\n                endif()\n                \n                # Flags start with / for MSVC\n                if (lib MATCHES \"^/\" AND ${target_triple} MATCHES \"msvc$\")\n                    # Windows GNU uses the compiler to invoke the linker, so -Wl, prefix is needed\n                    # https://gitlab.kitware.com/cmake/cmake/-/blob/9bed4f4d817f139f0c2e050d7420e1e247949fe4/Modules/Platform/Windows-GNU.cmake#L156\n                    if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL \"GNU\")\n                        list(APPEND flag_list \"-Wl,${lib}\")\n                    else()\n                        list(APPEND flag_list \"${lib}\")\n                    endif()\n                else()\n                    # Strip leading `-l` (unix) and potential .lib suffix (windows)\n                    string(REGEX REPLACE \"^-l\" \"\" \"stripped_lib\" \"${lib}\")\n                    string(REGEX REPLACE \"\\.lib$\" \"\" \"stripped_lib\" \"${stripped_lib}\")\n                    list(APPEND stripped_lib_list \"${stripped_lib}\")\n                endif()\n            endforeach()\n            set(libs_list \"${stripped_lib_list}\")\n            # We leave it up to the C/C++ executable that links in the Rust static-library\n            # to determine which version of the msvc runtime library it should select.\n            list(FILTER libs_list EXCLUDE REGEX \"^msvcrtd?\")\n            list(FILTER flag_list EXCLUDE REGEX \"^(-Wl,)?/defaultlib:msvcrtd?\")\n        else()\n            message(DEBUG \"Determining required native libraries - failed: Regex match failure.\")\n            message(DEBUG \"`native-static-libs` not found in: `${cargo_build_error_message}`\")\n            return()\n        endif()\n    endif()\n    set(\"${out_libs}\" \"${libs_list}\" PARENT_SCOPE)\n    set(\"${out_flags}\" \"${flag_list}\" PARENT_SCOPE)\nendfunction()\n\nif (NOT \"${Rust_TOOLCHAIN}\" STREQUAL \"$CACHE{Rust_TOOLCHAIN}\")\n    # Promote Rust_TOOLCHAIN to a cache variable if it is not already a cache variable\n    set(Rust_TOOLCHAIN ${Rust_TOOLCHAIN} CACHE STRING \"Requested rustup toolchain\" FORCE)\nendif()\n\nset(_RESOLVE_RUSTUP_TOOLCHAINS_DESC \"Indicates whether to descend into the toolchain pointed to by rustup\")\nset(Rust_RESOLVE_RUSTUP_TOOLCHAINS ON CACHE BOOL ${_RESOLVE_RUSTUP_TOOLCHAINS_DESC})\n\n# This block checks to see if we're prioritizing a rustup-managed toolchain.\nif (DEFINED Rust_TOOLCHAIN)\n    # If the user specifies `Rust_TOOLCHAIN`, then look for `rustup` first, rather than `rustc`.\n    find_program(Rust_RUSTUP rustup PATHS \"$ENV{HOME}/.cargo/bin\")\n    if(NOT Rust_RUSTUP)\n        if(NOT \"${Rust_FIND_QUIETLY}\")\n            message(\n                WARNING \"CMake variable `Rust_TOOLCHAIN` specified, but `rustup` was not found. \"\n                \"Ignoring toolchain and looking for a Rust toolchain not managed by rustup.\")\n        endif()\n    endif()\nelse()\n    # If we aren't definitely using a rustup toolchain, look for rustc first - the user may have\n    # a toolchain installed via a method other than rustup higher in the PATH, which should be\n    # preferred. However, if the first-found rustc is a rustup proxy, then we'll revert to\n    # finding the preferred toolchain via rustup.\n\n    # Uses `Rust_COMPILER` to let user-specified `rustc` win. But we will still \"override\" the\n    # user's setting if it is pointing to `rustup`. Default rustup install path is provided as a\n    # backup if a toolchain cannot be found in the user's PATH.\n\n    if (DEFINED Rust_COMPILER)\n        set(_Rust_COMPILER_TEST \"${Rust_COMPILER}\")\n        set(_USER_SPECIFIED_RUSTC ON)\n        if(NOT (EXISTS \"${_Rust_COMPILER_TEST}\" AND NOT IS_DIRECTORY \"${_Rust_COMPILER_TEST}\"))\n            set(_ERROR_MESSAGE \"Rust_COMPILER was set to `${Rust_COMPILER}`, but this file does \"\n                \"not exist.\"\n            )\n            _findrust_failed(${_ERROR_MESSAGE})\n            return()\n        endif()\n    else()\n        find_program(_Rust_COMPILER_TEST rustc PATHS \"$ENV{HOME}/.cargo/bin\")\n        if(NOT EXISTS \"${_Rust_COMPILER_TEST}\")\n            cmake_path(CONVERT \"$ENV{HOME}/.cargo/bin\" TO_CMAKE_PATH_LIST _cargo_bin_dir)\n            set(_ERROR_MESSAGE \"`rustc` not found in PATH or `${_cargo_bin_dir}`.\\n\"\n                    \"Hint: Check if `rustc` is in PATH or manually specify the location \"\n                    \"by setting `Rust_COMPILER` to the path to `rustc`.\")\n            _findrust_failed(${_ERROR_MESSAGE})\n        endif()\n    endif()\n\n    # Check if the discovered rustc is actually a \"rustup\" proxy.\n    execute_process(\n        COMMAND\n            ${CMAKE_COMMAND} -E env\n                RUSTUP_FORCE_ARG0=rustup\n            \"${_Rust_COMPILER_TEST}\" --version\n        OUTPUT_VARIABLE _RUSTC_VERSION_RAW\n        ERROR_VARIABLE _RUSTC_VERSION_STDERR\n        RESULT_VARIABLE _RUSTC_VERSION_RESULT\n    )\n\n    if(NOT (_RUSTC_VERSION_RESULT EQUAL \"0\"))\n        _findrust_failed(\"`${_Rust_COMPILER_TEST} --version` failed with ${_RUSTC_VERSION_RESULT}\\n\"\n            \"rustc stderr:\\n${_RUSTC_VERSION_STDERR}\"\n            )\n    endif()\n\n    if (_RUSTC_VERSION_RAW MATCHES \"rustup [0-9\\\\.]+\")\n        if (_USER_SPECIFIED_RUSTC)\n            message(\n                WARNING \"User-specified Rust_COMPILER pointed to rustup's rustc proxy. Corrosion's \"\n                \"FindRust will always try to evaluate to an actual Rust toolchain, and so the \"\n                \"user-specified Rust_COMPILER will be discarded in favor of the default \"\n                \"rustup-managed toolchain.\"\n            )\n\n            unset(Rust_COMPILER)\n            unset(Rust_COMPILER CACHE)\n        endif()\n\n        # Get `rustup` next to the `rustc` proxy\n        get_filename_component(_RUST_PROXIES_PATH \"${_Rust_COMPILER_TEST}\" DIRECTORY)\n        find_program(Rust_RUSTUP rustup HINTS \"${_RUST_PROXIES_PATH}\" NO_DEFAULT_PATH)\n    endif()\n\n    unset(_Rust_COMPILER_TEST CACHE)\nendif()\n\n# At this point, the only thing we should have evaluated is a path to `rustup` _if that's what the\n# best source for a Rust toolchain was determined to be_.\nif (NOT Rust_RUSTUP)\n    set(Rust_RESOLVE_RUSTUP_TOOLCHAINS OFF CACHE BOOL ${_RESOLVE_RUSTUP_TOOLCHAINS_DESC} FORCE)\nendif()\n\n# List of user variables that will override any toolchain-provided setting\nset(_Rust_USER_VARS Rust_COMPILER Rust_CARGO Rust_CARGO_TARGET Rust_CARGO_HOST_TARGET)\nforeach(_VAR ${_Rust_USER_VARS})\n    if (DEFINED \"${_VAR}\")\n        set(${_VAR}_CACHED \"${${_VAR}}\" CACHE INTERNAL \"Internal cache of ${_VAR}\")\n    else()\n        unset(${_VAR}_CACHED CACHE)\n    endif()\nendforeach()\n\n# Discover what toolchains are installed by rustup, if the discovered `rustc` is a proxy from\n# `rustup` and the user hasn't explicitly requested to override this behavior, then select either\n# the default toolchain, or the requested toolchain Rust_TOOLCHAIN\nif (Rust_RESOLVE_RUSTUP_TOOLCHAINS)\n    execute_process(\n        COMMAND\n            \"${Rust_RUSTUP}\" toolchain list --verbose\n        OUTPUT_VARIABLE _TOOLCHAINS_RAW\n    )\n\n    string(REPLACE \"\\n\" \";\" _TOOLCHAINS_RAW \"${_TOOLCHAINS_RAW}\")\n    set(_DISCOVERED_TOOLCHAINS \"\")\n    set(_DISCOVERED_TOOLCHAINS_RUSTC_PATH \"\")\n    set(_DISCOVERED_TOOLCHAINS_CARGO_PATH \"\")\n    set(_DISCOVERED_TOOLCHAINS_VERSION \"\")\n\n    foreach(_TOOLCHAIN_RAW ${_TOOLCHAINS_RAW})\n        if (_TOOLCHAIN_RAW MATCHES \"([a-zA-Z0-9\\\\._\\\\-]+)[ \\t\\r\\n]?(\\\\(active\\\\)|\\\\(active, default\\\\)|\\\\(default\\\\) \\\\(override\\\\)|\\\\(default\\\\)|\\\\(override\\\\))?[ \\t\\r\\n]+(.+)\")\n            set(_TOOLCHAIN \"${CMAKE_MATCH_1}\")\n            set(_TOOLCHAIN_TYPE \"${CMAKE_MATCH_2}\")\n\n            set(_TOOLCHAIN_PATH \"${CMAKE_MATCH_3}\")\n            set(_TOOLCHAIN_${_TOOLCHAIN}_PATH \"${CMAKE_MATCH_3}\")\n\n            if (_TOOLCHAIN_TYPE MATCHES \".*\\\\((active, )?default\\\\).*\")\n                set(_TOOLCHAIN_DEFAULT \"${_TOOLCHAIN}\")\n            endif()\n\n            if (_TOOLCHAIN_TYPE MATCHES \".*\\\\((active|override)\\\\).*\")\n                set(_TOOLCHAIN_OVERRIDE \"${_TOOLCHAIN}\")\n            endif()\n\n            execute_process(\n                    COMMAND\n                    \"${_TOOLCHAIN_PATH}/bin/rustc\" --version\n                    OUTPUT_VARIABLE _TOOLCHAIN_RAW_VERSION\n            )\n            if (_TOOLCHAIN_RAW_VERSION MATCHES \"rustc ([0-9]+)\\\\.([0-9]+)\\\\.([0-9]+)(-nightly)?\")\n                list(APPEND _DISCOVERED_TOOLCHAINS \"${_TOOLCHAIN}\")\n                list(APPEND _DISCOVERED_TOOLCHAINS_RUSTC_PATH \"${_TOOLCHAIN_PATH}/bin/rustc\")\n                list(APPEND _DISCOVERED_TOOLCHAINS_VERSION \"${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}\")\n\n                # We need this variable to determine the default toolchain, since `foreach(... IN ZIP_LISTS ...)`\n                # requires CMake 3.17. As a workaround we define this variable to lookup the version when iterating\n                # through the `_DISCOVERED_TOOLCHAINS` lists.\n                set(_TOOLCHAIN_${_TOOLCHAIN}_VERSION \"${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}\")\n                if(CMAKE_MATCH_4)\n                    set(_TOOLCHAIN_${_TOOLCHAIN}_IS_NIGHTLY \"TRUE\")\n                else()\n                    set(_TOOLCHAIN_${_TOOLCHAIN}_IS_NIGHTLY \"FALSE\")\n                endif()\n                set(_suffix \"\")\n                if(CMAKE_HOST_WIN32)\n                    set(_suffix \".exe\")\n                endif()\n                if(EXISTS \"${_TOOLCHAIN_PATH}/bin/cargo${_suffix}\")\n                    list(APPEND _DISCOVERED_TOOLCHAINS_CARGO_PATH \"${_TOOLCHAIN_PATH}/bin/cargo\")\n                else()\n                    list(APPEND _DISCOVERED_TOOLCHAINS_CARGO_PATH \"NOTFOUND\")\n                endif()\n            else()\n                message(AUTHOR_WARNING \"Unexpected output from `rustc --version` for Toolchain `${_TOOLCHAIN}`: \"\n                        \"`${_TOOLCHAIN_RAW_VERSION}`.\\n\"\n                        \"Ignoring this toolchain (Path: `${_TOOLCHAIN_PATH}`).\"\n                )\n            endif()\n        else()\n            message(AUTHOR_WARNING \"Didn't recognize toolchain: ${_TOOLCHAIN_RAW}. Ignoring this toolchain.\\n\"\n                \"Rustup toolchain list output( `${Rust_RUSTUP} toolchain list --verbose`):\\n\"\n                \"${_TOOLCHAINS_RAW}\"\n            )\n        endif()\n    endforeach()\n\n    # Expose a list of available rustup toolchains.\n    list(LENGTH _DISCOVERED_TOOLCHAINS _toolchain_len)\n    list(LENGTH _DISCOVERED_TOOLCHAINS_RUSTC_PATH _toolchain_rustc_len)\n    list(LENGTH _DISCOVERED_TOOLCHAINS_CARGO_PATH _toolchain_cargo_len)\n    list(LENGTH _DISCOVERED_TOOLCHAINS_VERSION _toolchain_version_len)\n    if(NOT\n        (_toolchain_len EQUAL _toolchain_rustc_len\n            AND _toolchain_cargo_len EQUAL _toolchain_version_len\n            AND _toolchain_len EQUAL _toolchain_cargo_len)\n        )\n        message(FATAL_ERROR \"Internal error - list length mismatch.\"\n            \"List lengths: ${_toolchain_len} toolchains, ${_toolchain_rustc_len} rustc, ${_toolchain_cargo_len} cargo,\"\n            \" ${_toolchain_version_len} version. The lengths should be the same.\"\n        )\n    endif()\n\n    set(Rust_RUSTUP_TOOLCHAINS \"${_DISCOVERED_TOOLCHAINS}\" CACHE INTERNAL \"List of available Rustup toolchains\")\n    set(Rust_RUSTUP_TOOLCHAINS_RUSTC_PATH \"${_DISCOVERED_TOOLCHAINS_RUSTC_PATH}\"\n        CACHE INTERNAL\n        \"List of the rustc paths corresponding to the toolchain at the same index in `Rust_RUSTUP_TOOLCHAINS`.\"\n    )\n    set(Rust_RUSTUP_TOOLCHAINS_CARGO_PATH \"${_DISCOVERED_TOOLCHAINS_CARGO_PATH}\"\n        CACHE INTERNAL\n        \"List of the cargo paths corresponding to the toolchain at the same index in `Rust_RUSTUP_TOOLCHAINS`. \\\n        May also be `NOTFOUND` if the toolchain does not have a cargo executable.\"\n    )\n    set(Rust_RUSTUP_TOOLCHAINS_VERSION \"${_DISCOVERED_TOOLCHAINS_VERSION}\"\n        CACHE INTERNAL\n        \"List of the rust toolchain version corresponding to the toolchain at the same index in \\\n        `Rust_RUSTUP_TOOLCHAINS`.\"\n    )\n\n    # Rust_TOOLCHAIN is preferred over a requested version if it is set.\n    if (NOT DEFINED Rust_TOOLCHAIN)\n        if (NOT DEFINED _TOOLCHAIN_OVERRIDE)\n            set(_TOOLCHAIN_SELECTED \"${_TOOLCHAIN_DEFAULT}\")\n        else()\n            set(_TOOLCHAIN_SELECTED \"${_TOOLCHAIN_OVERRIDE}\")\n        endif()\n        # Check default toolchain first.\n        _findrust_version_ok(\"_TOOLCHAIN_${_TOOLCHAIN_SELECTED}_VERSION\" _VERSION_OK)\n        if(NOT \"${_VERSION_OK}\")\n            foreach(_TOOLCHAIN \"${_DISCOVERED_TOOLCHAINS}\")\n                _findrust_version_ok(\"_TOOLCHAIN_${_TOOLCHAIN}_VERSION\" _VERSION_OK)\n                if(\"${_VERSION_OK}\")\n                    set(_TOOLCHAIN_SELECTED \"${_TOOLCHAIN}\")\n                    break()\n                endif()\n            endforeach()\n            # Check if we found a suitable version in the for loop.\n            if(NOT \"${_VERSION_OK}\")\n                string(REPLACE \";\" \"\\n\" _DISCOVERED_TOOLCHAINS \"${_DISCOVERED_TOOLCHAINS}\")\n                _findrust_failed(\"Failed to find a Rust toolchain matching the version requirements of \"\n                        \"${Rust_FIND_VERSION}. Available toolchains: ${_DISCOVERED_TOOLCHAINS}\")\n            endif()\n        endif()\n    endif()\n\n    set(Rust_TOOLCHAIN \"${_TOOLCHAIN_SELECTED}\" CACHE STRING \"The rustup toolchain to use\")\n    set_property(CACHE Rust_TOOLCHAIN PROPERTY STRINGS \"${_DISCOVERED_TOOLCHAINS}\")\n\n    if(NOT Rust_FIND_QUIETLY)\n        message(STATUS \"Rust Toolchain: ${Rust_TOOLCHAIN}\")\n    endif()\n\n    if (NOT Rust_TOOLCHAIN IN_LIST _DISCOVERED_TOOLCHAINS)\n        # If the precise toolchain wasn't found, try appending the default host\n        execute_process(\n            COMMAND\n                \"${Rust_RUSTUP}\" show\n            RESULT_VARIABLE _SHOW_RESULT\n            OUTPUT_VARIABLE _SHOW_RAW\n        )\n        if(NOT \"${_SHOW_RESULT}\" EQUAL \"0\")\n            _findrust_failed(\"Command `${Rust_RUSTUP} show` failed\")\n        endif()\n\n        if (_SHOW_RAW MATCHES \"Default host: ([a-zA-Z0-9_\\\\-]*)\\n\")\n            set(_DEFAULT_HOST \"${CMAKE_MATCH_1}\")\n        else()\n            _findrust_failed(\"Failed to parse \\\"Default host\\\" from `${Rust_RUSTUP} show`. Got: ${_SHOW_RAW}\")\n        endif()\n\n        if (NOT \"${Rust_TOOLCHAIN}-${_DEFAULT_HOST}\" IN_LIST _DISCOVERED_TOOLCHAINS)\n            set(_NOT_FOUND_MESSAGE \"Could not find toolchain '${Rust_TOOLCHAIN}'\\n\"\n                \"Available toolchains:\\n\"\n            )\n            foreach(_TOOLCHAIN ${_DISCOVERED_TOOLCHAINS})\n                list(APPEND _NOT_FOUND_MESSAGE \"  `${_TOOLCHAIN}`\\n\")\n            endforeach()\n            _findrust_failed(${_NOT_FOUND_MESSAGE})\n        endif()\n\n        set(_RUSTUP_TOOLCHAIN_FULL \"${Rust_TOOLCHAIN}-${_DEFAULT_HOST}\")\n    else()\n        set(_RUSTUP_TOOLCHAIN_FULL \"${Rust_TOOLCHAIN}\")\n    endif()\n\n    set(_RUST_TOOLCHAIN_PATH \"${_TOOLCHAIN_${_RUSTUP_TOOLCHAIN_FULL}_PATH}\")\n    if(NOT \"${Rust_FIND_QUIETLY}\")\n        message(VERBOSE \"Rust toolchain ${_RUSTUP_TOOLCHAIN_FULL}\")\n        message(VERBOSE \"Rust toolchain path ${_RUST_TOOLCHAIN_PATH}\")\n    endif()\n\n    # Is overridden if the user specifies `Rust_COMPILER` explicitly.\n    find_program(\n        Rust_COMPILER_CACHED\n        rustc\n            HINTS \"${_RUST_TOOLCHAIN_PATH}/bin\"\n            NO_DEFAULT_PATH)\nelse()\n    message(DEBUG \"Rust_RESOLVE_RUSTUP_TOOLCHAINS=OFF and Rust_RUSTUP=${Rust_RUSTUP}\")\n    if(Rust_RUSTUP)\n        get_filename_component(_RUSTUP_DIR \"${Rust_RUSTUP}\" DIRECTORY)\n        find_program(Rust_COMPILER_CACHED rustc HINTS \"${_RUSTUP_DIR}\")\n    else()\n        find_program(Rust_COMPILER_CACHED rustc)\n    endif()\n    message(DEBUG \"find_program rustc: ${Rust_COMPILER_CACHED}\")\n    if (EXISTS \"${Rust_COMPILER_CACHED}\")\n        # rustc is expected to be at `<toolchain_path>/bin/rustc`.\n        get_filename_component(_RUST_TOOLCHAIN_PATH \"${Rust_COMPILER_CACHED}\" DIRECTORY)\n        get_filename_component(_RUST_TOOLCHAIN_PATH \"${_RUST_TOOLCHAIN_PATH}\" DIRECTORY)\n    endif()\nendif()\n\nif (NOT EXISTS \"${Rust_COMPILER_CACHED}\")\n    set(_NOT_FOUND_MESSAGE \"The rustc executable was not found. \"\n        \"Rust not installed or ~/.cargo/bin not added to path?\\n\"\n        \"Hint: Consider setting `Rust_COMPILER` to the absolute path of `rustc`.\"\n    )\n    _findrust_failed(${_NOT_FOUND_MESSAGE})\nendif()\n\nif (Rust_RESOLVE_RUSTUP_TOOLCHAINS)\n    set(_NOT_FOUND_MESSAGE \"Rust was detected to be managed by rustup, but failed to find `cargo` \"\n        \"next to `rustc` in `${_RUST_TOOLCHAIN_PATH}/bin`. This can happen for custom toolchains, \"\n        \"if cargo was not built. \"\n        \"Please manually specify the path to a compatible `cargo` by setting `Rust_CARGO`.\"\n    )\n    find_program(\n        Rust_CARGO_CACHED\n        cargo\n            HINTS \"${_RUST_TOOLCHAIN_PATH}/bin\"\n            NO_DEFAULT_PATH\n    )\n    # note: maybe can use find_package_handle_standard_args here, if we remove the _CACHED postfix.\n    # not sure why that is here...\n    if(NOT EXISTS \"${Rust_CARGO_CACHED}\")\n        _findrust_failed(${_NOT_FOUND_MESSAGE})\n    endif()\n    set(Rust_TOOLCHAIN_IS_RUSTUP_MANAGED TRUE CACHE INTERNAL \"\" FORCE)\nelse()\n    set(_NOT_FOUND_MESSAGE \"Failed to find `cargo` in PATH and `${_RUST_TOOLCHAIN_PATH}/bin`.\\n\"\n        \"Please ensure cargo is in PATH or manually specify the path to a compatible `cargo` by \"\n        \"setting `Rust_CARGO`.\"\n    )\n    # On some systems (e.g. NixOS) cargo is not managed by rustup and also not next to rustc.\n    find_program(\n            Rust_CARGO_CACHED\n            cargo\n                HINTS \"${_RUST_TOOLCHAIN_PATH}/bin\"\n    )\n    # note: maybe can use find_package_handle_standard_args here, if we remove the _CACHED postfix.\n    # not sure why that is here...\n    if(NOT EXISTS \"${Rust_CARGO_CACHED}\")\n        _findrust_failed(${_NOT_FOUND_MESSAGE})\n    endif()\nendif()\n\nexecute_process(\n    COMMAND \"${Rust_CARGO_CACHED}\" --version --verbose\n    OUTPUT_VARIABLE _CARGO_VERSION_RAW\n    RESULT_VARIABLE _CARGO_VERSION_RESULT\n)\n# todo: check if cargo is a required component!\nif(NOT ( \"${_CARGO_VERSION_RESULT}\" EQUAL \"0\" ))\n    _findrust_failed(\"Failed to get cargo version.\\n\"\n        \"`${Rust_CARGO_CACHED} --version` failed with error: `${_CARGO_VERSION_RESULT}\"\n)\nendif()\n\n# todo: don't set cache variables here, but let find_package_handle_standard_args do the promotion\n# later.\nif (_CARGO_VERSION_RAW MATCHES \"cargo ([0-9]+)\\\\.([0-9]+)\\\\.([0-9]+)\")\n    set(Rust_CARGO_VERSION_MAJOR \"${CMAKE_MATCH_1}\" CACHE INTERNAL \"\" FORCE)\n    set(Rust_CARGO_VERSION_MINOR \"${CMAKE_MATCH_2}\" CACHE INTERNAL \"\" FORCE)\n    set(Rust_CARGO_VERSION_PATCH \"${CMAKE_MATCH_3}\" CACHE INTERNAL \"\" FORCE)\n    set(Rust_CARGO_VERSION \"${Rust_CARGO_VERSION_MAJOR}.${Rust_CARGO_VERSION_MINOR}.${Rust_CARGO_VERSION_PATCH}\" CACHE INTERNAL \"\" FORCE)\n# Workaround for the version strings where the `cargo ` prefix is missing.\nelseif(_CARGO_VERSION_RAW MATCHES \"([0-9]+)\\\\.([0-9]+)\\\\.([0-9]+)\")\n    set(Rust_CARGO_VERSION_MAJOR \"${CMAKE_MATCH_1}\" CACHE INTERNAL \"\" FORCE)\n    set(Rust_CARGO_VERSION_MINOR \"${CMAKE_MATCH_2}\" CACHE INTERNAL \"\" FORCE)\n    set(Rust_CARGO_VERSION_PATCH \"${CMAKE_MATCH_3}\" CACHE INTERNAL \"\" FORCE)\n    set(Rust_CARGO_VERSION \"${Rust_CARGO_VERSION_MAJOR}.${Rust_CARGO_VERSION_MINOR}.${Rust_CARGO_VERSION_PATCH}\" CACHE INTERNAL \"\" FORCE)\nelse()\n    _findrust_failed(\n        \"Failed to parse cargo version. `cargo --version` evaluated to (${_CARGO_VERSION_RAW}). \"\n        \"Expected a <Major>.<Minor>.<Patch> version triple.\"\n    )\nendif()\n\nexecute_process(\n    COMMAND \"${Rust_COMPILER_CACHED}\" --version --verbose\n    OUTPUT_VARIABLE _RUSTC_VERSION_RAW\n    RESULT_VARIABLE _RUSTC_VERSION_RESULT\n)\n\nif(NOT ( \"${_RUSTC_VERSION_RESULT}\" EQUAL \"0\" ))\n    _findrust_failed(\"Failed to get rustc version.\\n\"\n        \"${Rust_COMPILER_CACHED} --version failed with error: `${_RUSTC_VERSION_RESULT}`\")\nendif()\n\nif (_RUSTC_VERSION_RAW MATCHES \"rustc ([0-9]+)\\\\.([0-9]+)\\\\.([0-9]+)(-nightly)?\")\n    set(Rust_VERSION_MAJOR \"${CMAKE_MATCH_1}\" CACHE INTERNAL \"\" FORCE)\n    set(Rust_VERSION_MINOR \"${CMAKE_MATCH_2}\" CACHE INTERNAL \"\" FORCE)\n    set(Rust_VERSION_PATCH \"${CMAKE_MATCH_3}\" CACHE INTERNAL \"\" FORCE)\n    set(Rust_VERSION \"${Rust_VERSION_MAJOR}.${Rust_VERSION_MINOR}.${Rust_VERSION_PATCH}\" CACHE INTERNAL \"\" FORCE)\n    if(CMAKE_MATCH_4)\n        set(Rust_IS_NIGHTLY 1 CACHE INTERNAL \"\" FORCE)\n    else()\n        set(Rust_IS_NIGHTLY 0 CACHE INTERNAL \"\" FORCE)\n    endif()\nelse()\n    _findrust_failed(\"Failed to parse rustc version. `${Rust_COMPILER_CACHED} --version --verbose` \"\n        \"evaluated to:\\n`${_RUSTC_VERSION_RAW}`\"\n    )\nendif()\n\nif (_RUSTC_VERSION_RAW MATCHES \"host: ([a-zA-Z0-9_\\\\-]*)\\n\")\n    set(Rust_DEFAULT_HOST_TARGET \"${CMAKE_MATCH_1}\")\n    set(Rust_CARGO_HOST_TARGET_CACHED \"${Rust_DEFAULT_HOST_TARGET}\" CACHE STRING \"Host triple\")\nelse()\n    _findrust_failed(\n        \"Failed to parse rustc host target. `rustc --version --verbose` evaluated to:\\n${_RUSTC_VERSION_RAW}\"\n    )\nendif()\n\nif (_RUSTC_VERSION_RAW MATCHES \"LLVM version: ([0-9]+)\\\\.([0-9]+)(\\\\.([0-9]+))?\")\n    set(Rust_LLVM_VERSION_MAJOR \"${CMAKE_MATCH_1}\" CACHE INTERNAL \"\" FORCE)\n    set(Rust_LLVM_VERSION_MINOR \"${CMAKE_MATCH_2}\" CACHE INTERNAL \"\" FORCE)\n    # With the Rust toolchain 1.44.1 the reported LLVM version is 9.0, i.e. without a patch version.\n    # Since cmake regex does not support non-capturing groups, just ignore Match 3.\n    set(Rust_LLVM_VERSION_PATCH \"${CMAKE_MATCH_4}\" CACHE INTERNAL \"\" FORCE)\n    set(Rust_LLVM_VERSION \"${Rust_LLVM_VERSION_MAJOR}.${Rust_LLVM_VERSION_MINOR}.${Rust_LLVM_VERSION_PATCH}\" CACHE INTERNAL \"\" FORCE)\nelseif(NOT Rust_FIND_QUIETLY)\n    message(\n            WARNING\n            \"Failed to parse rustc LLVM version. `rustc --version --verbose` evaluated to:\\n${_RUSTC_VERSION_RAW}\"\n    )\nendif()\n\nif (NOT Rust_CARGO_TARGET_CACHED)\n    unset(_CARGO_ARCH)\n    unset(_CARGO_ABI)\n    if (WIN32)\n        if (CMAKE_VS_PLATFORM_NAME)\n            string(TOLOWER \"${CMAKE_VS_PLATFORM_NAME}\" LOWER_VS_PLATFORM_NAME)\n            if (\"${LOWER_VS_PLATFORM_NAME}\" STREQUAL \"win32\")\n                set(_CARGO_ARCH i686)\n            elseif(\"${LOWER_VS_PLATFORM_NAME}\" STREQUAL \"x64\")\n                set(_CARGO_ARCH x86_64)\n            elseif(\"${LOWER_VS_PLATFORM_NAME}\" STREQUAL \"arm64\")\n                set(_CARGO_ARCH aarch64)\n            else()\n                message(WARNING \"VS Platform '${CMAKE_VS_PLATFORM_NAME}' not recognized\")\n            endif()\n        endif()\n        # Fallback path\n        if(NOT DEFINED _CARGO_ARCH)\n            # Possible values for windows when not cross-compiling taken from here:\n            # https://learn.microsoft.com/en-us/windows/win32/winprog64/wow64-implementation-details\n            # When cross-compiling the user is expected to supply the value, so we match more variants.\n            if(CMAKE_SYSTEM_PROCESSOR MATCHES \"^(AMD64|amd64|x86_64)$\")\n                set(_CARGO_ARCH x86_64)\n            elseif(CMAKE_SYSTEM_PROCESSOR MATCHES \"^(ARM64|arm64|aarch64)$\")\n                set(_CARGO_ARCH aarch64)\n            elseif(CMAKE_SYSTEM_PROCESSOR MATCHES \"^(X86|x86|i686)$\")\n                set(_CARGO_ARCH i686)\n            elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL \"i586\")\n                set(_CARGO_ARCH i586)\n            elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL \"IA64\")\n                message(FATAL_ERROR \"No rust target for Intel Itanium.\")\n            elseif(NOT \"${CMAKE_SYSTEM_PROCESSOR}\")\n                message(WARNING \"Failed to detect target architecture. Please set `CMAKE_SYSTEM_PROCESSOR`\"\n                    \" to your target architecture or set `Rust_CARGO_TARGET` to your cargo target triple.\"\n                )\n            else()\n                message(WARNING \"Failed to detect target architecture. Please set \"\n                    \"`Rust_CARGO_TARGET` to your cargo target triple.\"\n                )\n            endif()\n        endif()\n\n        set(_CARGO_VENDOR \"pc-windows\")\n\n        # The MSVC Generators will always target the msvc ABI.\n        # For other generators we check the compiler ID and compiler target (if present)\n        # If no compiler is set and we are not cross-compiling then we just choose the\n        # default rust host target.\n        if(DEFINED MSVC\n            OR \"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"MSVC\"\n            OR \"${CMAKE_C_COMPILER_ID}\" STREQUAL \"MSVC\"\n            OR \"${CMAKE_CXX_COMPILER_TARGET}\" MATCHES \"-msvc$\"\n            OR \"${CMAKE_C_COMPILER_TARGET}\" MATCHES \"-msvc$\"\n        )\n            set(_CARGO_ABI msvc)\n        elseif(\"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"GNU\"\n            OR \"${CMAKE_C_COMPILER_ID}\" STREQUAL \"GNU\"\n            OR (NOT CMAKE_CROSSCOMPILING\n               AND NOT DEFINED CMAKE_CXX_COMPILER_ID\n               AND NOT DEFINED CMAKE_C_COMPILER_ID\n               AND \"${Rust_DEFAULT_HOST_TARGET}\" MATCHES \"-gnu$\"\n            )\n        )\n            set(_CARGO_ABI gnu)\n        elseif((\"${CMAKE_C_COMPILER_ID}\" MATCHES \"Clang$\" OR \"${CMAKE_CXX_COMPILER_ID}\" MATCHES \"Clang$\")\n            AND (\"${CMAKE_CXX_COMPILER_TARGET}\" MATCHES \"-gnu(llvm)?$\"\n                OR \"${CMAKE_C_COMPILER_TARGET}\" MATCHES \"-gnu(llvm)?$\")\n        )\n            if(\"${Rust_VERSION}\" VERSION_GREATER_EQUAL \"1.79\")\n                set(_CARGO_ABI gnullvm)\n            else()\n                message(WARNING \"Your selected C/C++ compilers suggest you want to use the -gnullvm\"\n                        \" rust targets, however your Rust compiler version is ${Rust_VERSION}, which is\"\n                        \" before the promotion of the gnullvm target to tier2.\"\n                        \" Please either use a more recent rust compiler or manually choose a target \"\n                        \" triple by specifying `Rust_CARGO_TARGET` manually.\"\n                )\n            endif()\n        elseif(NOT \"${CMAKE_CROSSCOMPILING}\" AND \"${Rust_DEFAULT_HOST_TARGET}\" MATCHES \"-msvc$\")\n            # We first check if the gnu branches match to ensure this fallback is only used\n            # if no compiler is enabled.\n            set(_CARGO_ABI msvc)\n        else()\n            message(WARNING \"Could not determine the target ABI. Please specify `Rust_CARGO_TARGET` manually.\")\n        endif()\n\n        if(DEFINED _CARGO_ARCH AND DEFINED _CARGO_VENDOR AND DEFINED _CARGO_ABI)\n            set(Rust_CARGO_TARGET_CACHED \"${_CARGO_ARCH}-${_CARGO_VENDOR}-${_CARGO_ABI}\"\n                CACHE STRING \"Target triple\")\n        endif()\n    elseif (ANDROID)\n        if (CMAKE_ANDROID_ARCH_ABI STREQUAL armeabi-v7a)\n            if (CMAKE_ANDROID_ARM_NEON)\n                set(_Rust_ANDROID_TARGET thumbv7neon-linux-androideabi)\n            else ()\n                set(_Rust_ANDROID_TARGET armv7-linux-androideabi)\n            endif()\n        elseif (CMAKE_ANDROID_ARCH_ABI STREQUAL arm64-v8a)\n            set(_Rust_ANDROID_TARGET aarch64-linux-android)\n        elseif (CMAKE_ANDROID_ARCH_ABI STREQUAL x86)\n            set(_Rust_ANDROID_TARGET i686-linux-android)\n        elseif (CMAKE_ANDROID_ARCH_ABI STREQUAL x86_64)\n            set(_Rust_ANDROID_TARGET x86_64-linux-android)\n        endif()\n\n        if (_Rust_ANDROID_TARGET)\n            set(Rust_CARGO_TARGET_CACHED \"${_Rust_ANDROID_TARGET}\" CACHE STRING \"Target triple\")\n        endif()\n    elseif(\"${CMAKE_SYSTEM_NAME}\" STREQUAL \"OHOS\")\n        if(CMAKE_OHOS_ARCH_ABI STREQUAL arm64-v8a)\n            set(_RUST_OHOS_TARGET aarch64-unknown-linux-ohos)\n        elseif(CMAKE_OHOS_ARCH_ABI STREQUAL armeabi-v7a)\n            set(_RUST_OHOS_TARGET armv7-unknown-linux-ohos)\n        elseif(CMAKE_OHOS_ARCH_ABI STREQUAL x86_64)\n            set(_RUST_OHOS_TARGET x86_64-unknown-linux-ohos)\n        else()\n            message(WARNING \"unrecognized OHOS architecture: ${OHOS_ARCH}\")\n        endif()\n        if(_RUST_OHOS_TARGET)\n            set(Rust_CARGO_TARGET_CACHED \"${_RUST_OHOS_TARGET}\" CACHE STRING \"Target triple\")\n        endif()\n    endif()\n    # Fallback to the default host target\n    if(NOT Rust_CARGO_TARGET_CACHED)\n        if(CMAKE_CROSSCOMPILING)\n            message(WARNING \"CMake is in cross-compiling mode, but the cargo target-triple could not be inferred.\"\n                \"Falling back to the default host target. Please consider manually setting `Rust_CARGO_TARGET`.\"\n            )\n        endif()\n        set(Rust_CARGO_TARGET_CACHED \"${Rust_DEFAULT_HOST_TARGET}\" CACHE STRING \"Target triple\")\n    endif()\n\n    message(STATUS \"Rust Target: ${Rust_CARGO_TARGET_CACHED}\")\nendif()\n\n\nif(Rust_TOOLCHAIN_IS_RUSTUP_MANAGED)\n    execute_process(COMMAND rustup target list --toolchain \"${Rust_TOOLCHAIN}\"\n                    OUTPUT_VARIABLE AVAILABLE_TARGETS_RAW\n    )\n    string(REPLACE \"\\n\" \";\" AVAILABLE_TARGETS_RAW \"${AVAILABLE_TARGETS_RAW}\")\n    string(REPLACE \" (installed)\" \"\" \"AVAILABLE_TARGETS\" \"${AVAILABLE_TARGETS_RAW}\")\n    set(INSTALLED_TARGETS_RAW \"${AVAILABLE_TARGETS_RAW}\")\n    list(FILTER INSTALLED_TARGETS_RAW INCLUDE REGEX \" \\\\(installed\\\\)\")\n    string(REPLACE \" (installed)\" \"\" \"INSTALLED_TARGETS\" \"${INSTALLED_TARGETS_RAW}\")\n    list(TRANSFORM INSTALLED_TARGETS STRIP)\n    if(\"${Rust_CARGO_TARGET_CACHED}\" IN_LIST AVAILABLE_TARGETS)\n        message(DEBUG \"Cargo target ${Rust_CARGO_TARGET} is an official target-triple\")\n        message(DEBUG \"Installed targets: ${INSTALLED_TARGETS}\")\n        if(NOT (\"${Rust_CARGO_TARGET_CACHED}\" IN_LIST INSTALLED_TARGETS))\n            if(Rust_RUSTUP_INSTALL_MISSING_TARGET)\n                message(STATUS \"Cargo target ${Rust_CARGO_TARGET_CACHED} is not installed. Installing via rustup.\")\n                execute_process(COMMAND \"${Rust_RUSTUP}\" target add\n                                --toolchain ${Rust_TOOLCHAIN}\n                                ${Rust_CARGO_TARGET_CACHED}\n                                RESULT_VARIABLE target_add_result\n                )\n                if(NOT \"${target_add_result}\" EQUAL \"0\")\n                    message(FATAL_ERROR \"Target ${Rust_CARGO_TARGET_CACHED} is not installed for toolchain \"\n                            \"${Rust_TOOLCHAIN} and automatically installing failed with ${target_add_result}.\\n\"\n                            \"You can try to manually install by running\\n\"\n                            \"`rustup target add --toolchain ${Rust_TOOLCHAIN} ${Rust_CARGO_TARGET}`.\"\n                    )\n                endif()\n                message(STATUS \"Installed target ${Rust_CARGO_TARGET_CACHED} successfully.\")\n            else()\n                message(FATAL_ERROR \"Target ${Rust_CARGO_TARGET_CACHED} is not installed for toolchain ${Rust_TOOLCHAIN}.\\n\"\n                        \"Help: Run `rustup target add --toolchain ${Rust_TOOLCHAIN} ${Rust_CARGO_TARGET_CACHED}` to install \"\n                        \"the missing target or configure corrosion with `Rust_RUSTUP_INSTALL_MISSING_TARGET=ON`.\"\n                )\n            endif()\n        endif()\n    endif()\nendif()\n\nif(Rust_CARGO_TARGET_CACHED STREQUAL Rust_DEFAULT_HOST_TARGET)\n    set(Rust_CROSSCOMPILING FALSE CACHE INTERNAL \"Rust is configured for cross-compiling\")\nelse()\n    set(Rust_CROSSCOMPILING TRUE  CACHE INTERNAL \"Rust is configured for cross-compiling\")\nendif()\n\n_corrosion_parse_target_triple(\"${Rust_CARGO_TARGET_CACHED}\" rust_arch rust_vendor rust_os rust_env)\n_corrosion_parse_target_triple(\"${Rust_CARGO_HOST_TARGET_CACHED}\" rust_host_arch rust_host_vendor rust_host_os rust_host_env)\n\nset(Rust_CARGO_TARGET_ARCH \"${rust_arch}\" CACHE INTERNAL \"Target architecture\")\nset(Rust_CARGO_TARGET_VENDOR \"${rust_vendor}\" CACHE INTERNAL \"Target vendor\")\nset(Rust_CARGO_TARGET_OS \"${rust_os}\" CACHE INTERNAL \"Target Operating System\")\nset(Rust_CARGO_TARGET_ENV \"${rust_env}\" CACHE INTERNAL \"Target environment\")\n\nset(Rust_CARGO_HOST_ARCH \"${rust_host_arch}\" CACHE INTERNAL \"Host architecture\")\nset(Rust_CARGO_HOST_VENDOR \"${rust_host_vendor}\" CACHE INTERNAL \"Host vendor\")\nset(Rust_CARGO_HOST_OS \"${rust_host_os}\" CACHE INTERNAL \"Host Operating System\")\nset(Rust_CARGO_HOST_ENV \"${rust_host_env}\" CACHE INTERNAL \"Host environment\")\n\nif(NOT DEFINED CACHE{Rust_CARGO_TARGET_LINK_NATIVE_LIBS})\n    message(STATUS \"Determining required link libraries for target ${Rust_CARGO_TARGET_CACHED}\")\n    unset(required_native_libs)\n    _corrosion_determine_libs_new(\"${Rust_CARGO_TARGET_CACHED}\" required_native_libs required_link_flags)\n    if(DEFINED required_native_libs)\n        message(STATUS \"Required static libs for target ${Rust_CARGO_TARGET_CACHED}: ${required_native_libs}\" )\n    endif()\n    if(DEFINED required_link_flags)\n        message(STATUS \"Required link flags for target ${Rust_CARGO_TARGET_CACHED}: ${required_link_flags}\" )\n    endif()\n    # In very recent corrosion versions it is possible to override the rust compiler version\n    # per target, so to be totally correct we would need to determine the libraries for\n    # every installed Rust version, that the user could choose from.\n    # In practice there aren't likely going to be any major differences, so we just do it once\n    # for the target and once for the host target (if cross-compiling).\n    set(Rust_CARGO_TARGET_LINK_NATIVE_LIBS \"${required_native_libs}\" CACHE INTERNAL\n            \"Required native libraries when linking Rust static libraries\")\n    set(Rust_CARGO_TARGET_LINK_OPTIONS \"${required_link_flags}\" CACHE INTERNAL\n            \"Required link flags when linking Rust static libraries\")\nendif()\n\nif(Rust_CROSSCOMPILING AND NOT DEFINED CACHE{Rust_CARGO_HOST_TARGET_LINK_NATIVE_LIBS})\n    message(STATUS \"Determining required link libraries for target ${Rust_CARGO_HOST_TARGET_CACHED}\")\n    unset(host_libs)\n    _corrosion_determine_libs_new(\"${Rust_CARGO_HOST_TARGET_CACHED}\" host_libs host_flags)\n    if(DEFINED host_libs)\n        message(STATUS \"Required static libs for host target ${Rust_CARGO_HOST_TARGET_CACHED}: ${host_libs}\" )\n    endif()\n    set(Rust_CARGO_HOST_TARGET_LINK_NATIVE_LIBS \"${host_libs}\" CACHE INTERNAL\n        \"Required native libraries when linking Rust static libraries for the host target\")\n    set(Rust_CARGO_HOST_TARGET_LINK_OPTIONS \"${host_flags}\" CACHE INTERNAL\n        \"Required linker flags when linking Rust static libraries for the host target\")\nendif()\n\n# Set the input variables as non-cache variables so that the variables are available after\n# `find_package`, even if the values were evaluated to defaults.\nforeach(_VAR ${_Rust_USER_VARS})\n    set(${_VAR} \"${${_VAR}_CACHED}\")\n    # Ensure cached variables have type INTERNAL\n    set(${_VAR}_CACHED \"${${_VAR}_CACHED}\" CACHE INTERNAL \"Internal cache of ${_VAR}\")\nendforeach()\n\nfind_package_handle_standard_args(\n    Rust\n    REQUIRED_VARS Rust_COMPILER Rust_VERSION Rust_CARGO Rust_CARGO_VERSION Rust_CARGO_TARGET Rust_CARGO_HOST_TARGET\n    VERSION_VAR Rust_VERSION\n)\n\n\nif(NOT TARGET Rust::Rustc)\n    add_executable(Rust::Rustc IMPORTED GLOBAL)\n    set_property(\n        TARGET Rust::Rustc\n        PROPERTY IMPORTED_LOCATION \"${Rust_COMPILER_CACHED}\"\n    )\n\n    add_executable(Rust::Cargo IMPORTED GLOBAL)\n    set_property(\n        TARGET Rust::Cargo\n        PROPERTY IMPORTED_LOCATION \"${Rust_CARGO_CACHED}\"\n    )\n    set(Rust_FOUND true)\nendif()\n\nlist(POP_BACK CMAKE_MESSAGE_CONTEXT)\n"
  },
  {
    "path": "doc/.gitignore",
    "content": "book\n"
  },
  {
    "path": "doc/book.toml",
    "content": "[book]\nlanguage = \"en\"\nmultilingual = false\nsrc = \"src\"\ntitle = \"Corrosion documentation\"\n"
  },
  {
    "path": "doc/src/SUMMARY.md",
    "content": "# Summary\n\n- [Introduction](./introduction.md)\n- [Quick Start](./quick_start.md)\n- [Setup Corrosion](./setup_corrosion.md)\n- [Usage](./usage.md)\n- [Advanced](./advanced.md)\n- [FFI binding integrations](./ffi_bindings.md)\n- [Common Issues](./common_issues.md)\n"
  },
  {
    "path": "doc/src/advanced.md",
    "content": "## What does corrosion do?\n\nThe specifics of what corrosion does should be regarded as an implementation detail and not relied on\nwhen writing user code. However, a basic understanding of what corrosion does may be helpful when investigating\nissues.\n\n### FindRust\n\nCorrosion maintains a CMake module `FindRust` which is executed when Corrosion is loaded, i.e. at the time\nof `find_package(corrosion)`, `FetchContent_MakeAvailable(corrosion)` or `add_subdirectory(corrosion)` depending\non the method used to include Corrosion.\n\n`FindRust` will search for installed rust toolchains, respecting the options prefixed with `Rust_` documented in\nthe [Usage](usage.md#corrosion-options) chapter.\nIt will select _one_ Rust toolchain to be used for the compilation of Rust code. Toolchains managed by `rustup`\nwill be resolved and corrosion will always select a specific toolchain, not a `rustup` proxy.\n\n\n### Importing Rust crates\n\nCorrosion's main function is `corrosion_import_crate`, which internally will call `cargo metadata` to provide\nstructured information based on the `Cargo.toml` manifest.\nCorrosion will then iterate over all workspace and/or package members and find all rust crates that are either\na static (`staticlib`) or shared (`cdylib`) library or a `bin` target and create CMake targets matching the\ncrate name. Additionally, a build target is created for each imported target, containing the required build\ncommand to create the imported artifact. This build command can be influenced by various arguments to \n`corrosion_import_crate` as well as corrosion specific target properties which are documented int the  \n[Usage](usage.md) chapter.\nCorrosion adds the necessary dependencies and also copies the target artifacts out of the cargo build tree\nto standard CMake locations, even respecting `OUTPUT_DIRECTORY` target properties if set.\n\n### Linking\n\nDepending on the type of the crate the linker will either be invoked by CMake or by `rustc`.\nRust `staticlib`s are linked into C/C++ code via `target_link_libraries()` and the linker is\ninvoked by CMake.\nFor rust `cdylib`s and `bin`s, the linker is invoked via `rustc` and CMake just gets the final artifact.\n\n#### CMake invokes the linker\n\nWhen CMake invokes the linker, everything is as usual. CMake will call the linker with\nthe compiler as the linker driver and users can just use the regular CMake functions to\nmodify linking behaviour. `corrosion_set_linker()` has **no effect**.\nAs a convenience, `corrosion_link_libraries()` will forward its arguments to `target_link_libraries()`.\n\n#### Rustc invokes the linker \n\nRust `cdylib`s and `bin`s are linked via `rustc`. Corrosion provides several helper functions\nto influence the linker invocation for such targets. \n\n`corrosion_link_libraries()` is a limited version of `target_link_libraries()` \nfor rust `cdylib` or `bin` targets.\nUnder the hood this function passes `-l` and `-L` flags to the linker invocation and\nensures the linked libraries are built first.\nMuch of the advanced functionality available in `target_link_libraries()` is not implemented yet,\nbut pull-requests are welcome! In the meantime, users may want to use \n`corrosion_add_target_local_rustflags()` to pass customized linking flags.\n\n`corrosion_set_linker()` can be used to specify a custom linker, in case the default one\nchosen by corrosion is not what you want.\nCorrosion currently instructs `rustc` to use the C/C++ compiler as the linker driver.\nThis is done because:\n- For C++ code we must link with `libstdc++` or `libc++` (depending on the compiler), so we must\n  either specify the library on the link line or use a `c++` compiler as the linker driver.\n- `Rustc`s default linker selection currently is not so great. For a number of platforms\n  `rustc` will fallback to `cc` as the linker driver. When cross-compiling, this leads\n  to linking failures, since the linker driver is for the host architecture.\n  Corrosion avoids this by specifying the C/C++ compiler as the linker driver.\n\n\nIn some cases, especially in older rust versions (pre 1.68), the linker flavor detection \nof `rustc` is also not correct, so when setting a custom linker you may want to pass the\n[`-C linker-flavor`](https://doc.rust-lang.org/rustc/codegen-options/index.html#linker-flavor)\nrustflag via `corrosion_add_target_local_rustflags()`.\n\n## FFI bindings\n\nFor interaction between Rust and other languages there need to be some FFI bindings of some sort.\nFor simple cases manually defining the interfaces may be sufficient, but in many cases users\nwish to use tools like [bindgen], [cbindgen], [cxx] or [autocxx] to automate the generating of\nbindings.\n\nIn principle there are two different ways to generate the bindings:\n- use a `build.rs` script to generate the bindings when cargo is invoked, using\n  library versions of the tools to generate the bindings.\n- use the cli versions of the tools and setup custom CMake targets/commands to\n  generate the bindings. This approach should be preferred if the bindings are needed\n  by the C/C++ side.\n\nCorrosion currently provides 2 experimental functions to integrate cbindgen and cxx into\nthe build process. They are not 100% production ready yet, but should work well as a \ntemplate on how to integrate generating bindings into your build process.\n\nTodo: expand this documentation and link to other resources.\n\n[bindgen]: https://rust-lang.github.io/rust-bindgen/\n[cbindgen]: https://github.com/eqrion/cbindgen\n[cxx]: https://cxx.rs/\n[autocxx]: https://google.github.io/autocxx/index.html\n  "
  },
  {
    "path": "doc/src/common_issues.md",
    "content": "# Commonly encountered (Non-Corrosion) Issues\n\n## Table of Contents\n\n- [Linking Debug C/C++ libraries into Rust fails on Windows MSVC targets](#linking-debug-cc-libraries-into-rust-fails-on-windows-msvc-targets)\n- [Linking Rust static libraries into Debug C/C++ binaries fails on Windows MSVC targets](#linking-rust-static-libraries-into-debug-cc-binaries-fails-on-windows-msvc-targets)\n- [Missing `soname` on Linux for `cdylibs`](#missing-soname-on-linux-for-cdylibs)\n- [Missing `install_name` on MacOS for `ccdylibs` / Hardcoded references to the build-directory](#missing-installname-on-macos-for-ccdylibs--hardcoded-references-to-the-build-directory)\n- [CMake Error (target_link_libraries): Cannot find source file](#cmake-error-target_link_libraries-cannot-find-source-file)\n\n## Linking Debug C/C++ libraries into Rust fails on Windows MSVC targets\n\n`rustc` always links against the non-debug Windows runtime on `*-msvc` targets.\nThis is tracked [in this issue](https://github.com/rust-lang/rust/issues/39016)\nand could be fixed upstream.\n\nA typical error message for this issue is:\n\n```\n   Compiling rust_bin v0.1.0 (D:\\a\\corrosion\\corrosion\\test\\cxxbridge\\cxxbridge_cpp2rust\\rust)\nerror: linking with `link.exe` failed: exit code: 1319\n[ redacted ]\n  = note: cxxbridge-cpp.lib(lib.cpp.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in libcxx-bafec361a1a30317.rlib(cxx.o)\n\n          cxxbridge-cpp.lib(lib.cpp.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in libcxx-bafec361a1a30317.rlib(cxx.o)\n\n          cpp_lib.lib(cpplib.cpp.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in libcxx-bafec361a1a30317.rlib(cxx.o)\n\n          cpp_lib.lib(cpplib.cpp.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in libcxx-bafec361a1a30317.rlib(cxx.o)\n\n          msvcrt.lib(initializers.obj) : warning LNK4098: defaultlib 'msvcrtd.lib' conflicts with use of other libs; use /NODEFAULTLIB:library\n```\n\n### Solutions\n\nOne solution is to also use the non-debug version when building the C/C++ libraries. \nYou can set the [MSVC_RUNTIME_LIBRARY] target properties of your C/C++ libraries to the non-debug variants.\nBy default you will probably want to select the `MultiThreadedDLL` variant, unless you specified\n[`-Ctarget-feature=+crt-static`](https://rust-lang.github.io/rfcs/1721-crt-static.html) in your\n`RUSTFLAGS`.\n\n\n[MSVC_RUNTIME_LIBRARY]: https://cmake.org/cmake/help/latest/prop_tgt/MSVC_RUNTIME_LIBRARY.html#prop_tgt:MSVC_RUNTIME_LIBRARY\n\n## Linking Rust static libraries into Debug C/C++ binaries fails on Windows MSVC targets\n\nThis issue is quite similar to the previous one, except that this time it's a Rust library being linked\ninto a C/C++ target. If it's 100% only Rust code you likely won't even have any issues.\nHowever, if somewhere in the dependency graph C/C++ code is built and linked into your Rust library,\nyou will likely encounter this issue. Please note, that using [cxx] counts as using C++ code and will\nlead to this issue.\n\nThe previous solution should also work for this case, but additionally you [may also\nhave success](https://github.com/rust-lang/rust/issues/39016#issuecomment-853964918) by using \n`corrosion_set_env_vars(your_rust_lib \"CFLAGS=-MDd\" \"CXXFLAGS=-MDd\")` (or `-MTd` for a statically linked\nruntime).\nFor debug builds, this is likely to be the preferable solution. It assumes that downstream C/C++ code\nis built by the `cc` crate, which respects the `CFLAGS` and `CXXFLAGS` environment variables.\n\n[cxx]: https://github.com/dtolnay/cxx\n\n\n## Missing `soname` on Linux for `cdylibs`\n\nCargo doesn't support setting the `soname` field for cdylib, which may cause issues.\nYou can set the soname manually by passing a linker-flag such as `-Clink-arg=-Wl,-soname,libyour_crate.so`\nto the linker via `corrosion_add_target_local_rustflags()` and additionally seting the `IMPORTED_SONAME`\nproperty on the import CMake target:  \n```\nset_target_properties(your_crate-shared PROPERTIES IMPORTED_SONAME libyour_crate.so)\n```\nReplace `your_crate` with the name of your shared library as defined in the `[lib]` section of your Cargo.toml\nManifest file.\n\nAttention: The Linux section may not be entirely correct, maybe `$ORIGIN` needs to be added to the linker arguments.\nFeel free to open a pull-request with corrections.\n\n## Missing `install_name` on MacOS for `ccdylibs` / Hardcoded references to the build-directory\n\nThe solution here is essentially the same as in the previous section.\n```\ncorrosion_add_target_local_rustflags(your_crate -Clink-arg=-Wl,-install_name,@rpath/libyour_crate.dylib,-current_version,${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR},-compatibility_version,${PROJECT_VERSION_MAJOR}.0)\nset_target_properties(your_crate-shared PROPERTIES IMPORTED_NO_SONAME 0)\nset_target_properties(your_crate-shared PROPERTIES IMPORTED_SONAME libyour_crate.dylib)\n```\nWhen building binaries using this shared library, you should set the build rpath to the output directory of\nyour shared library, e.g. by setting `set(CMAKE_BUILD_RPATH ${YOUR_CUSTOM_OUTPUT_DIRECTORY})` before adding\nexecutables.\nFor a practical example, you may look at [Slint PR 2455](https://github.com/slint-ui/slint/pull/2455).\n\n## CMake Error (target_link_libraries): Cannot find source file\n\nWhen using `corrosion_add_cxxbridge`, you may encounter an error similar to this in targets that depend on the cxxbridge target:\n\n```diff\n- CMake Error at ...../CMakeLists.txt:61 (target_link_libraries):\n-  Cannot find source file:\n-\n-    ...../corrosion_generated/..../somefile.h\n-\n-  Tried extensions .c .C .c++ .cc .cpp .cxx .cu .mpp .m .M .mm .ixx .cppm\n-  .ccm .cxxm .c++m .h .hh .h++ .hm .hpp .hxx .in .txx .f .F .for .f77 .f90\n-  .f95 .f03 .hip .ispc\n```\n\nWhere `somefile.h` should be generated by CXX via `corrosion_add_cxxbridge`.\nIn theory, CMake should already know that this is a generated file and just generate it when needed.\n\nHowever, in older versions of CMake the `GENERATED` property isn't correctly propagated.\nSee also: [https://gitlab.kitware.com/cmake/cmake/-/issues/18399](https://gitlab.kitware.com/cmake/cmake/-/issues/18399)\n\nThis has since been fixed with CMake 3.20: [https://cmake.org/cmake/help/v3.20/policy/CMP0118.html](https://cmake.org/cmake/help/latest/command/cmake_policy.html#version)\nHowever, the CMake policy CMP0118 must be enabled **in any dependent CMakeLists.txt** for the fix to work.\n\nThe best fix is to call:\n```cmake\ncmake_minimium_required(VERSION 3.20 FATAL_ERROR)\n# (or any other version above 3.20)\n```\nAs described [here](https://cmake.org/cmake/help/latest/command/cmake_policy.html#version), this implies a call to `cmake_policy` which enables CMP0118.\n\nUnfortunately this must be done in all (transitive) downstream dependencies that link to the bridge target, so cannot be done from within corrosion automatically.\n"
  },
  {
    "path": "doc/src/ffi_bindings.md",
    "content": "# Integrating Automatically Generated FFI Bindings\n\nThere are a number of tools to automatically generate bindings between Rust and different\nforeign languages.\n\n1. [bindgen](#bindgen)\n2. [cbindgen](#cbindgen-integration)\n3. [cxx](#cxx-integration)\n\n## bindgen\n\n[bindgen] is a tool to automatically generate Rust bindings from C headers.\nAs such, integrating bindgen [via a build-script](https://rust-lang.github.io/rust-bindgen/library-usage.html)\nworks well and their doesn't seem to be a need to create CMake rules for \ngenerating the bindings.\n\n[bindgen]: https://github.com/rust-lang/rust-bindgen\n\n## cbindgen integration\n\n⚠️⚠️⚠️ **EXPERIMENTAL** ⚠️⚠️⚠️\n\n[cbindgen] is a tool that generates C/C++ headers from Rust code. When compiling C/C++\ncode that `#include`s such generated headers the buildsystem must be aware of the dependencies.\nGenerating the headers via a build-script is possible, but Corrosion offers no guidance here.\n\nInstead, Corrosion offers an experimental function to add CMake rules using cbindgen to generate\nthe headers.\nThis is not available on a stable released version yet, and the details are subject to change.\n{{#include ../../cmake/Corrosion.cmake:corrosion_cbindgen}}\n\n## cxx integration\n\n⚠️⚠️⚠️ **EXPERIMENTAL** ⚠️⚠️⚠️\n\n[cxx] is a tool which generates bindings for C++/Rust interop.\n\n{{#include ../../cmake/Corrosion.cmake:corrosion_add_cxxbridge}}\n"
  },
  {
    "path": "doc/src/introduction.md",
    "content": "## About Corrosion\n\nCorrosion, formerly known as cmake-cargo, is a tool for integrating Rust into an existing CMake\nproject. Corrosion is capable of automatically importing executables, static libraries, and\ndynamic libraries from a Rust package or workspace as CMake targets.\n\nThe imported static and dynamic library types can be linked into C/C++ CMake targets using the usual\nCMake functions such as [`target_link_libraries()`].\nFor rust executables and dynamic libraries corrosion provides a `corrosion_link_libraries`\nhelper function to conveniently add the necessary flags to link C/C++ libraries into\nthe rust target.\n\n## Requirements\n\n- The latest release (v0.6) of Corrosion currently requires CMake 3.22 or newer.\n- The previous v0.5 release supports CMake 3.15 or newer. If you are using the v0.5 release, please\n  view [the documentation here](./v0.5/introduction.md). \n\n[`target_link_libraries()`]: https://cmake.org/cmake/help/latest/command/target_link_libraries.html\n"
  },
  {
    "path": "doc/src/quick_start.md",
    "content": "# Quick Start\n\nYou can add corrosion to your project via the `FetchContent` CMake module or one of the other methods\ndescribed in the [Setup chapter](setup_corrosion.md).\nAfterwards you can import Rust targets defined in a `Cargo.toml` manifest file by using\n`corrosion_import_crate`. This will add CMake targets with names matching the crate names defined\nin the Cargo.toml manifest. These targets can then subsequently be used, e.g. to link the imported\ntarget into a regular C/C++ target.\n\nThe example below shows how to add Corrosion to your project via `FetchContent`\nand how to import a rust library and link it into a regular C/C++ CMake target.\n\n```cmake\ninclude(FetchContent)\n\nFetchContent_Declare(\n    Corrosion\n    GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git\n    GIT_TAG v0.6 # Optionally specify a commit hash, version tag or branch here\n)\n# Set any global configuration variables such as `Rust_TOOLCHAIN` before this line!\nFetchContent_MakeAvailable(Corrosion)\n\n# Import targets defined in a package or workspace manifest `Cargo.toml` file\ncorrosion_import_crate(MANIFEST_PATH rust-lib/Cargo.toml)\n\nadd_executable(your_cool_cpp_bin main.cpp)\n\n# In this example the the `Cargo.toml` file passed to `corrosion_import_crate` is assumed to have\n# defined a static (`staticlib`) or shared (`cdylib`) rust library with the name \"rust-lib\".\n# A target with the same name is now available in CMake and you can use it to link the rust library into\n# your C/C++ CMake target(s).\ntarget_link_libraries(your_cool_cpp_bin PUBLIC rust-lib)\n```\n\n\nPlease see the [Usage chapter](usage.md) for a complete discussion of possible configuration options.\n"
  },
  {
    "path": "doc/src/setup_corrosion.md",
    "content": "# Adding Corrosion to your project\n\nThere are two fundamental installation methods that are supported by Corrosion - installation as a\nCMake package or using it as a subdirectory in an existing CMake project. For CMake versions below\n3.19 Corrosion strongly recommends installing the package, either via a package manager or manually\nusing CMake's installation facilities.\nIf you have CMake 3.19 or newer, we recommend to use either the [FetchContent](#fetchcontent) or the \n[Subdirectory](#subdirectory) method to integrate Corrosion.\n\n## FetchContent\nIf you are using CMake >= 3.19 or installation is difficult or not feasible in\nyour environment, you can use the\n[FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) module to include\nCorrosion. This will download Corrosion and use it as if it were a subdirectory at configure time.\n\nIn your CMakeLists.txt:\n```cmake\ninclude(FetchContent)\n\nFetchContent_Declare(\n    Corrosion\n    GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git\n    # v0.6 will be updated to point to the latest patch version. \n    # Use v0.6.<patch_version> or the commit hash to prevent such auto updates.\n    GIT_TAG v0.6\n)\n# Set any global configuration variables such as `Rust_TOOLCHAIN` before this line!\nFetchContent_MakeAvailable(Corrosion)\n```\n\n## Subdirectory\nCorrosion can also be used directly as a subdirectory. This solution may work well for small\nprojects, but it's discouraged for large projects with many dependencies, especially those which may\nthemselves use Corrosion. Either copy the Corrosion library into your source tree, being sure to\npreserve the `LICENSE` file, or add this repository as a git submodule:\n```bash\ngit submodule add https://github.com/corrosion-rs/corrosion.git\n```\n\nFrom there, using Corrosion is easy. In your CMakeLists.txt:\n```cmake\nadd_subdirectory(path/to/corrosion)\n```\n\n## Installation\n\n\nInstallation will pre-build all of Corrosion's native tooling (required only for CMake versions\nbelow 3.19) and install it together with Corrosions CMake files into a standard location.\nOn CMake >= 3.19 installing Corrosion does not offer any speed advantages, unless the native\ntooling option is explicitly enabled.\n\n### Install from source\n\nFirst, download and install Corrosion:\n```bash\ngit clone https://github.com/corrosion-rs/corrosion.git\n# Optionally, specify -DCMAKE_INSTALL_PREFIX=<target-install-path> to specify a \n# custom installation directory\ncmake -Scorrosion -Bbuild -DCMAKE_BUILD_TYPE=Release\ncmake --build build --config Release\n# This next step may require sudo or admin privileges if you're installing to a system location,\n# which is the default.\ncmake --install build --config Release\n```\n\nYou'll want to ensure that the install directory is available in your `PATH` or `CMAKE_PREFIX_PATH`\nenvironment variable. This is likely to already be the case by default on a Unix system, but on\nWindows it will install to `C:\\Program Files (x86)\\Corrosion` by default, which will not be in your\n`PATH` or `CMAKE_PREFIX_PATH` by default.\n\nOnce Corrosion is installed, and you've ensured the package is available in your `PATH`, you\ncan use it from your own project like any other package from your CMakeLists.txt:\n```cmake\nfind_package(Corrosion REQUIRED)\n```\n\n### Package Manager\n\n#### Homebrew (unofficial)\n\nCorrosion is available via Homebrew and can be installed via\n\n```bash\nbrew install corrosion\n```\n\nPlease note that this package is community maintained. Please also keep in mind that Corrosion follows\nsemantic versioning and minor version bumps (i.e. `0.3` -> `0.4`) may contain breaking changes, while \nCorrosion is still pre `1.0`.\nPlease read the release notes when upgrading Corrosion.\n"
  },
  {
    "path": "doc/src/usage.md",
    "content": "## Usage\n\n### Automatically import crate targets with `corrosion_import_crate`\n\nIn order to integrate a Rust crate into CMake, you first need to import Rust crates from\na [package] or [workspace]. Corrosion provides `corrosion_import_crate()` to automatically import\ncrates defined in a Cargo.toml Manifest file:\n\n{{#include ../../cmake/Corrosion.cmake:corrosion-import-crate}}\n\nCorrosion will use `cargo metadata` to add a cmake target for each crate defined in the Manifest file\nand add the necessary rules to build the targets.\nFor Rust executables an [`IMPORTED`] executable target is created with the same name as defined in the `[[bin]]`\nsection of the Manifest corresponding to this target.\nIf no such name was defined the target name defaults to the Rust package name.\nFor Rust library targets an [`INTERFACE`] library target is created with the same name as defined in the `[lib]`\nsection of the Manifest. This `INTERFACE` library links an internal corrosion target, which is either a\n`SHARED` or `STATIC` `IMPORTED` library, depending on the Rust crate type (`cdylib` vs `staticlib`).\n\nThe created library targets can be linked into other CMake targets by simply using [target_link_libraries].\n\nCorrosion will by default copy the produced Rust artifacts into `${CMAKE_CURRENT_BINARY_DIR}`. The target location\ncan be changed by setting the CMake `OUTPUT_DIRECTORY` target properties on the imported Rust targets.\nSee the [OUTPUT_DIRECTORY](#cmake-output_directory-target-properties-and-imported_location) section for more details.\n\nMany of the options available for `corrosion_import_crate` can also be individually set per\ntarget, see [Per Target options](#per-target-options) for details.\n\n[package]: https://doc.rust-lang.org/book/ch07-01-packages-and-crates.html\n[workspace]: https://doc.rust-lang.org/cargo/reference/workspaces.html\n[`IMPORTED`]: https://cmake.org/cmake/help/latest/prop_tgt/IMPORTED.html\n[`INTERFACE`]: https://cmake.org/cmake/help/latest/command/add_library.html#interface-libraries\n[target_link_libraries]: https://cmake.org/cmake/help/latest/command/target_link_libraries.html\n\n### Experimental: Install crate and headers with `corrosion_install`\n\nThe default CMake [install commands] do not work correctly with the targets exported from `corrosion_import_crate()`.\nCorrosion provides `corrosion_install` to automatically install relevant files:\n\n{{#include ../../cmake/Corrosion.cmake:corrosion-install}}\n\nThe example below shows how to import a rust library and make it available for install through CMake.\n\n```cmake\ninclude(FetchContent)\n\nFetchContent_Declare(\n        Corrosion\n        GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git\n        # v0.6 will be updated to point to the latest patch version. \n        # Use v0.6.<patch_version> or the commit hash to prevent such auto updates.\n        GIT_TAG v0.6\n)\n# Set any global configuration variables such as `Rust_TOOLCHAIN` before this line!\nFetchContent_MakeAvailable(Corrosion)\n\n# Import targets defined in a package or workspace manifest `Cargo.toml` file\ncorrosion_import_crate(MANIFEST_PATH rust-lib/Cargo.toml)\n\n# Add a manually written header file which will be exported\n# Requires CMake >=3.23\ntarget_sources(rust-lib INTERFACE\n        FILE_SET HEADERS\n        BASE_DIRS include\n        FILES\n        include/rust-lib/rust-lib.h\n)\n\n# OR for CMake <= 3.23\ntarget_include_directories(is_odd INTERFACE\n        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>\n        $<INSTALL_INTERFACE:include>\n)\ntarget_sources(is_odd\n        INTERFACE\n        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/rust-lib/rust-lib.h>\n        $<INSTALL_INTERFACE:include/rust-lib/rust-lib.h>\n)\n\n# Rust libraries must be installed using `corrosion_install`.\ncorrosion_install(TARGETS rust-lib EXPORT RustLibTargets)\n\n# Installs the main target\ninstall(\n        EXPORT RustLibTargets\n        NAMESPACE RustLib::\n        DESTINATION lib/cmake/RustLib\n)\n\n# Necessary for packaging helper commands\ninclude(CMakePackageConfigHelpers)\n# Create a file for checking version compatibility\n# Optional\nwrite_basic_package_version_file(\n        \"${CMAKE_CURRENT_BINARY_DIR}/RustLibConfigVersion.cmake\"\n        VERSION \"${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}\"\n        COMPATIBILITY AnyNewerVersion\n)\n\n# Configures the main config file that cmake loads\nconfigure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in\n        \"${CMAKE_CURRENT_BINARY_DIR}/RustLibConfig.cmake\"\n        INSTALL_DESTINATION lib/cmake/RustLib\n        NO_SET_AND_CHECK_MACRO\n        NO_CHECK_REQUIRED_COMPONENTS_MACRO\n)\n# Config.cmake.in contains\n# @PACKAGE_INIT@\n# \n# include(${CMAKE_CURRENT_LIST_DIR}/RustLibTargetsCorrosion.cmake)\n# include(${CMAKE_CURRENT_LIST_DIR}/RustLibTargets.cmake)\n\n# Install all generated files\ninstall(FILES\n        ${CMAKE_CURRENT_BINARY_DIR}/RustLibConfigVersion.cmake\n        ${CMAKE_CURRENT_BINARY_DIR}/RustLibConfig.cmake\n        ${CMAKE_CURRENT_BINARY_DIR}/corrosion/RustLibTargetsCorrosion.cmake\n        DESTINATION lib/cmake/RustLib\n)\n```\n\n[install commands]: https://cmake.org/cmake/help/latest/command/install.html\n\n### Per Target options\n\nSome configuration options can be specified individually for each target. You can set them via the\n`corrosion_set_xxx()` functions specified below:\n\n- `corrosion_set_env_vars(<target_name> <key1=value1> [... <keyN=valueN>])`: Define environment variables\n  that should be set during the invocation of `cargo build` for the specified target. Please note that\n  the environment variable will only be set for direct builds of the target via cmake, and not for any\n  build where cargo built the crate in question as a dependency for another target.\n  The environment variables may contain generator expressions.\n- `corrosion_add_target_rustflags(<target_name> <rustflag> [... <rustflagN>])`: When building the target,\n  the `RUSTFLAGS` environment variable will contain the flags added via this function. Please note that any\n  dependencies (built by cargo) will also see these flags. See also: `corrosion_add_target_local_rustflags`.\n- `corrosion_add_target_local_rustflags(target_name rustc_flag [more_flags ...])`: Support setting\n  rustflags for only the main target (crate) and none of its dependencies.\n  This is useful in cases where you only need rustflags on the main-crate, but need to set different\n  flags for different targets. Without \"local\" Rustflags this would require rebuilds of the\n  dependencies when switching targets.\n- `corrosion_set_hostbuild(<target_name>)`: The target should be compiled for the Host target and ignore any\n  cross-compile configuration.\n- `corrosion_set_features(<target_name> [ALL_FEATURES <Bool>] [NO_DEFAULT_FEATURES] [FEATURES <feature1> ... ])`:\n  For a given target, enable specific features via `FEATURES`, toggle `ALL_FEATURES` on or off or disable all features\n  via `NO_DEFAULT_FEATURES`. For more information on features, please see also the\n  [cargo reference](https://doc.rust-lang.org/cargo/reference/features.html).\n- `corrosion_set_cargo_flags(<target_name> <flag1> ...])`:\n  For a given target, add options and flags at the end of `cargo build` invocation. This will be appended after any\n  arguments passed through the `FLAGS` during the crate import.\n- `corrosion_set_linker(target_name linker)`: Use `linker` to link the target.\n  Please note that this only has an effect for targets where the final linker invocation is done\n  by cargo, i.e. targets where foreign code is linked into rust code and not the other way around.\n  Please also note that if you are cross-compiling and specify a linker such as `clang`, you are\n  responsible for also adding a rustflag which adds the necessary `--target=` argument for the\n  linker.\n\n\n### Global Corrosion Options\n\n#### Selecting the Rust toolchain and target triple\n\nThe following variables are evaluated automatically in most cases. In typical cases you\nshouldn't need to alter any of these. If you do want to specify them manually, make sure to set\nthem **before** `find_package(Corrosion REQUIRED)`.\n\n- `Rust_TOOLCHAIN:STRING` - Specify a named rustup toolchain to use. Changes to this variable\n  resets all other options. Default: If the first-found `rustc` is a `rustup` proxy, then the default\n  rustup toolchain (see `rustup show`) is used. Otherwise, the variable is unset by default.\n- `Rust_COMPILER:STRING` - Path to `rustc`, which should be used for compiling or for toolchain\n  detection (if it is a `rustup` proxy). Default: The `rustc` in the first-found toolchain, either\n  from `rustup`, or from a toolchain available in the user's `PATH`.\n- `Rust_RESOLVE_RUSTUP_TOOLCHAINS:BOOL` - If the found `rustc` is a `rustup` proxy, resolve a\n  concrete path to a specific toolchain managed by `rustup`, according to the `rustup` toolchain\n  selection rules and other options detailed here. If this option is turned off, the found `rustc`\n  will be used as-is to compile, even if it is a `rustup` proxy, which might increase compilation\n  time. Default: `ON` if the found `rustc` is a rustup proxy or a `rustup` managed toolchain was\n  requested, `OFF` otherwise. Forced `OFF` if `rustup` was not found.\n- `Rust_CARGO:STRING` - Path to `cargo`. Default: the `cargo` installed next to `${Rust_COMPILER}`.\n- `Rust_CARGO_TARGET:STRING` - The default target triple to build for. Alter for cross-compiling.\n  Default: On Visual Studio Generator, the matching triple for `CMAKE_VS_PLATFORM_NAME`. Otherwise,\n  the default target triple reported by `${Rust_COMPILER} --version --verbose`.\n- `CORROSION_TOOLS_RUST_TOOLCHAIN:STRING`: Specify a different toolchain (e.g. `stable`) to use for compiling helper \n   tools such as `cbindgen` or `cxxbridge`. This can be useful when you want to compile your project with an \n   older rust version (e.g. for checking the MSRV), but you can build build-tools with a newer installed rust version.\n- `CORROSION_HOST_TARGET_LINKER`: This cache variable is currently **only used when targeting iOS** and allows the user\n    to select a linker-driver (e.g. `/usr/bin/cc`) for linking artifacts for the host target. This option is useful\n   when the build contains build-scripts or proc-macros (which run on the host target) and the default value is not\n   working.\n\n\n#### Enable Convenience Options\n\nThe following options are off by default, but may increase convenience:\n\n- `Rust_RUSTUP_INSTALL_MISSING_TARGET:BOOL`: Automatically install a missing target via `rustup` instead of failing.\n\n\n#### Developer/Maintainer Options\nThese options are not used in the course of normal Corrosion usage, but are used to configure how\nCorrosion is built and installed. Only applies to Corrosion builds and subdirectory uses.\n\n- `CORROSION_BUILD_TESTS:BOOL` - Build the Corrosion tests. Default: `Off` if Corrosion is a\n  subdirectory, `ON` if it is the top-level project\n\n\n### Information provided by Corrosion\n\nFor your convenience, Corrosion sets a number of variables which contain information about the version of the rust\ntoolchain. You can use the CMake version comparison operators\n(e.g. [`VERSION_GREATER_EQUAL`](https://cmake.org/cmake/help/latest/command/if.html#version-comparisons)) on the main\nvariable (e.g. `if(Rust_VERSION VERSION_GREATER_EQUAL \"1.57.0\")`), or you can inspect the major, minor and patch\nversions individually.\n- `Rust_VERSION<_MAJOR|_MINOR|_PATCH>` - The version of rustc.\n- `Rust_CARGO_VERSION<_MAJOR|_MINOR|_PATCH>` - The cargo version.\n- `Rust_LLVM_VERSION<_MAJOR|_MINOR|_PATCH>` - The LLVM version used by rustc.\n- `Rust_IS_NIGHTLY` - 1 if a nightly toolchain is used, otherwise 0. Useful for selecting an unstable feature for a\n  crate, that is only available on nightly toolchains.\n- `Rust_RUSTUP_TOOLCHAINS`, `Rust_RUSTUP_TOOLCHAINS_RUSTC_PATH`, `Rust_RUSTUP_TOOLCHAINS_CARGO_PATH`\n  and `Rust_RUSTUP_TOOLCHAINS_VERSION`: These variables are lists, which should be iterated over with\n  CMakes `foreach(var IN ZIP_LISTS list1 list2 ...)` iterator. They provide a list of installed rustup managed toolchains and\n  the associated rustc and cargo paths as well as the corresponding rustc version.\n- Cache variables containing information based on the target triple for the selected target\n  as well as the default host target:\n  - `Rust_CARGO_TARGET_ARCH`, `Rust_CARGO_HOST_ARCH`: e.g. `x86_64` or `aarch64`\n  - `Rust_CARGO_TARGET_VENDOR`, `Rust_CARGO_HOST_VENDOR`: e.g. `apple`, `pc`, `unknown` etc.\n  - `Rust_CARGO_TARGET_OS`, `Rust_CARGO_HOST_OS`:  e.g. `darwin`, `linux`, `windows`, `none`\n  - `Rust_CARGO_TARGET_ENV`, `Rust_CARGO_HOST_ENV`: e.g. `gnu`, `musl`\n\n\n\n\n### Selecting a custom cargo profile\n\n[Rust 1.57](https://blog.rust-lang.org/2021/12/02/Rust-1.57.0.html) stabilized the support for custom\n[profiles](https://doc.rust-lang.org/cargo/reference/profiles.html). If you are using a sufficiently new rust toolchain,\nyou may select a custom profile by adding the optional argument `PROFILE <profile_name>` to\n`corrosion_import_crate()`. If you do not specify a profile, or you use an older toolchain, corrosion will select\nthe standard `dev` profile if the CMake config is either `Debug` or unspecified. In all other cases the `release`\nprofile is chosen for cargo.\n\n### Importing C-Style Libraries Written in Rust\nCorrosion makes it completely trivial to import a crate into an existing CMake project. Consider\na project called [rust2cpp](test/rust2cpp/rust2cpp) with the following file structure:\n```\nrust2cpp/\n    rust/\n        src/\n            lib.rs\n        Cargo.lock\n        Cargo.toml\n    CMakeLists.txt\n    main.cpp\n```\n\nThis project defines a simple Rust lib crate, like so, in [`rust2cpp/rust/Cargo.toml`](test/rust2cpp/rust2cpp/rust/Cargo.toml):\n```toml\n[package]\nname = \"rust-lib\"\nversion = \"0.1.0\"\nauthors = [\"Andrew Gaspar <andrew.gaspar@outlook.com>\"]\nlicense = \"MIT\"\nedition = \"2018\"\n\n[dependencies]\n\n[lib]\ncrate-type=[\"staticlib\"]\n```\n\nIn addition to `\"staticlib\"`, you can also use `\"cdylib\"`. In fact, you can define both with a\nsingle crate and switch between which is used using the standard\n[`BUILD_SHARED_LIBS`](https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html) variable.\n\nThis crate defines a simple crate called `rust-lib`. Importing this crate into your\n[CMakeLists.txt](test/rust2cpp/CMakeLists.txt) is trivial:\n```cmake\n# Note: you must have already included Corrosion for `corrosion_import_crate` to be available. See # the `Installation` section above.\n\ncorrosion_import_crate(MANIFEST_PATH rust/Cargo.toml)\n```\n\nNow that you've imported the crate into CMake, all of the executables, static libraries, and dynamic\nlibraries defined in the Rust can be directly referenced. So, merely define your C++ executable as\nnormal in CMake and add your crate's library using target_link_libraries:\n```cmake\nadd_executable(cpp-exe main.cpp)\ntarget_link_libraries(cpp-exe PUBLIC rust-lib)\n```\n\nThat's it! You're now linking your Rust library to your C++ library.\n\n#### Generate Bindings to Rust Library Automatically\n\nCurrently, you must manually declare bindings in your C or C++ program to the exported routines and\ntypes in your Rust project. You can see boths sides of this in\n[the Rust code](test/rust2cpp/rust2cpp/rust/src/lib.rs) and in [the C++ code](test/rust2cpp/rust2cpp/main.cpp).\n\nIntegration with [cbindgen](https://github.com/eqrion/cbindgen) is\nplanned for the future.\n\n### Importing Libraries Written in C and C++ Into Rust\n\nThe rust targets can be imported with `corrosion_import_crate()` into CMake.\nFor targets where the linker should be invoked by Rust corrosion provides\n`corrosion_link_libraries()` to link your C/C++ libraries with the Rust target.\nFor additional linker flags you may use `corrosion_add_target_local_rustflags()`\nand pass linker arguments via the `-Clink-args` flag to rustc. These flags will\nonly be passed to the final rustc invocation and not affect any rust dependencies.\n\nC bindings can be generated via [bindgen](https://github.com/rust-lang/rust-bindgen).\nCorrosion does not offer any direct integration yet, but you can either generate the\nbindings in the build-script of your crate, or generate the bindings as a CMake build step\n(e.g. a custom target) and add a dependency from `cargo-prebuild_<rust_target>` to your\ncustom target for generating the bindings.\n\nExample:\n\n```cmake\n# Import your Rust targets\ncorrosion_import_crate(MANIFEST_PATH rust/Cargo.toml)\n# Link C/C++ libraries with your Rust target\ncorrosion_link_libraries(target_name c_library)\n# Optionally explicitly define which linker to use.\ncorrosion_set_linker(target_name your_custom_linker)\n# Optionally set linker arguments\ncorrosion_add_target_local_rustflags(target_name \"-Clink-args=<linker arguments>\")\n# Optionally tell CMake that the rust crate depends on another target (e.g. a code generator)\nadd_dependencies(cargo-prebuild_<target_name> custom_bindings_target)\n```\n\n### Cross Compiling\nCorrosion attempts to support cross-compiling as generally as possible, though not all\nconfigurations are tested. Cross-compiling is explicitly supported in the following scenarios.\n\nIn all cases, you will need to install the standard library for the Rust target triple. When using\nRustup, you can use it to install the target standard library:\n\n```bash\nrustup target add <target-rust-triple>\n```\n\nIf the target triple is automatically derived, Corrosion will print the target during configuration.\nFor example:\n\n```\n-- Rust Target: aarch64-linux-android\n```\n\n#### Windows-to-Windows\nCorrosion supports cross-compiling between arbitrary Windows architectures using the Visual Studio\nGenerator. For example, to cross-compile for ARM64 from any platform, simply set the `-A`\narchitecture flag:\n\n```bash\ncmake -S. -Bbuild-arm64 -A ARM64\ncmake --build build-arm64\n```\n\nPlease note that for projects containing a build-script at least Rust 1.54 is required due to a bug\nin previous cargo versions, which causes the build-script to incorrectly be built for the target\nplatform.\n\n#### Linux-to-Linux\nIn order to cross-compile on Linux, you will need to install a cross-compiler. For example, on\nUbuntu, to cross compile for 64-bit Little-Endian PowerPC Little-Endian, install\n`g++-powerpc64le-linux-gnu` from apt-get:\n\n```bash\nsudo apt install g++-powerpc64le-linux-gnu\n```\n\nCurrently, Corrosion does not automatically determine the target triple while cross-compiling on\nLinux, so you'll need to specify a matching `Rust_CARGO_TARGET`.\n\n```bash\ncmake -S. -Bbuild-ppc64le -DRust_CARGO_TARGET=powerpc64le-unknown-linux-gnu -DCMAKE_CXX_COMPILER=powerpc64le-linux-gnu-g++\ncmake --build build-ppc64le\n```\n\n#### Android\n\nCross-compiling for Android is supported on all platforms with the Makefile and Ninja generators,\nand the Rust target triple will automatically be selected. The CMake\n[cross-compiling instructions for Android](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-android)\napply here. For example, to build for ARM64:\n\n```bash\ncmake -S. -Bbuild-android-arm64 -GNinja -DCMAKE_SYSTEM_NAME=Android \\\n      -DCMAKE_ANDROID_NDK=/path/to/android-ndk-rxxd -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a\n```\n\n**Important note:** The Android SDK ships with CMake 3.10 at newest, which Android Studio will\nprefer over any CMake you've installed locally. CMake 3.10 is insufficient for using Corrosion,\nwhich requires a minimum of CMake 3.22. If you're using Android Studio to build your project,\nfollow the instructions in the Android Studio documentation for\n[using a specific version of CMake](https://developer.android.com/studio/projects/install-ndk#vanilla_cmake).\n\n\n### CMake `OUTPUT_DIRECTORY` target properties and `IMPORTED_LOCATION`\n\nCorrosion respects the following `OUTPUT_DIRECTORY` target properties:\n-   [ARCHIVE_OUTPUT_DIRECTORY](https://cmake.org/cmake/help/latest/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY.html)\n-   [LIBRARY_OUTPUT_DIRECTORY](https://cmake.org/cmake/help/latest/prop_tgt/LIBRARY_OUTPUT_DIRECTORY.html)\n-   [RUNTIME_OUTPUT_DIRECTORY](https://cmake.org/cmake/help/latest/prop_tgt/RUNTIME_OUTPUT_DIRECTORY.html)\n-   [PDB_OUTPUT_DIRECTORY](https://cmake.org/cmake/help/latest/prop_tgt/PDB_OUTPUT_DIRECTORY.html)\n\nIf the target property is set (e.g. by defining the `CMAKE_XYZ_OUTPUT_DIRECTORY` variable before calling\n`corrosion_import_crate()`), corrosion will copy the built rust artifacts to the location defined in the\ntarget property.\nDue to limitations in CMake these target properties are evaluated in a deferred manner, to\nsupport the user setting the target properties after the call to `corrosion_import_crate()`.\nThis has the side effect that the `IMPORTED_LOCATION` property will be set late, and users should not\nuse `get_property` to read `IMPORTED_LOCATION` at configure time. Instead, generator expressions\nshould be used to get the location of the target artifact.\nIf `IMPORTED_LOCATION` is needed at configure time users may use `cmake_language(DEFER CALL ...)` to defer\nevaluation to after the `IMPORTED_LOCATION` property is set.\n"
  },
  {
    "path": "test/CMakeLists.txt",
    "content": "# This option is currently used to prevent recursion\noption(CORROSION_TESTS \"Enable Corrosion tests\" ON)\nmark_as_advanced(CORROSION_TESTS)\nif(NOT CORROSION_TESTS)\n    return()\nendif()\n\noption(CORROSION_TESTS_CXXBRIDGE\n        \"Build cxxbridge tests which requires cxxbridge executable being available\"\n        OFF)\noption(CORROSION_TESTS_KEEP_BUILDDIRS\n    \"By default corrosion tests will cleanup after themselves. This option limits the cleaning up to the\n     target directories and will keep the build directories, which may be useful for caching.\"\n    OFF)\nmark_as_advanced(CORROSION_TESTS_NO_CLEANUP)\n\nset(test_install_path \"${CMAKE_CURRENT_BINARY_DIR}/test-install-corrosion\")\nfile(REAL_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/..\" corrosion_source_dir)\nset(test_header_contents\n        \"option(CORROSION_TESTS_FIND_CORROSION \\\"Use Corrosion as a subdirectory\\\" OFF)\"\n        \"if (CORROSION_TESTS_FIND_CORROSION)\"\n        \"    set(CMAKE_PREFIX_PATH \\\"${test_install_path}\\\" CACHE INTERNAL \\\"\\\" FORCE)\"\n        \"    find_package(Corrosion REQUIRED PATHS \\\"${test_install_path}\\\" NO_CMAKE_SYSTEM_PATH)\"\n        \"else()\"\n        \"    add_subdirectory(\\\"${corrosion_source_dir}\\\" corrosion)\"\n        \"endif()\"\n)\n\nstring(REPLACE \";\" \"\\n\" test_header_contents \"${test_header_contents}\")\n\nfile(WRITE test_header.cmake \"${test_header_contents}\")\n\noption(CORROSION_TESTS_INSTALL_CORROSION\n        \"Install Corrosion to a test directory and let tests use the installed Corrosion\"\n        OFF)\nif(CORROSION_TESTS_INSTALL_CORROSION)\n    add_test(NAME \"install_corrosion_configure\"\n        COMMAND\n            ${CMAKE_COMMAND}\n            -S \"${CMAKE_CURRENT_SOURCE_DIR}/..\"\n            -B \"${CMAKE_CURRENT_BINARY_DIR}/build-corrosion\"\n            -DCORROSION_VERBOSE_OUTPUT=ON\n            -DCORROSION_TESTS=OFF\n            -DCMAKE_BUILD_TYPE=Release\n            -G${CMAKE_GENERATOR}\n            \"-DCMAKE_INSTALL_PREFIX=${test_install_path}\"\n    )\n    add_test(NAME \"install_corrosion_build\"\n            COMMAND\n            ${CMAKE_COMMAND} --build \"${CMAKE_CURRENT_BINARY_DIR}/build-corrosion\" --config Release\n            )\n    add_test(NAME \"install_corrosion_install\"\n            COMMAND\n            ${CMAKE_COMMAND} --install \"${CMAKE_CURRENT_BINARY_DIR}/build-corrosion\" --config Release\n        )\n    set_tests_properties(\"install_corrosion_configure\" PROPERTIES FIXTURES_SETUP \"fixture_corrosion_configure\")\n    set_tests_properties(\"install_corrosion_build\"     PROPERTIES FIXTURES_SETUP \"fixture_corrosion_build\")\n    set_tests_properties(\"install_corrosion_build\"     PROPERTIES FIXTURES_REQUIRED \"fixture_corrosion_configure\")\n    set_tests_properties(\"install_corrosion_install\"   PROPERTIES FIXTURES_REQUIRED \"fixture_corrosion_build\")\n    set_tests_properties(\"install_corrosion_install\"   PROPERTIES FIXTURES_SETUP \"fixture_corrosion_install\")\n\n    add_test(NAME \"install_corrosion_build_cleanup\" COMMAND \"${CMAKE_COMMAND}\" -E remove_directory \"${CMAKE_CURRENT_BINARY_DIR}/build-corrosion\")\n    set_tests_properties(\"install_corrosion_build_cleanup\" PROPERTIES\n        FIXTURES_CLEANUP\n        \"fixture_corrosion_configure;fixture_corrosion_build\"\n    )\n\n    add_test(NAME \"install_corrosion_cleanup\" COMMAND \"${CMAKE_COMMAND}\" -E remove_directory \"${test_install_path}\")\n    set_tests_properties(\"install_corrosion_cleanup\" PROPERTIES\n        FIXTURES_CLEANUP\n        \"fixture_corrosion_configure;fixture_corrosion_build;fixture_corrosion_install\"\n    )\nendif()\n\nfunction(corrosion_tests_add_test test_name bin_names)\n    set(options \"IS_HOSTBUILD\")\n    set(one_value_kewords \"TEST_SRC_DIR\")\n    set(multi_value_keywords \"\")\n    cmake_parse_arguments(PARSE_ARGV 2 TST \"${options}\" \"${one_value_kewords}\" \"${multi_value_keywords}\")\n    set(pass_through_arguments \"${TST_UNPARSED_ARGUMENTS}\")\n\n# In the future we could add multiple tests here for different configurations (generator, build mode, rust version ...)\n# which would allow us to simplify the github job matrix\n    if(TST_TEST_SRC_DIR)\n        set(test_dir \"${TST_TEST_SRC_DIR}\")\n    else()\n        set(test_dir \"${test_name}\")\n    endif()\n\n    set(configure_cmake_args)\n    if(CMAKE_C_COMPILER)\n        list(APPEND configure_cmake_args \"C_COMPILER\" \"${CMAKE_C_COMPILER}\")\n    endif()\n    if(CMAKE_CXX_COMPILER)\n        list(APPEND configure_cmake_args \"CXX_COMPILER\" \"${CMAKE_CXX_COMPILER}\")\n    endif()\n    if(CMAKE_C_COMPILER_TARGET)\n        list(APPEND configure_cmake_args \"C_COMPILER_TARGET\" \"${CMAKE_C_COMPILER_TARGET}\")\n    endif()\n    if(CMAKE_CXX_COMPILER_TARGET)\n        list(APPEND configure_cmake_args \"CXX_COMPILER_TARGET\" \"${CMAKE_CXX_COMPILER_TARGET}\")\n    endif()\n    if(CMAKE_GENERATOR_PLATFORM)\n        list(APPEND configure_cmake_args \"GENERATOR_PLATFORM\" \"${CMAKE_GENERATOR_PLATFORM}\")\n    endif()\n    if(CMAKE_CROSSCOMPILING)\n        list(APPEND configure_cmake_args SYSTEM_NAME \"${CMAKE_SYSTEM_NAME}\")\n    endif()\n    if(CMAKE_OSX_ARCHITECTURES)\n        list(APPEND configure_cmake_args OSX_ARCHITECTURES \"${CMAKE_OSX_ARCHITECTURES}\")\n    endif()\n    if(CMAKE_OSX_SYSROOT)\n        list(APPEND configure_cmake_args OSX_SYSROOT \"${CMAKE_OSX_SYSROOT}\")\n    endif()\n    if(CMAKE_TOOLCHAIN_FILE)\n        list(APPEND configure_cmake_args TOOLCHAIN_FILE \"${CMAKE_TOOLCHAIN_FILE}\")\n    endif()\n\n    add_test(NAME \"${test_name}_build\"\n            COMMAND\n            ${CMAKE_COMMAND}\n            -P \"${CMAKE_SOURCE_DIR}/test/ConfigureAndBuild.cmake\"\n            SOURCE_DIR \"${CMAKE_CURRENT_LIST_DIR}/${test_dir}\"\n            BINARY_DIR \"${CMAKE_CURRENT_BINARY_DIR}/build-${test_name}\"\n            GENERATOR \"${CMAKE_GENERATOR}\"\n            RUST_TOOLCHAIN \"${Rust_TOOLCHAIN}\"\n            CARGO_TARGET \"${Rust_CARGO_TARGET}\"\n            ${configure_cmake_args}\n            ${pass_through_arguments}\n\n            COMMAND_EXPAND_LISTS\n            )\n    set_tests_properties(\"${test_name}_build\" PROPERTIES FIXTURES_SETUP \"build_fixture_${test_name}\")\n    if(CORROSION_TESTS_INSTALL_CORROSION)\n        set_tests_properties(\"${test_name}_build\" PROPERTIES FIXTURES_REQUIRED \"fixture_corrosion_install\")\n    endif()\n    foreach(bin ${bin_names})\n        if(WIN32)\n            set(bin_filename \"${bin}.exe\")\n        else()\n            set(bin_filename \"${bin}\")\n        endif()\n        add_test(NAME \"${test_name}_run_${bin}\" COMMAND \"${CMAKE_CURRENT_BINARY_DIR}/build-${test_name}/${bin_filename}\")\n        set_tests_properties(\"${test_name}_run_${bin}\" PROPERTIES FIXTURES_REQUIRED \"build_fixture_${test_name}\")\n        # CMAKE_CROSSCOMPILING is not set when cross-compiling with VS (via -A flag).\n        # Todo: We could run x86 binaries on x64 hosts.\n        if((CMAKE_CROSSCOMPILING OR CMAKE_VS_PLATFORM_NAME) AND NOT \"${TST_IS_HOSTBUILD}\")\n            # Todo: In the future we could potentially run some tests with qemu.\n            set_tests_properties(\"${test_name}_run_${bin}\" PROPERTIES DISABLED TRUE)\n        endif()\n    endforeach()\n\n    if(CORROSION_TESTS_KEEP_BUILDDIRS)\n        add_test(NAME \"${test_name}_cleanup_artifacts\"\n            COMMAND \"${CMAKE_COMMAND}\" --build \"${CMAKE_CURRENT_BINARY_DIR}/build-${test_name}\" --target clean\n        )\n        add_test(NAME \"${test_name}_cleanup_cargo\"\n            COMMAND \"${CMAKE_COMMAND}\" -E remove_directory \"${CMAKE_CURRENT_BINARY_DIR}/build-${test_name}/cargo\"\n            )\n        set_tests_properties(\"${test_name}_cleanup_artifacts\" PROPERTIES FIXTURES_CLEANUP \"build_fixture_${test_name}\")\n        set_tests_properties(\"${test_name}_cleanup_cargo\" PROPERTIES FIXTURES_CLEANUP \"build_fixture_${test_name}\")\n    else()\n        add_test(NAME \"${test_name}_cleanup\" COMMAND \"${CMAKE_COMMAND}\" -E remove_directory \"${CMAKE_CURRENT_BINARY_DIR}/build-${test_name}\")\n        set_tests_properties(\"${test_name}_cleanup\" PROPERTIES FIXTURES_CLEANUP \"build_fixture_${test_name}\")\n    endif()\nendfunction()\n\n# Please keep this in alphabetical order.\nadd_subdirectory(config_discovery)\nadd_subdirectory(cargo_flags)\nadd_subdirectory(cpp2rust)\nif(Rust_VERSION VERSION_GREATER_EQUAL \"1.64.0\")\n    # Flag `--crate-type` is only supported since Rust 1.64.0\n    add_subdirectory(crate_type)\n    add_subdirectory(override_crate_type)\nendif()\nadd_subdirectory(custom_profiles)\nif(NOT Rust_CROSSCOMPILING AND Rust_VERSION VERSION_GREATER_EQUAL \"1.60.0\")\n    add_subdirectory(custom_target)\nendif()\nadd_subdirectory(cbindgen)\nadd_subdirectory(corrosion_install)\nadd_subdirectory(cxxbridge)\nadd_subdirectory(envvar)\nadd_subdirectory(features)\nadd_subdirectory(find_rust)\nadd_subdirectory(gensource)\nadd_subdirectory(hostbuild)\nadd_subdirectory(multitarget)\nadd_subdirectory(nostd)\nadd_subdirectory(\"output directory\")\nadd_subdirectory(parse_target_triple)\nadd_subdirectory(rust2cpp)\nadd_subdirectory(rustflags)\nadd_subdirectory(workspace)\n"
  },
  {
    "path": "test/ConfigureAndBuild.cmake",
    "content": "# CMake script to configure and build a test project\n\nset(TEST_ARG_LIST)\n\n# Expect actual arguments to start at index 3 (cmake -P <script_name>)\nforeach(ARG_INDEX RANGE 3 ${CMAKE_ARGC})\n    list(APPEND TEST_ARG_LIST \"${CMAKE_ARGV${ARG_INDEX}}\")\nendforeach()\n\nset(options \"USE_INSTALLED_CORROSION\")\nset(oneValueArgs\n    SOURCE_DIR\n    BINARY_DIR\n    GENERATOR\n    GENERATOR_PLATFORM\n    RUST_TOOLCHAIN\n    CARGO_TARGET\n    C_COMPILER\n    CXX_COMPILER\n    C_COMPILER_TARGET\n    CXX_COMPILER_TARGET\n    SYSTEM_NAME\n    CARGO_PROFILE\n    OSX_ARCHITECTURES\n    OSX_SYSROOT\n    TOOLCHAIN_FILE\n)\nset(multiValueArgs \"PASS_THROUGH_ARGS\")\ncmake_parse_arguments(TEST \"${options}\" \"${oneValueArgs}\"\n                      \"${multiValueArgs}\" ${TEST_ARG_LIST} )\n\nset(configure_args \"\")\nif(TEST_CARGO_TARGET)\n    list(APPEND configure_args \"-DRust_CARGO_TARGET=${TEST_CARGO_TARGET}\")\nendif()\nif(TEST_USE_INSTALLED_CORROSION)\n    list(APPEND configure_args \"-DCORROSION_TESTS_FIND_CORROSION=ON\")\nendif()\nif(TEST_GENERATOR_PLATFORM)\n    list(APPEND configure_args \"-A${TEST_GENERATOR_PLATFORM}\")\nendif()\nif(TEST_C_COMPILER)\n    list(APPEND configure_args \"-DCMAKE_C_COMPILER=${TEST_C_COMPILER}\")\nendif()\nif(TEST_CXX_COMPILER)\n    list(APPEND configure_args \"-DCMAKE_CXX_COMPILER=${TEST_CXX_COMPILER}\")\nendif()\nif(TEST_C_COMPILER_TARGET)\n    list(APPEND configure_args \"-DCMAKE_C_COMPILER_TARGET=${TEST_C_COMPILER_TARGET}\")\nendif()\nif(TEST_CXX_COMPILER_TARGET)\n    list(APPEND configure_args \"-DCMAKE_CXX_COMPILER_TARGET=${TEST_CXX_COMPILER_TARGET}\")\nendif()\nif(TEST_SYSTEM_NAME)\n    list(APPEND configure_args \"-DCMAKE_SYSTEM_NAME=${TEST_SYSTEM_NAME}\")\nendif()\nif(TEST_OSX_ARCHITECTURES)\n    list(APPEND configure_args \"-DCMAKE_OSX_ARCHITECTURES=${TEST_OSX_ARCHITECTURES}\")\nendif()\nif(TEST_OSX_SYSROOT)\n    list(APPEND configure_args \"-DCMAKE_OSX_SYSROOT=${TEST_OSX_SYSROOT}\")\nendif()\nif(TEST_TOOLCHAIN_FILE)\n    list(APPEND configure_args \"-DCMAKE_TOOLCHAIN_FILE=${TEST_TOOLCHAIN_FILE}\")\nendif()\nif(TEST_CARGO_PROFILE)\n    list(APPEND configure_args \"-DCARGO_PROFILE=${TEST_CARGO_PROFILE}\")\nendif()\n\n# Remove old binary directory\nfile(REMOVE_RECURSE \"${TEST_BINARY_DIR}\")\n\nfile(MAKE_DIRECTORY \"${TEST_BINARY_DIR}\")\n\nmessage(STATUS \"TEST_BINARY_DIRECTORY: ${TEST_BINARY_DIR}\")\n\nexecute_process(\n    COMMAND\n        \"${CMAKE_COMMAND}\"\n            \"-G${TEST_GENERATOR}\"\n            \"-DRust_TOOLCHAIN=${TEST_RUST_TOOLCHAIN}\"\n            --log-level Debug\n            ${configure_args}\n            ${TEST_PASS_THROUGH_ARGS}\n            -S \"${TEST_SOURCE_DIR}\"\n            -B \"${TEST_BINARY_DIR}\"\n        COMMAND_ECHO STDOUT\n        RESULT_VARIABLE EXIT_CODE\n)\n\nif (NOT \"${EXIT_CODE}\" EQUAL 0)\n    message(FATAL_ERROR \"Configure step failed. Exit code: `${EXIT_CODE}`\")\nendif()\n\nif (\"${TEST_GENERATOR}\" STREQUAL \"Ninja Multi-Config\"\n        OR \"${TEST_GENERATOR}\" MATCHES \"Visual Studio\"\n    )\n    foreach(config Debug Release RelWithDebInfo)\n        execute_process(\n                COMMAND \"${CMAKE_COMMAND}\"\n                    --build \"${TEST_BINARY_DIR}\"\n                    --config \"${config}\"\n                COMMAND_ECHO STDOUT\n                RESULT_VARIABLE EXIT_CODE\n        )\n        if (NOT \"${EXIT_CODE}\" EQUAL 0)\n            message(FATAL_ERROR \"Build step failed for config `${config}`. \"\n                    \"Exit code: `${EXIT_CODE}`\")\n        endif()\n    endforeach()\nelse()\n    execute_process(\n            COMMAND \"${CMAKE_COMMAND}\" --build \"${TEST_BINARY_DIR}\"\n            COMMAND_ECHO STDOUT\n            RESULT_VARIABLE EXIT_CODE\n    )\n    if (NOT \"${EXIT_CODE}\" EQUAL 0)\n        message(FATAL_ERROR \"Build step failed. Exit code: `${EXIT_CODE}`\")\n    endif()\nendif()\n\n\n"
  },
  {
    "path": "test/README.md",
    "content": "# Corrosion Tests\n\nCorrosions tests are run via ctest. The tests themselves utilize CMake script mode\nto configure and build a test project, which allows for great flexibility.\nUsing ctest properties such as `PASS_REGULAR_EXPRESSION` or `FAIL_REGULAR_EXPRESSION`\ncan be used to confirm that built executable targets run as expected, but can also\nbe used to fail tests if Corrosion warnings appear in the configure output."
  },
  {
    "path": "test/TestFileExists.cmake",
    "content": "# CMake script to test if a file exists. Errors if the file does not exist.\n# Expect actual arguments to start at index 3 (cmake -P <script_name>)\n\n# Expect one argument\nif(NOT (CMAKE_ARGC EQUAL \"4\"))\n    message(FATAL_ERROR \"Test Internal Error: Unexpected ARGC Value: ${CMAKE_ARGC}.\")\nendif()\n\nset(FILE_PATH \"${CMAKE_ARGV3}\")\n\nif(NOT ( EXISTS \"${FILE_PATH}\" ))\n    set(error_details \"File `${FILE_PATH}` does not exist!\\n\")\n    set(PARENT_TREE \"${FILE_PATH}\")\n    cmake_path(HAS_PARENT_PATH PARENT_TREE has_parent)\n    while(has_parent)\n        cmake_path(GET PARENT_TREE PARENT_PATH PARENT_TREE)\n        cmake_path(HAS_PARENT_PATH PARENT_TREE has_parent)\n        if(EXISTS \"${PARENT_TREE}\")\n            file(GLOB dir_contents LIST_DIRECTORIES true \"${PARENT_TREE}/*\")\n            list(APPEND error_details \"Found Parent directory `${PARENT_TREE}` exists and contains:\\n\" ${dir_contents})\n            break()\n        else()\n            list(APPEND error_details \"Parent directory `${PARENT_TREE}` also does not exist!\")\n        endif()\n    endwhile()\n    message(FATAL_ERROR \"Test failed: ${error_details}\")\nendif()\n"
  },
  {
    "path": "test/cargo_flags/CMakeLists.txt",
    "content": "corrosion_tests_add_test(cargo_flags \"flags-exe\")\n\nset_tests_properties(\"cargo_flags_run_flags-exe\" PROPERTIES PASS_REGULAR_EXPRESSION [[Hello, Cxx! I am Rust!]])\n"
  },
  {
    "path": "test/cargo_flags/cargo_flags/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\ncorrosion_import_crate(MANIFEST_PATH rust/Cargo.toml FLAGS --features one)\n\nadd_executable(flags-exe main.cpp)\ntarget_link_libraries(flags-exe PUBLIC flags_lib)\ncorrosion_set_cargo_flags(flags_lib --features two)\ncorrosion_set_cargo_flags(flags_lib $<TARGET_PROPERTY:flags_lib,more_flags>)\n\nset_property(\n    TARGET flags_lib\n    APPEND\n    PROPERTY more_flags --features three\n)\n"
  },
  {
    "path": "test/cargo_flags/cargo_flags/main.cpp",
    "content": "extern \"C\" void rust_function(char const *name);\n\n\nint main(int argc, char **argv) {\n        rust_function(\"Cxx\");\n}\n"
  },
  {
    "path": "test/cargo_flags/cargo_flags/rust/Cargo.toml",
    "content": "[package]\nname = \"flags-lib\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n[lib]\ncrate-type=[\"staticlib\"]\n\n[features]\n\none = []\ntwo = []\nthree = []\n"
  },
  {
    "path": "test/cargo_flags/cargo_flags/rust/src/lib.rs",
    "content": "use std::os::raw::c_char;\n\n#[no_mangle]\npub extern \"C\" fn rust_function(name: *const c_char) {\n    let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() };\n    println!(\"Hello, {}! I am Rust!\", name);\n\n    #[cfg(not(feature = \"one\"))]\n    compile_error!(\"Feature one is not enabled\");\n    #[cfg(not(feature = \"two\"))]\n    compile_error!(\"Feature two is not enabled\");\n    #[cfg(not(feature = \"three\"))]\n    compile_error!(\"Feature three is not enabled\");\n}\n"
  },
  {
    "path": "test/cbindgen/CMakeLists.txt",
    "content": "corrosion_tests_add_test(cbindgen_rust2cpp_auto \"cpp-exe\" TEST_SRC_DIR auto)\ncorrosion_tests_add_test(cbindgen_manual \"cpp-exe\" TEST_SRC_DIR manual)\n\nset_tests_properties(cbindgen_rust2cpp_auto_run_cpp-exe cbindgen_manual_run_cpp-exe\n         PROPERTIES PASS_REGULAR_EXPRESSION\n        \"^add_point Result: Point { x: 100, y: 100 }\\r?\\n$\"\n)\n\nadd_test(NAME \"cbindgen_install_configure\"\n         COMMAND\n         ${CMAKE_COMMAND}\n         -S \"${CMAKE_CURRENT_SOURCE_DIR}/install_lib\"\n         -B \"${CMAKE_CURRENT_BINARY_DIR}/build_install_lib\"\n         \"-G${CMAKE_GENERATOR}\"\n            --install-prefix \"${CMAKE_CURRENT_BINARY_DIR}/build_install_lib/test_install_lib_install_dir\"\n\n         COMMAND_EXPAND_LISTS\n)\n\nadd_test(NAME \"cbindgen_install\"\n         COMMAND\n         ${CMAKE_COMMAND}\n         --build \"${CMAKE_CURRENT_BINARY_DIR}/build_install_lib\"\n         --target install\n         --config Debug\n)\n\nadd_test(NAME cbindgen_install_check_header_installed\n         COMMAND\n         \"${CMAKE_COMMAND}\"\n         -P \"${CMAKE_CURRENT_SOURCE_DIR}/../TestFileExists.cmake\"\n         \"${CMAKE_CURRENT_BINARY_DIR}/build_install_lib/test_install_lib_install_dir/include/rust-lib.h\"\n)\n\nadd_test(NAME cbindgen_install_clean\n         COMMAND\n         \"${CMAKE_COMMAND}\"\n            -E remove_directory \"${CMAKE_CURRENT_BINARY_DIR}/build_install_lib/\"\n)\nset_tests_properties(\"cbindgen_install_configure\" PROPERTIES FIXTURES_SETUP \"configure_fixture_cbindgen_install\")\nset_tests_properties(\"cbindgen_install\" PROPERTIES FIXTURES_REQUIRED \"configure_fixture_cbindgen_install\")\n\nset_tests_properties(\"cbindgen_install\" PROPERTIES FIXTURES_SETUP \"install_fixture_cbindgen_install\")\nset_tests_properties(\"cbindgen_install_check_header_installed\" PROPERTIES FIXTURES_REQUIRED \"install_fixture_cbindgen_install\")\nset_tests_properties(\"cbindgen_install_check_header_installed\" PROPERTIES FIXTURES_SETUP \"fx_check_header_installed\")\nset_tests_properties(cbindgen_install_clean PROPERTIES FIXTURES_CLEANUP \"configure_fixture_cbindgen_install;install_fixture_cbindgen_install;fx_check_header_installed\")\n\n# Todo: We also should add a cpp2rust test with the following setup:\n# - A rust lib that is used by a rust executable\n# - cbindgen creates bindings for the rust-lib\n# - c++ code uses the rust lib and is used in turn by the rust bin.\n\n# todo: add a test for the DEPFILE and correct regenerating if the sources are touched.\n"
  },
  {
    "path": "test/cbindgen/auto/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\n\nset(CORROSION_TOOLS_RUST_TOOLCHAIN \"stable\")\ninclude(../../test_header.cmake)\ncorrosion_import_crate(MANIFEST_PATH rust/Cargo.toml)\ncorrosion_experimental_cbindgen(TARGET the_rust_lib_crate_name HEADER_NAME \"rust-lib.h\")\n\nadd_executable(cpp-exe main.cpp)\nset_property(TARGET cpp-exe PROPERTY CXX_STANDARD 11)\ntarget_link_libraries(cpp-exe PUBLIC the_rust_lib_crate_name)\n"
  },
  {
    "path": "test/cbindgen/auto/main.cpp",
    "content": "#include \"rust-lib.h\"\n#include <cassert>\n\nint main(int argc, char **argv) {\n    assert(is_magic_number(MAGIC_NUMBER));\n    struct Point p1, p2;\n    p1.x = 54;\n    p2.x = 46;\n    p1.y = 34;\n    p2.y = 66;\n    add_point(&p1, &p2);\n    assert(p1.x == 100);\n    assert(p2.x == 46);\n    assert(p1.y == 100);\n    assert(p2.y == 66);\n    add_point(&p1, NULL);\n    assert(p1.x == 100);\n    assert(p1.y == 100);\n\n    assert(OTHER_MOD_MAGIC_NUMBER == 192312312);\n    assert(FFI_MAGIC_NUMBER == 0xFDA00184);\n}\n"
  },
  {
    "path": "test/cbindgen/auto/rust/Cargo.toml",
    "content": "[package]\nname = \"the_rust_package_name\"\nversion = \"0.1.0\"\nlicense = \"MIT\"\nedition = \"2018\"\n\n[dependencies]\n\n[lib]\ncrate-type=[\"staticlib\"]\nname = \"the_rust_lib_crate_name\"\n"
  },
  {
    "path": "test/cbindgen/auto/rust/cbindgen.toml",
    "content": "language = \"C++\"\ninclude_version = true\n\n\n"
  },
  {
    "path": "test/cbindgen/auto/rust/src/ffi.rs",
    "content": "//! Just a module that contains some entries that should be parsed by cbindgen.\n\npub const FFI_MAGIC_NUMBER: u64 = 0xFDA0_0184;\n"
  },
  {
    "path": "test/cbindgen/auto/rust/src/lib.rs",
    "content": "pub const MAGIC_NUMBER: u64 = 0xABCD_EFAB;\n\npub mod ffi;\npub mod other_mod;\n\n#[derive(Debug)]\n#[repr(C)]\npub struct Point {\n    x: u64,\n    y: u64,\n}\n\nimpl Point {\n    pub(crate) fn add(&mut self, rhs: &Point) {\n        self.x = self.x.wrapping_add(rhs.x);\n        self.y = self.y.wrapping_add(rhs.y);\n    }\n}\n\n#[no_mangle]\npub extern \"C\" fn add_point(lhs: Option<&mut Point>, rhs: Option<&Point>) {\n    if let (Some(p1), Some(p2)) = (lhs, rhs) {\n        p1.add(p2);\n        // Print something so we can let Ctest assert the output.\n        println!(\"add_point Result: {:?}\", p1);\n    }\n}\n\n// simple test if the constant was exported by cbindgen correctly\n#[no_mangle]\npub extern \"C\" fn is_magic_number(num: u64) -> bool {\n    num == MAGIC_NUMBER\n}\n"
  },
  {
    "path": "test/cbindgen/auto/rust/src/other_mod/mod.rs",
    "content": "pub const OTHER_MOD_MAGIC_NUMBER: u32 = 192312312;\n"
  },
  {
    "path": "test/cbindgen/install_lib/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\n\nset(CORROSION_TOOLS_RUST_TOOLCHAIN \"stable\")\ninclude(../../test_header.cmake)\n\ncorrosion_import_crate(MANIFEST_PATH rust_lib/Cargo.toml)\n\nif(\"${CMAKE_SYSTEM_NAME}\" STREQUAL \"Linux\")\n    corrosion_add_target_local_rustflags(rust_lib \"-Clink-arg=-Wl,-soname,librust_lib.so\")\n    set_target_properties(rust_lib-shared PROPERTIES IMPORTED_SONAME librust_lib.so)\nelseif(\"${CMAKE_SYSTEM_NAME}\" STREQUAL \"Darwin\")\n    corrosion_add_target_local_rustflags(rust_lib -Clink-arg=-Wl,-install_name,@rpath/librust_lib.dylib,-current_version,1.0,-compatibility_version,1.0)\n    set_target_properties(rust_lib-shared PROPERTIES IMPORTED_NO_SONAME 0)\n    set_target_properties(rust_lib-shared PROPERTIES IMPORTED_SONAME librust_lib.dylib)\nendif()\n\ncorrosion_experimental_cbindgen(TARGET rust_lib HEADER_NAME \"rust-lib.h\")\n\ncorrosion_install(TARGETS rust_lib LIBRARY PUBLIC_HEADER)\n"
  },
  {
    "path": "test/cbindgen/install_lib/rust_lib/Cargo.toml",
    "content": "[package]\nname = \"rust_lib\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n[dependencies]\n\n[lib]\ncrate-type = [\"staticlib\", \"cdylib\"]\n"
  },
  {
    "path": "test/cbindgen/install_lib/rust_lib/src/lib.rs",
    "content": "\n#[no_mangle]\npub extern \"C\" fn add(left: u64, right: u64) -> u64 {\n    left + right\n}\n"
  },
  {
    "path": "test/cbindgen/manual/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\n\nset(CORROSION_TOOLS_RUST_TOOLCHAIN \"stable\")\ninclude(../../test_header.cmake)\ncorrosion_import_crate(MANIFEST_PATH rust/Cargo.toml)\n\nadd_library(cbindgen_rust_lib INTERFACE)\ncorrosion_experimental_cbindgen(MANIFEST_DIRECTORY rust\n                                CARGO_PACKAGE the-rust-lib-package-name\n                                BINDINGS_TARGET cbindgen_rust_lib\n                                HEADER_NAME \"rust-lib.h\")\n\n# The interface library for the generated headers should link to the actual rust library\ntarget_link_libraries(cbindgen_rust_lib INTERFACE the_actual_library_crate_name)\n\nadd_executable(cpp-exe main.cpp)\nset_property(TARGET cpp-exe PROPERTY CXX_STANDARD 11)\n# The C/C++ bin needs to link to the cbindgen library with the generated sources.\ntarget_link_libraries(cpp-exe PUBLIC cbindgen_rust_lib)\n#add_dependencies(cpp-exe cbindgen_rust_lib)\n"
  },
  {
    "path": "test/cbindgen/manual/main.cpp",
    "content": "#include \"rust-lib.h\"\n#include <cassert>\n\nint main(int argc, char **argv) {\n    assert(is_magic_number(MAGIC_NUMBER));\n    struct Point p1, p2;\n    p1.x = 54;\n    p2.x = 46;\n    p1.y = 34;\n    p2.y = 66;\n    add_point(&p1, &p2);\n    assert(p1.x == 100);\n    assert(p2.x == 46);\n    assert(p1.y == 100);\n    assert(p2.y == 66);\n    add_point(&p1, NULL);\n    assert(p1.x == 100);\n    assert(p1.y == 100);\n\n    assert(OTHER_MOD_MAGIC_NUMBER == 192312312);\n    assert(FFI_MAGIC_NUMBER == 0xFDA00184);\n}\n"
  },
  {
    "path": "test/cbindgen/manual/rust/Cargo.toml",
    "content": "[package]\nname = \"the-rust-lib-package-name\"\nversion = \"0.1.0\"\nlicense = \"MIT\"\nedition = \"2018\"\n\n[dependencies]\n\n[lib]\ncrate-type=[\"staticlib\"]\nname = \"the_actual_library_crate_name\"\n"
  },
  {
    "path": "test/cbindgen/manual/rust/cbindgen.toml",
    "content": "language = \"C++\"\ninclude_version = true\n\n\n"
  },
  {
    "path": "test/cbindgen/manual/rust/src/ffi.rs",
    "content": "//! Just a module that contains some entries that should be parsed by cbindgen.\n\npub const FFI_MAGIC_NUMBER: u64 = 0xFDA0_0184;\n"
  },
  {
    "path": "test/cbindgen/manual/rust/src/lib.rs",
    "content": "pub const MAGIC_NUMBER: u64 = 0xABCD_EFAB;\n\npub mod ffi;\npub mod other_mod;\n\n#[derive(Debug)]\n#[repr(C)]\npub struct Point {\n    x: u64,\n    y: u64,\n}\n\nimpl Point {\n    pub(crate) fn add(&mut self, rhs: &Point) {\n        self.x = self.x.wrapping_add(rhs.x);\n        self.y = self.y.wrapping_add(rhs.y);\n    }\n}\n\n#[no_mangle]\npub extern \"C\" fn add_point(lhs: Option<&mut Point>, rhs: Option<&Point>) {\n    if let (Some(p1), Some(p2)) = (lhs, rhs) {\n        p1.add(p2);\n        // Print something so we can let Ctest assert the output.\n        println!(\"add_point Result: {:?}\", p1);\n    }\n}\n\n// simple test if the constant was exported by cbindgen correctly\n#[no_mangle]\npub extern \"C\" fn is_magic_number(num: u64) -> bool {\n    num == MAGIC_NUMBER\n}\n"
  },
  {
    "path": "test/cbindgen/manual/rust/src/other_mod/mod.rs",
    "content": "pub const OTHER_MOD_MAGIC_NUMBER: u32 = 192312312;\n"
  },
  {
    "path": "test/config_discovery/CMakeLists.txt",
    "content": "# The `.cargo/config.toml` file registers the `my-registry` index. If Cargo fails to\n# discover the config file, the build will fail with:\n# \"registry index was not found in any configuration: `my-registry`\"\ncorrosion_tests_add_test(config_discovery \"config_discovery\")\n\n# Run the `cargo-clean` target to verify `.cargo/config.toml` discovery.\nadd_test(NAME \"config_discovery_run_cargo_clean\"\n    COMMAND \"${CMAKE_COMMAND}\" --build \"${CMAKE_CURRENT_BINARY_DIR}/build-config_discovery\" --target cargo-clean\n)\nset_tests_properties(\"config_discovery_run_cargo_clean\" PROPERTIES \n    FIXTURES_REQUIRED \"build_fixture_config_discovery\"\n    DEPENDS \"config_discovery_run_config_discovery\"\n)\n"
  },
  {
    "path": "test/config_discovery/README.md",
    "content": "# Cargo Configuration Discovery Test\n\nThis test verifies that `cargo` correctly discovers configuration files such as `.cargo/config.toml` and `toolchain.toml` in the source tree.\n\n## What's Being Tested\n\nCargo discovers configuration files by searching the current working directory and its parent directories. Therefore, Corrosion must set the correct `WORKING_DIRECTORY` for all `cargo` invocations.\n\n## How the Test Works\n\nThe test uses a `.cargo/config.toml` that defines a custom registry alias `my-registry`. A dependency in `Cargo.toml` references this alias via `registry = \"my-registry\"`.\n\nIf `cargo` does not find `.cargo/config.toml`, the `registry = \"my-registry\"` entry will cause an error during manifest parsing.\n"
  },
  {
    "path": "test/config_discovery/config_discovery/.cargo/config.toml",
    "content": "# Defines registry alias `my-registry` pointing to crates.io.\n# If not discovered cargo errors: \"registry `my-registry` not found\"\n[registries.my-registry]\nindex = \"https://github.com/rust-lang/crates.io-index\"\n"
  },
  {
    "path": "test/config_discovery/config_discovery/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\ncorrosion_import_crate(MANIFEST_PATH Cargo.toml)\n"
  },
  {
    "path": "test/config_discovery/config_discovery/Cargo.toml",
    "content": "[package]\nname = \"config_discovery\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n[dependencies]\n# Uses registry alias `my-registry`. If `.cargo/config.toml` is not discovered, the test will\n# fail wit the error: \"registry `my-registry` not found\"\nbitflags = { version = \"1.3\", registry = \"my-registry\" }\n"
  },
  {
    "path": "test/config_discovery/config_discovery/src/main.rs",
    "content": "use bitflags::bitflags;\n\nbitflags! {\n    struct TestFlags: u32 {\n        const VALUE = 0b00000001;\n    }\n}\n\nfn main() {\n    let flags = TestFlags::VALUE;\n    println!(\"Flag value: {}\", flags.bits());\n}\n"
  },
  {
    "path": "test/corrosion_install/CMakeLists.txt",
    "content": "if(NOT (CMAKE_CROSSCOMPILING AND MSVC))\n    # When using MSVC the cmake build via ExternalProject seems to inherit the target architecture,\n    # which breaks the test. Since we practically don't care about this, and we just want to ensure\n    # that installing an executable works, skipping this test when cross-compiling is fine.\n    corrosion_tests_add_test(install_rust_bin \"generated_from_installed_bin\")\n\n    set_tests_properties(\"install_rust_bin_run_generated_from_installed_bin\"\n                         PROPERTIES PASS_REGULAR_EXPRESSION\n                         \"Hello World! I'm generated code\"\n    )\nendif()\n\n# Todo: Fix and re-enable tests on Windows\nif(NOT CMAKE_CROSSCOMPILING AND NOT WIN32)\n    corrosion_tests_add_test(install_lib \"main-static;main-shared\")\n\n    set_tests_properties(\"install_lib_run_main-static\" \"install_lib_run_main-shared\"\n                         PROPERTIES PASS_REGULAR_EXPRESSION\n                         \"The sum is 11\"\n    )\nendif()\n\n# Further tests we should add:\n# - Test installing a Rust executable, that requires a (C/C++) shared library at runtime.\n#   Note: We should delete the build directory of the subproject\n#         before running the installed rust executable, to insure the shared library is loaded from the\n#         installed location and not from the build dir."
  },
  {
    "path": "test/corrosion_install/install_lib/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(ExternalProject)\n\nadd_library(static_lib STATIC IMPORTED)\nadd_library(shared_lib SHARED IMPORTED)\nset(install_prefix \"${CMAKE_CURRENT_BINARY_DIR}/rust_lib\")\nset(static_lib_install_path \"${install_prefix}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}rust_lib${CMAKE_STATIC_LIBRARY_SUFFIX}\")\nset(shared_lib_install_path \"${install_prefix}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}rust_lib${CMAKE_SHARED_LIBRARY_SUFFIX}\")\n\n\nset_target_properties(static_lib PROPERTIES\n                      IMPORTED_LOCATION\n                      \"${static_lib_install_path}\")\n\nset_target_properties(shared_lib PROPERTIES\n                      IMPORTED_LOCATION\n                      \"${shared_lib_install_path}\")\n\nadd_executable(main-static main.cpp)\ntarget_link_libraries(main-static PRIVATE static_lib)\n\nExternalProject_Add(\n        rust_lib\n        PREFIX \"${CMAKE_CURRENT_BINARY_DIR}/rust_lib\"\n        SOURCE_DIR \"${CMAKE_CURRENT_SOURCE_DIR}/rust_lib\"\n        CMAKE_ARGS \"-DCMAKE_INSTALL_PREFIX=${install_prefix}\"\n        # INSTALL_BYPRODUCTS \"${static_lib_install_path}\"\n)\n\n# Dummy target since INSTALL_BYPRODUCTS requires CMake 3.26\nadd_custom_target(build_rust_project_dummy\n                  COMMAND echo dummy\n                  BYPRODUCTS \"${static_lib_install_path}\" \"${shared_lib_install_path}\"\n                  DEPENDS rust_lib)\n\nadd_dependencies(main-static build_rust_project_dummy)\n\nset(CMAKE_BUILD_RPATH ${install_prefix}/lib)\nadd_executable(main-shared main.cpp)\ntarget_link_libraries(main-shared\n        PUBLIC shared_lib)\n\nadd_dependencies(main-shared build_rust_project_dummy)\n"
  },
  {
    "path": "test/corrosion_install/install_lib/main.cpp",
    "content": "#include <stdint.h>\n#include <assert.h>\n#include <iostream>\n\nextern \"C\" uint64_t add(uint64_t a, uint64_t b);\n\nint main(int argc, char **argv) {\n    uint64_t sum = add(5, 6);\n    assert(sum == 11);\n    std::cout << \"The sum is \" << sum << std::endl;\n}\n"
  },
  {
    "path": "test/corrosion_install/install_lib/rust_lib/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../../test_header.cmake)\n\ncorrosion_import_crate(MANIFEST_PATH Cargo.toml)\n\nif(\"${CMAKE_SYSTEM_NAME}\" STREQUAL \"Linux\")\n    corrosion_add_target_local_rustflags(rust_lib \"-Clink-arg=-Wl,-soname,librust_lib.so\")\n    set_target_properties(rust_lib-shared PROPERTIES IMPORTED_SONAME librust_lib.so)\nelseif(\"${CMAKE_SYSTEM_NAME}\" STREQUAL \"Darwin\")\n    corrosion_add_target_local_rustflags(rust_lib -Clink-arg=-Wl,-install_name,@rpath/librust_lib.dylib,-current_version,1.0,-compatibility_version,1.0)\n    set_target_properties(rust_lib-shared PROPERTIES IMPORTED_NO_SONAME 0)\n    set_target_properties(rust_lib-shared PROPERTIES IMPORTED_SONAME librust_lib.dylib)\nendif()\n\ntarget_sources(rust_lib INTERFACE include/rust_lib/rust_lib.hpp)\n\ncorrosion_install(TARGETS rust_lib)\n"
  },
  {
    "path": "test/corrosion_install/install_lib/rust_lib/Cargo.toml",
    "content": "[package]\nname = \"rust_lib\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n[dependencies]\n\n[lib]\ncrate-type = [\"staticlib\", \"cdylib\"]\n"
  },
  {
    "path": "test/corrosion_install/install_lib/rust_lib/include/rust_lib/rust_lib.hpp",
    "content": "#include <cstdint.h>\n\nextern \"C\" uint64_t add(uint64_t left, uint64_t right);\n"
  },
  {
    "path": "test/corrosion_install/install_lib/rust_lib/src/lib.rs",
    "content": "\n#[no_mangle]\npub extern \"C\" fn add(left: u64, right: u64) -> u64 {\n    left + right\n}\n"
  },
  {
    "path": "test/corrosion_install/install_rust_bin/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.22)\nproject(test_project VERSION 0.1.0)\n\n# Note: Corrosion supports `hostbuild`, so building a Rust binary in a subproject\n# like this doesn't offer any benefit over using the hostbuild option.\n# However, this is a reasonable way to test that installing Rust binaries via\n# corrosion_install works as expected.\ninclude(ExternalProject)\n\nset(bin_suffix \"\")\nif(CMAKE_HOST_WIN32)\n    set(bin_suffix \".exe\")\nendif()\nset(generator_bin_path \"${CMAKE_CURRENT_BINARY_DIR}/rust_bin/bin/my_rust_bin${bin_suffix}\")\n\nExternalProject_Add(\n        rust_bin\n        PREFIX \"${CMAKE_CURRENT_BINARY_DIR}/rust_bin\"\n        SOURCE_DIR \"${CMAKE_CURRENT_SOURCE_DIR}/rust_bin\"\n        CMAKE_ARGS \"-DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/rust_bin\"\n)\n\n# This custom command is the main part of the test:\n# We test that corrosion (in the CMake of the ExternalProject) properly installed\n# a Rust executable to the location we specified by running the executable, which generates some cpp code.\nadd_custom_command(\n        OUTPUT generated_main.cpp\n        COMMAND \"${generator_bin_path}\" > \"${CMAKE_CURRENT_BINARY_DIR}/generated_main.cpp\"\n        DEPENDS rust_bin\n)\n\nadd_executable(generated_from_installed_bin ${CMAKE_CURRENT_BINARY_DIR}/generated_main.cpp)\n"
  },
  {
    "path": "test/corrosion_install/install_rust_bin/rust_bin/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.22)\nproject(test_rust_bin VERSION 0.1.0)\ninclude(../../../test_header.cmake)\ninclude(GNUInstallDirs)\n\ncorrosion_import_crate(MANIFEST_PATH Cargo.toml)\ncorrosion_install(TARGETS my_rust_bin)\n"
  },
  {
    "path": "test/corrosion_install/install_rust_bin/rust_bin/Cargo.toml",
    "content": "[package]\nname = \"my_rust_bin\"\nversion = \"0.1.0\"\nedition = \"2018\"\nlicense = \"MIT\"\n\n[dependencies]\n"
  },
  {
    "path": "test/corrosion_install/install_rust_bin/rust_bin/src/main.rs",
    "content": "fn main() {\n    println!(\n\"#include <iostream>\nint main() {{\n    std::cout << \\\"Hello World! I'm generated code\\\";\n    return 0;\n}}\"\n    );\n}\n"
  },
  {
    "path": "test/cpp2rust/CMakeLists.txt",
    "content": "corrosion_tests_add_test(cpp2rust \"rust-exe\")\n\nset_tests_properties(\"cpp2rust_run_rust-exe\" PROPERTIES PASS_REGULAR_EXPRESSION\n        \"Hello, Rust! I am Cpp!\\r?\\nHello, Rust! I am Cpp library Number 2!\\r?\\nHello, Rust! I am Cpp library Number 3!\"\n        )\n"
  },
  {
    "path": "test/cpp2rust/cpp2rust/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\ncorrosion_import_crate(MANIFEST_PATH rust/Cargo.toml)\n\nadd_library(cpp-lib lib.cpp)\ntarget_compile_features(cpp-lib PRIVATE cxx_std_14)\nset_target_properties(\n    cpp-lib\n    PROPERTIES\n        POSITION_INDEPENDENT_CODE ON\n)\n\nadd_library(cpp-lib2 lib2.cpp)\ntarget_compile_features(cpp-lib2 PRIVATE cxx_std_14)\nset_target_properties(\n        cpp-lib2\n        PROPERTIES\n        POSITION_INDEPENDENT_CODE ON\n        OUTPUT_NAME cpp-lib-renamed\n)\n\nadd_library(cpp-lib3 \"path with space/lib3.cpp\" )\ntarget_compile_features(cpp-lib3 PRIVATE cxx_std_14)\nset_target_properties(\n        cpp-lib3\n        PROPERTIES\n        POSITION_INDEPENDENT_CODE ON\n)\n\ncorrosion_link_libraries(rust-exe cpp-lib cpp-lib2 cpp-lib3)\n"
  },
  {
    "path": "test/cpp2rust/cpp2rust/lib.cpp",
    "content": "#include <iostream>\n\nextern \"C\" void cpp_function(char const *name) {\n    std::cout << \"Hello, \" << name << \"! I am Cpp!\\n\";\n}\n"
  },
  {
    "path": "test/cpp2rust/cpp2rust/lib2.cpp",
    "content": "#include <iostream>\n#include <stdint.h>\n\nextern \"C\" void cpp_function2(char const *name) {\n    std::cout << \"Hello, \" << name << \"! I am Cpp library Number 2!\\n\";\n}\n\nextern \"C\" uint32_t get_42() {\n    uint32_t v = 42;\n    return v;\n}\n"
  },
  {
    "path": "test/cpp2rust/cpp2rust/path with space/lib3.cpp",
    "content": "// Check that libraries located at a path containing a space can also be linked.\n\n#include <iostream>\n\nextern \"C\" void cpp_function3(char const *name) {\n    std::cout << \"Hello, \" << name << \"! I am Cpp library Number 3!\\n\";\n}\n\n"
  },
  {
    "path": "test/cpp2rust/cpp2rust/rust/Cargo.toml",
    "content": "[package]\nname = \"rust-exe\"\nversion = \"0.1.0\"\nauthors = [\"Andrew Gaspar <andrew.gaspar@outlook.com>\"]\nlicense = \"MIT\"\nedition = \"2018\"\n\n[dependencies]\nrust-dependency = { path = \"rust_dependency\" }\n"
  },
  {
    "path": "test/cpp2rust/cpp2rust/rust/build.rs",
    "content": "// Build-scripts also need to be linked, so just add a dummy buildscript ensuring this works.\nfn main() {\n    println!(\"Build-script is running.\")\n}\n"
  },
  {
    "path": "test/cpp2rust/cpp2rust/rust/rust_dependency/Cargo.toml",
    "content": "[package]\nname = \"rust-dependency\"\nversion = \"0.1.0\"\nlicense = \"MIT\"\nedition = \"2018\"\n\n[dependencies]\n\n"
  },
  {
    "path": "test/cpp2rust/cpp2rust/rust/rust_dependency/src/lib.rs",
    "content": "\nextern \"C\" {\n    fn get_42() -> u32;\n}\npub fn calls_ffi() {\n    let res = unsafe { get_42()};\n    assert_eq!(res, 42);\n}\n"
  },
  {
    "path": "test/cpp2rust/cpp2rust/rust/src/bin/rust-exe.rs",
    "content": "use std::os::raw::c_char;\n\nextern \"C\" {\n    fn cpp_function(name: *const c_char);\n    fn cpp_function2(name: *const c_char);\n    fn cpp_function3(name: *const c_char);\n\n}\n\nfn greeting(name: &str) {\n    let name = std::ffi::CString::new(name).unwrap();\n    unsafe {\n        cpp_function(name.as_ptr());\n        cpp_function2(name.as_ptr());\n        cpp_function3(name.as_ptr());\n    }\n}\n\nfn main() {\n    let args = std::env::args().skip(1).collect::<Vec<_>>();\n    if args.len() >= 1 {\n        greeting(&args[0]);\n    } else {\n        greeting(\"Rust\");\n    }\n    rust_dependency::calls_ffi();\n}\n"
  },
  {
    "path": "test/crate_type/CMakeLists.txt",
    "content": "corrosion_tests_add_test(crate_type \"cpp-exe\")\n\n\nset_tests_properties(\"crate_type_run_cpp-exe\" PROPERTIES PASS_REGULAR_EXPRESSION\n        \"Hello from lib 1!\\r?\\nHello from lib 2!\"\n        )\n"
  },
  {
    "path": "test/crate_type/crate_type/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\n# Add --crate-type to ensure that only the specified type of library is built and no error is thrown\ncorrosion_import_crate(MANIFEST_PATH proj1/Cargo.toml CRATE_TYPES staticlib FLAGS --crate-type=staticlib)\ncorrosion_import_crate(MANIFEST_PATH proj2/Cargo.toml CRATE_TYPES cdylib FLAGS --crate-type=cdylib)\n\nadd_executable(cpp-exe main.cpp)\ntarget_link_libraries(cpp-exe proj1)\ntarget_link_libraries(cpp-exe proj2)\n"
  },
  {
    "path": "test/crate_type/crate_type/main.cpp",
    "content": "extern \"C\" void rust_function1();\nextern \"C\" void rust_function2();\n\nint main() {\n    rust_function1();\n    rust_function2();\n    return 0;\n}\n"
  },
  {
    "path": "test/crate_type/crate_type/proj1/Cargo.toml",
    "content": "[package]\nname = \"proj1\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n[dependencies]\n\n[lib]\ncrate-type=[\"staticlib\", \"cdylib\"]\n\n"
  },
  {
    "path": "test/crate_type/crate_type/proj1/src/lib.rs",
    "content": "#[no_mangle]\npub extern \"C\" fn rust_function1() {\n    println!(\"Hello from lib 1!\");\n}\n"
  },
  {
    "path": "test/crate_type/crate_type/proj2/Cargo.toml",
    "content": "[package]\nname = \"proj2\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n[dependencies]\n\n[lib]\ncrate-type=[\"staticlib\", \"cdylib\"]\n"
  },
  {
    "path": "test/crate_type/crate_type/proj2/src/lib.rs",
    "content": "#[no_mangle]\npub extern \"C\" fn rust_function2() {\n    println!(\"Hello from lib 2!\");\n}\n"
  },
  {
    "path": "test/custom_profiles/CMakeLists.txt",
    "content": "# The tests in this folder test specifying the cargo profile name via the --profile option.\n# The built-in `test` and `bench` profiles are _not_ supported, because they output\n# artifacts to a different location and add a hash to the artifact name.\nif(Rust_VERSION VERSION_GREATER_EQUAL 1.57.0)\n\n    corrosion_tests_add_test(custom_profiles_global \"custom-profile-exe\" TEST_SRC_DIR custom_profiles)\n    corrosion_tests_add_test(custom_profiles_target_specific \"custom-profile-exe\"\n        TEST_SRC_DIR custom_profiles\n        PASS_THROUGH_ARGS -DCORROSION_TEST_USE_TARGET_SPECIFIC_OVERRIDE=ON\n    )\n    corrosion_tests_add_test(dev_profile \"dev_bin\" TEST_SRC_DIR basic_profiles CARGO_PROFILE dev)\n    corrosion_tests_add_test(release_profile \"release_bin\" TEST_SRC_DIR basic_profiles CARGO_PROFILE release)\n\n    set_tests_properties(\"custom_profiles_global_run_custom-profile-exe\" PROPERTIES PASS_REGULAR_EXPRESSION\n        \"^Hello, Cpp! I'm Rust!\\r?\\n$\"\n        )\n    set_tests_properties(\"custom_profiles_target_specific_run_custom-profile-exe\" PROPERTIES PASS_REGULAR_EXPRESSION\n        \"^Hello, Cpp! I'm Rust!\\r?\\n$\"\n        )\n    set_tests_properties(\"dev_profile_run_dev_bin\" PROPERTIES PASS_REGULAR_EXPRESSION\n        \"^Hello, Cpp! I'm Rust!\\r?\\n$\"\n        )\n    set_tests_properties(\"release_profile_run_release_bin\" PROPERTIES PASS_REGULAR_EXPRESSION\n        \"^Hello, Cpp! I'm Rust!\\r?\\n$\"\n        )\n\nendif()\n"
  },
  {
    "path": "test/custom_profiles/basic_profiles/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\nif(NOT DEFINED CARGO_PROFILE)\n    message(FATAL_ERROR \"Test internal error. The test should be called with the CARGO_PROFILE parameter.\")\nendif()\n\ncorrosion_import_crate(MANIFEST_PATH rust/Cargo.toml PROFILE ${CARGO_PROFILE})\n\nadd_executable(${CARGO_PROFILE}_bin main.cpp)\ntarget_link_libraries(${CARGO_PROFILE}_bin PUBLIC cargo_profiles_lib)\n"
  },
  {
    "path": "test/custom_profiles/basic_profiles/main.cpp",
    "content": "extern \"C\" void rust_function(char const *name);\n\n\nint main(int argc, char **argv) {\n        rust_function(\"Cpp\");\n}\n"
  },
  {
    "path": "test/custom_profiles/basic_profiles/rust/Cargo.toml",
    "content": "[package]\nname = \"cargo-profiles-lib\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n[lib]\ncrate-type=[\"staticlib\"]\n"
  },
  {
    "path": "test/custom_profiles/basic_profiles/rust/src/lib.rs",
    "content": "use std::os::raw::c_char;\n\n#[no_mangle]\npub extern \"C\" fn rust_function(name: *const c_char) {\n    let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() };\n    println!(\"Hello, {}! I'm Rust!\", name);\n}\n\n"
  },
  {
    "path": "test/custom_profiles/custom_profiles/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\nset(_release_profile $<IF:$<CONFIG:Release>,release-without-dbg,custom-without-dbg>)\nset(custom_profile $<IF:$<CONFIG:Debug>,dev-without-dbg,${_release_profile}>)\n\nif(CORROSION_TEST_USE_TARGET_SPECIFIC_OVERRIDE)\n    # Select \"wrong\" profile here on purpose.\n    corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml PROFILE dev)\n    set_target_properties(custom_profiles_lib\n        PROPERTIES\n        INTERFACE_CORROSION_CARGO_PROFILE \"${custom_profile}\"\n    )\nelse()\n    corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml PROFILE ${custom_profile})\nendif()\n\nadd_executable(custom-profile-exe main.cpp)\ntarget_link_libraries(custom-profile-exe PUBLIC custom_profiles_lib)\n"
  },
  {
    "path": "test/custom_profiles/custom_profiles/main.cpp",
    "content": "extern \"C\" void rust_function(char const *name);\n\n\nint main(int argc, char **argv) {\n        rust_function(\"Cpp\");\n}\n"
  },
  {
    "path": "test/custom_profiles/custom_profiles/rust/Cargo.toml",
    "content": "[package]\nname = \"custom-profiles-lib\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n[lib]\ncrate-type=[\"staticlib\"]\n\n# Test if neither release or debug where selected by only disabling debug-assertions in the inherited profile.\n[profile.release]\ndebug-assertions = true\n\n[profile.dev-without-dbg]\ninherits = \"dev\"\ndebug-assertions = false\n\n[profile.release-without-dbg]\ninherits = \"release\"\ndebug-assertions = false\n\n[profile.custom-without-dbg]\ninherits = \"release\"\nopt-level = 1\ndebug-assertions = false\n"
  },
  {
    "path": "test/custom_profiles/custom_profiles/rust/src/lib.rs",
    "content": "use std::os::raw::c_char;\n\n#[no_mangle]\npub extern \"C\" fn rust_function(name: *const c_char) {\n    let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() };\n    println!(\"Hello, {}! I'm Rust!\", name);\n}\n\n\n#[cfg(debug_assertions)]\nconst _: () = assert!(false, \"Debug assertions where not disabled via custom profile!\");\n"
  },
  {
    "path": "test/custom_target/CMakeLists.txt",
    "content": "# Create a custom target triple, by taking the default host triple target spec.\n# This way we don't actually need to cross-compile and just check if we can handle\n# custom json target triples.\n# Note: dashes and not underscore is important, at least if cc-rs is used by dependencies,\n# since cc-rs will attempt to parse the target triple.\n# A real-world toolchain .json file should be named the same as the corresponding c/c++ compiler target,\n# in order for cc-rs to choose the correct target by default.\nset(target_spec_file \"${CMAKE_CURRENT_BINARY_DIR}/custom-target-triple.json\")\nexecute_process(COMMAND\n                ${CMAKE_COMMAND} -E env RUSTC_BOOTSTRAP=1\n                ${_CORROSION_RUSTC} -Z unstable-options --print target-spec-json\n                OUTPUT_FILE \"${target_spec_file}\"\n                COMMAND_ERROR_IS_FATAL ANY\n)\n\nset(Rust_CARGO_TARGET \"${target_spec_file}\")\ncorrosion_tests_add_test(custom_target \"test-exe;rust-bin\")\n\nset_tests_properties(\"custom_target_run_test-exe\" PROPERTIES PASS_REGULAR_EXPRESSION [[Hello, Cxx! I am Rust!]])\nset_tests_properties(\"custom_target_run_rust-bin\" PROPERTIES PASS_REGULAR_EXPRESSION [[The answer is 42]])\n\n"
  },
  {
    "path": "test/custom_target/custom_target/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0 LANGUAGES C CXX)\n# The outer test driver gives the file a useless name\n# Supress the warning, since we don't rely on this information anyway.\nset(CORROSION_NO_WARN_PARSE_TARGET_TRIPLE_FAILED ON)\ninclude(../../test_header.cmake)\n\nif(NOT \"${Rust_CARGO_TARGET}\" MATCHES \".json\")\n    message(FATAL_ERROR \"This test project expects to be configured with a custom rust target!\"\n            \"Actual target: ${Rust_CARGO_TARGET}\"\n    )\nendif()\n\ncorrosion_import_crate(MANIFEST_PATH rust/Cargo.toml)\ncorrosion_set_cargo_flags(rust_lib \"-Zbuild-std\")\n# custom target triples require nightly features\ncorrosion_set_env_vars(rust_lib RUSTC_BOOTSTRAP=1)\n\ncorrosion_set_cargo_flags(rust-bin \"-Zbuild-std\")\ncorrosion_set_env_vars(rust-bin RUSTC_BOOTSTRAP=1)\n\nadd_executable(test-exe main.cpp)\ntarget_link_libraries(test-exe PUBLIC rust_lib)\n"
  },
  {
    "path": "test/custom_target/custom_target/main.cpp",
    "content": "extern \"C\" void rust_function(char const *name);\n\n\nint main(int argc, char **argv) {\n        rust_function(\"Cxx\");\n}\n"
  },
  {
    "path": "test/custom_target/custom_target/rust/Cargo.toml",
    "content": "[package]\nname = \"rust-lib\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n[lib]\ncrate-type=[\"staticlib\", \"lib\"]\n\n[[bin]]\nname = \"rust-bin\"\npath = \"src/bin.rs\"\n\n[build-dependencies]\ncc = \"1\"\n"
  },
  {
    "path": "test/custom_target/custom_target/rust/build.rs",
    "content": "fn main() {\n    let mut builder = cc::Build::new();\n    // We override the target here, purely to make the testcase simpler.\n    // In a real-world project, the custom rust .json target triple file\n    // should have a filename matching the target-triple the c-compiler understands\n    // (if the c/c++ toolchain is llvm based)\n    builder.target(&std::env::var(\"HOST\").unwrap());\n\n    builder.file(\"c_lib.c\").compile(\"custom_target\");\n}"
  },
  {
    "path": "test/custom_target/custom_target/rust/c_lib.c",
    "content": "#include <stdint.h>\n\nuint32_t calculate_42(void) {\n    return 42;\n}"
  },
  {
    "path": "test/custom_target/custom_target/rust/src/bin.rs",
    "content": "use rust_lib::calculate_42;\n\nfn main() {\n    let answer = unsafe { calculate_42() } ;\n    println!(\"The answer is {}\", answer);\n}\n"
  },
  {
    "path": "test/custom_target/custom_target/rust/src/lib.rs",
    "content": "use std::os::raw::c_char;\n\nextern \"C\" {\n    pub fn calculate_42() -> u32;\n}\n\n#[no_mangle]\npub extern \"C\" fn rust_function(name: *const c_char) {\n    let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() };\n    let res = unsafe { calculate_42() };\n    assert_eq!(res, 42);\n    println!(\"Hello, {}! I am Rust!\", name);\n}\n"
  },
  {
    "path": "test/cxxbridge/CMakeLists.txt",
    "content": "if(CORROSION_TESTS_CXXBRIDGE)\n    corrosion_tests_add_test(cxxbridge_cpp2rust_1 \"rust_bin\"\n        TEST_SRC_DIR cxxbridge_cpp2rust\n        PASS_THROUGH_ARGS -DTEST_CXXBRIDGE_VARIANT1=ON\n    )\n    corrosion_tests_add_test(cxxbridge_cpp2rust_2 \"rust_bin\"\n        TEST_SRC_DIR cxxbridge_cpp2rust\n        PASS_THROUGH_ARGS -DTEST_CXXBRIDGE_VARIANT2=ON\n    )\n    corrosion_tests_add_test(cxxbridge_rust2cpp \"cxxbridge-exe\")\n    if (CMAKE_VERSION VERSION_GREATER_EQUAL \"3.24.0\" AND CMAKE_LINK_GROUP_USING_RESCAN_SUPPORTED)\n        corrosion_tests_add_test(cxxbridge_circular_link_group \"cpp_bin\"\n            TEST_SRC_DIR cxxbridge_circular\n            PASS_THROUGH_ARGS -DTEST_CXXBRIDGE_VARIANT1=ON\n        )\n    endif()\n    corrosion_tests_add_test(cxxbridge_circular_mutual_link \"cpp_bin\"\n        TEST_SRC_DIR cxxbridge_circular\n        PASS_THROUGH_ARGS -DTEST_CXXBRIDGE_VARIANT2=ON\n    )\n\n    set_tests_properties(\"cxxbridge_cpp2rust_1_run_rust_bin\"\n        PROPERTIES PASS_REGULAR_EXPRESSION\n            \"main function\"\n    )\n    set_tests_properties(\"cxxbridge_rust2cpp_run_cxxbridge-exe\"\n        PROPERTIES PASS_REGULAR_EXPRESSION\n            \"Hello cxxbridge from lib.rs! \\\\[4, 5, 6\\\\]\\r?\\nHello cxxbridge from foo/mod.rs! \\\\[4, 5, 6\\\\]\"\n    )\n\n    if(NOT WIN32)\n        corrosion_tests_add_test(cxxbridge_exported_impls \"test_main\")\n        set_tests_properties(\"cxxbridge_exported_impls_run_test_main\"\n            PROPERTIES PASS_REGULAR_EXPRESSION\n                \"main function\"\n        )\n    endif()\nendif()\n"
  },
  {
    "path": "test/cxxbridge/cxxbridge_circular/CMakeLists.txt",
    "content": "# This CMake project tests the setup for circular dependencies that involve a CXX bridge\n# While circular dependencies are usually discouraged, with CXX they are reasonbly natural,\n# as ideally, Rust should be able to call C++ freely and vice-versa.\n#\n# The way this project is set up, the rust_lib target acts as the one target that includes\n# the mixed C++ and Rust code with the cpp_lib and cxxbridge targets as implementation details,\n# which shouldn't be used individually.\ncmake_minimum_required(VERSION 3.24)\nproject(test_project VERSION 0.1.0 LANGUAGES CXX)\ninclude(../../test_header.cmake)\nset(CMAKE_CXX_STANDARD 11)\nset(CMAKE_CXX_STANDARD_REQUIRED 1)\n\ncorrosion_import_crate(MANIFEST_PATH rust/Cargo.toml)\ncorrosion_add_cxxbridge(cxxbridge CRATE rust_lib FILES lib.rs)\n\nif(MSVC)\n    set_target_properties(cxxbridge PROPERTIES MSVC_RUNTIME_LIBRARY \"MultiThreadedDLL\")\nendif()\n\nadd_library(cpp_lib STATIC cpplib.cpp)\ntarget_include_directories(cpp_lib PUBLIC \"${CMAKE_CURRENT_LIST_DIR}/include\")\n\n# Make sure the cpp library can access the headers from the bridge and vice-versa\ntarget_link_libraries(cpp_lib PUBLIC cxxbridge)\ntarget_link_libraries(cxxbridge PRIVATE cpp_lib)\n\n# The 3 libraries (rust, cpp, cxx) have a circular dependency, set this up in the linker\n# so that the rust_lib target links to everything and circular references are resolved.\nif(TEST_CXXBRIDGE_VARIANT1)\n    if (NOT CMAKE_LINK_GROUP_USING_RESCAN_SUPPORTED)\n        message(FATAL_ERROR \"Cannot run this test case without Cmake 3.24 or higher\")\n    endif()\n    target_link_libraries(rust_lib INTERFACE\n        \"$<LINK_GROUP:RESCAN,cxxbridge,rust_lib-static,cpp_lib>\")\nelseif(TEST_CXXBRIDGE_VARIANT2)\n    target_link_libraries(rust_lib INTERFACE cxxbridge cpp_lib)\nendif()\n\nadd_executable(cpp_bin main.cpp)\ntarget_link_libraries(cpp_bin cpp_lib)\n\nif(MSVC)\n    set_target_properties(cpp_lib PROPERTIES MSVC_RUNTIME_LIBRARY \"MultiThreadedDLL\")\n    set_target_properties(cxxbridge PROPERTIES MSVC_RUNTIME_LIBRARY \"MultiThreadedDLL\")\n    set_target_properties(cpp_bin PROPERTIES MSVC_RUNTIME_LIBRARY \"MultiThreadedDLL\")\nendif()\n"
  },
  {
    "path": "test/cxxbridge/cxxbridge_circular/cpplib.cpp",
    "content": "#include \"cpplib.h\"\n#include \"cxxbridge/lib.h\"\n#include \"rust/cxx.h\"\n#include <iostream>\n\nRsImage read_image(rust::Str path) {\n  std::cout << \"read_image called\" << std::endl;\n  std::cout << path << std::endl;\n  Rgba c = {1.0, 2.0, 3.0, 4.0};\n  RsImage v = {1, 1, c};\n  return v;\n}\n\nvoid assert_equality() {\n  if (!read_image(\"dummy_path\").equal_to(\"dummy path\")) {\n    throw std::runtime_error(\"equality_check failed\");\n  }\n}\n"
  },
  {
    "path": "test/cxxbridge/cxxbridge_circular/include/cpplib.h",
    "content": "#pragma once\n#include \"cxxbridge/lib.h\"\n\n::RsImage read_image(::rust::Str path);\n\nvoid assert_equality();\n"
  },
  {
    "path": "test/cxxbridge/cxxbridge_circular/main.cpp",
    "content": "#include \"cpplib.h\"\n\n#include <iostream>\n\nint main(void) {\n  std::cout << \"Testing roundtrip...\" << std::endl;\n\n  try {\n    assert_equality();\n  } catch (const std::exception &e) {\n    std::cerr << \"Error: \" << e.what() << std::endl;\n    return 1;\n  }\n\n  std::cout << \"Roundtrip successful!\";\n  return 0;\n}\n"
  },
  {
    "path": "test/cxxbridge/cxxbridge_circular/rust/Cargo.toml",
    "content": "[package]\nname = \"rust_lib\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n[lib]\nname = \"rust_lib\"\ncrate-type = [\"staticlib\"]\n\n[dependencies]\ncxx = \"1.0\"\n"
  },
  {
    "path": "test/cxxbridge/cxxbridge_circular/rust/src/lib.rs",
    "content": "#[cxx::bridge]\npub mod ffi {\n    #[derive(Debug, PartialEq)]\n    pub struct Rgba {\n        r: f32,\n        g: f32,\n        b: f32,\n        a: f32,\n    }\n\n    #[derive(Debug, PartialEq)]\n    pub struct RsImage {\n        width: usize,\n        height: usize,\n        raster: Rgba,\n    }\n    unsafe extern \"C++\" {\n        include!(\"cpplib.h\");\n        pub fn read_image(path: &str) -> RsImage;\n    }\n\n    extern \"Rust\" {\n        pub fn equal_to(self: &RsImage, other: &str) -> bool;\n    }\n}\n\nuse ffi::*;\n\nimpl RsImage {\n    pub fn equal_to(&self, path: &str) -> bool {\n        println!(\"equal_to\");\n        *self == read_image(path)\n    }\n}\n"
  },
  {
    "path": "test/cxxbridge/cxxbridge_cpp2rust/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0 LANGUAGES CXX)\ninclude(../../test_header.cmake)\nset(CMAKE_CXX_STANDARD 11)\nset(CMAKE_CXX_STANDARD_REQUIRED 1)\n\ncorrosion_import_crate(MANIFEST_PATH rust/Cargo.toml)\ncorrosion_add_cxxbridge(cxxbridge-cpp CRATE rust_bin FILES lib.rs)\ntarget_include_directories(cxxbridge-cpp PRIVATE \"include\")\n\nif(CMAKE_SYSTEM_NAME STREQUAL \"Linux\"\n    OR (CMAKE_SYSTEM_NAME STREQUAL \"Windows\"\n        AND (CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\" OR CMAKE_CXX_COMPILER_ID MATCHES \"Clang\")\n    )\n)\n    corrosion_add_target_local_rustflags(rust_bin \"-Clink-arg=-fuse-ld=lld\")\nendif()\n\nif(MSVC)\n    set_target_properties(cxxbridge-cpp PROPERTIES MSVC_RUNTIME_LIBRARY \"MultiThreadedDLL\")\nendif()\n\nif(TEST_CXXBRIDGE_VARIANT1)\n    # Variant 1: Merge the C++ User sources into the generated library target.\n    target_sources(cxxbridge-cpp PRIVATE cpplib.cpp)\n    corrosion_link_libraries(rust_bin cxxbridge-cpp)\nelseif(TEST_CXXBRIDGE_VARIANT2)\n    # Variant 2: Create a separate C++ library and link both the User library and\n    # the generated library into rust\n    add_library(cpp_lib STATIC cpplib.cpp)\n    target_include_directories(cpp_lib PUBLIC \"${CMAKE_CURRENT_LIST_DIR}/include\")\n    target_link_libraries(cpp_lib PUBLIC cxxbridge-cpp)\n    corrosion_link_libraries(rust_bin cpp_lib cxxbridge-cpp)\n    if(MSVC)\n        set_target_properties(cpp_lib PROPERTIES MSVC_RUNTIME_LIBRARY \"MultiThreadedDLL\")\n    endif()\nelse()\n    message(FATAL_ERROR \"Internal test error - required option not defined\")\nendif()\n"
  },
  {
    "path": "test/cxxbridge/cxxbridge_cpp2rust/cpplib.cpp",
    "content": "#include <iostream>\n#include \"cpplib.h\"\n#include \"cxxbridge-cpp/lib.h\"\n#include \"rust/cxx.h\"\n\nRsImage read_image(rust::Str path) {\n    std::cout << \"read_image called\" << std::endl;\n    std::cout << path << std::endl;\n    Rgba c = { 1.0, 2.0, 3.0, 4.0};\n    RsImage v = { 1, 1, c};\n    return v;\n}\nvoid write_image(::rust::Str path, ::RsImage const & image) {\n\n}\n"
  },
  {
    "path": "test/cxxbridge/cxxbridge_cpp2rust/include/cpplib.h",
    "content": "#pragma once\n#include \"cxxbridge-cpp/lib.h\"\n\n::RsImage read_image(::rust::Str path);\nvoid write_image(::rust::Str path, ::RsImage const & image);\n"
  },
  {
    "path": "test/cxxbridge/cxxbridge_cpp2rust/rust/Cargo.toml",
    "content": "[package]\nname = \"rust_bin\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n[lib]\nname = \"cxxbridge_lib\"\n\n[dependencies]\ncxx = \"1.0\"\n"
  },
  {
    "path": "test/cxxbridge/cxxbridge_cpp2rust/rust/src/lib.rs",
    "content": "#[cxx::bridge]\npub mod ffi\n{\n    #[derive(Debug, PartialEq)]\n    pub struct Rgba\n    {\n        r: f32,\n        g: f32,\n        b: f32,\n        a: f32,\n    }\n\n    #[derive(Debug,PartialEq)]\n    pub struct RsImage\n    {\n        width: usize,\n        height: usize,\n        raster: Rgba,\n    }\n    unsafe extern \"C++\"\n    {\n        include!(\"cpplib.h\");\n        pub fn read_image(path: &str) -> RsImage;\n        fn write_image(path: &str, image: &RsImage);\n    }\n}"
  },
  {
    "path": "test/cxxbridge/cxxbridge_cpp2rust/rust/src/main.rs",
    "content": "use cxxbridge_lib::ffi::{RsImage,Rgba,read_image};\n\nfn main() {\n    println!(\"main function\");\n    let expected = RsImage { width: 1, height: 1, raster: Rgba {\n        r: 1.0,\n        g: 2.0,\n        b: 3.0,\n        a: 4.0,\n    }};\n    let actual = read_image(\"dummy path\");\n    println!(\"returned from C++\");\n    assert_eq!(actual, expected)\n}"
  },
  {
    "path": "test/cxxbridge/cxxbridge_exported_impls/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.24)\nproject(test_project VERSION 0.1.0 LANGUAGES CXX)\ninclude(../../test_header.cmake)\nset(CMAKE_CXX_STANDARD 11)\nset(CMAKE_CXX_STANDARD_REQUIRED 1)\n\ncorrosion_import_crate(MANIFEST_PATH rust/Cargo.toml)\ncorrosion_add_cxxbridge(cxxbridge\n    CRATE rust_lib\n    FILES\n        bridge_a.rs\n        bridge_b.rs\n        lib.rs\n)\n\nif(MSVC)\n    set_target_properties(cxxbridge PROPERTIES MSVC_RUNTIME_LIBRARY \"MultiThreadedDLL\")\nendif()\n\nadd_executable(test_main\n    main.cpp\n)\n\ntarget_link_libraries(test_main\n    cxxbridge\n)"
  },
  {
    "path": "test/cxxbridge/cxxbridge_exported_impls/main.cpp",
    "content": "#include \"cxxbridge/lib.h\"\n\n#include <iostream>\n\nint main()\n{\n    auto result = make_result();\n\n    std::cout << static_cast<std::string>(result.ok->message) << std::endl;\n\n    std::cout << \"main function\" << std::endl;\n\n    return 0;\n}"
  },
  {
    "path": "test/cxxbridge/cxxbridge_exported_impls/rust/Cargo.toml",
    "content": "[package]\nname = \"rust_lib\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n[lib]\nname = \"rust_lib\"\ncrate-type = [\"staticlib\"]\n\n[dependencies]\ncxx = \"1.0\"\n"
  },
  {
    "path": "test/cxxbridge/cxxbridge_exported_impls/rust/src/bridge_a.rs",
    "content": "#[cxx::bridge]\npub mod ffi {\n    pub struct OkResult {\n        pub value: bool,\n        pub message: String,\n    }\n\n    pub struct TestResult {\n        pub ok: SharedPtr<OkResult>,\n    }\n\n    impl SharedPtr<OkResult> {}\n\n    extern \"Rust\" {\n        fn make_result() -> Result<TestResult>;\n    }\n}\n\npub fn make_result() -> Result<ffi::TestResult, String> {\n    let now = std::time::Instant::now();\n    let ok = ffi::OkResult { value: true, message: format!(\"{:#?}\", now)};\n    Ok(ffi::TestResult { ok: cxx::SharedPtr::new(ok)} )\n}\n\n"
  },
  {
    "path": "test/cxxbridge/cxxbridge_exported_impls/rust/src/bridge_b.rs",
    "content": "#[cxx::bridge]\npub mod ffi {\n\n    #[derive(Clone)]\n    pub struct NewVal {\n        pub value: bool,\n        pub message: String,\n    }\n\n    impl SharedPtr<NewVal> {}\n\n    extern \"Rust\" {\n        fn make_new_val() -> SharedPtr<NewVal>;\n    }\n}\n\npub fn make_new_val() -> cxx::SharedPtr<ffi::NewVal> {\n    let now = std::time::Instant::now();\n    let ok = ffi::NewVal { value: true, message: format!(\"{:#?}\", now)};\n    cxx::SharedPtr::new(ok)\n}"
  },
  {
    "path": "test/cxxbridge/cxxbridge_exported_impls/rust/src/lib.rs",
    "content": "pub mod bridge_a;\npub mod bridge_b;\n// pub use bridge_a::combine_result;\n\n#[cxx::bridge]\npub mod ffi {\n\n    extern \"C++\" {\n        include!(\"cxxbridge/bridge_a.h\");\n        include!(\"cxxbridge/bridge_b.h\");\n\n        type TestResult = crate::bridge_a::ffi::TestResult;\n        type NewVal = crate::bridge_b::ffi::NewVal;\n    }\n\n    extern \"Rust\" {\n        fn combine_result(other: SharedPtr<NewVal>) -> Result<TestResult>;\n    }\n\n}\n\npub fn combine_result(other: cxx::SharedPtr<crate::bridge_b::ffi::NewVal>) -> Result<ffi::TestResult, String> {\n    if let Some(crate::bridge_b::ffi::NewVal { value, message }) = other.as_ref().cloned() {\n        let result = crate::bridge_a::ffi::TestResult { ok: cxx::SharedPtr::new(crate::bridge_a::ffi::OkResult { value, message }) };\n        Ok(result)\n    }\n    else {\n        crate::bridge_a::make_result()\n    }\n}"
  },
  {
    "path": "test/cxxbridge/cxxbridge_rust2cpp/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\nset(CMAKE_CXX_STANDARD 11)\nset(CMAKE_CXX_STANDARD_REQUIRED 1)\n\ncorrosion_import_crate(MANIFEST_PATH rust/Cargo.toml)\ncorrosion_add_cxxbridge(cxxbridge-cpp CRATE cxxbridge_crate FILES lib.rs foo/mod.rs)\n\nadd_executable(cxxbridge-exe main.cpp)\ntarget_link_libraries(cxxbridge-exe PUBLIC cxxbridge-cpp)\n\nif(MSVC)\n    # Note: This is required because we use `cxx` which uses `cc` to compile and link C++ code.\n    corrosion_set_env_vars(cxxbridge_crate \"CFLAGS=-MDd\" \"CXXFLAGS=-MDd\")\nendif()\n"
  },
  {
    "path": "test/cxxbridge/cxxbridge_rust2cpp/main.cpp",
    "content": "#include <cxxbridge-cpp/foo/mod.h>\n#include <cxxbridge-cpp/lib.h>\n#include <vector>\n\nint main(int argc, char **argv)\n{\n    std::vector<uint64_t> input = { 4, 5, 6};\n    rust::Slice<const ::std::uint64_t> slice{input.data(), input.size()};\n    lib::print(slice);\n    foo::print(slice);\n}\n"
  },
  {
    "path": "test/cxxbridge/cxxbridge_rust2cpp/rust/Cargo.toml",
    "content": "[package]\nname = \"cxxbridge-crate\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n[lib]\ncrate-type = [\"staticlib\"]\n\n[dependencies]\ncxx = \"1.0\"\n"
  },
  {
    "path": "test/cxxbridge/cxxbridge_rust2cpp/rust/src/foo/mod.rs",
    "content": "#[cxx::bridge(namespace = \"foo\")]\nmod bridge {\n    extern \"Rust\" {\n        fn print(slice: &[u64]);\n    }\n}\n\nfn print(slice: &[u64]) {\n    println!(\"Hello cxxbridge from foo/mod.rs! {:?}\", slice);\n}\n"
  },
  {
    "path": "test/cxxbridge/cxxbridge_rust2cpp/rust/src/lib.rs",
    "content": "mod foo;\n\n#[cxx::bridge(namespace = \"lib\")]\nmod bridge {\n    extern \"Rust\" {\n        fn print(slice: &[u64]);\n    }\n}\n\nfn print(slice: &[u64]) {\n    println!(\"Hello cxxbridge from lib.rs! {:?}\", slice);\n}\n"
  },
  {
    "path": "test/envvar/CMakeLists.txt",
    "content": "corrosion_tests_add_test(envvar \"program_requiring_rust_lib_with_envvar\")\n\nset_tests_properties(\"envvar_run_program_requiring_rust_lib_with_envvar\" PROPERTIES PASS_REGULAR_EXPRESSION\n        \"Ok\"\n        )\n"
  },
  {
    "path": "test/envvar/envvar/.cargo/config.toml",
    "content": "[env]\nCOR_CONFIG_TOML_ENV_VAR = \"EnvVariableSetViaConfig.toml\"\n"
  },
  {
    "path": "test/envvar/envvar/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\ncorrosion_import_crate(MANIFEST_PATH Cargo.toml)\n\ncorrosion_set_env_vars(rust_lib_requiring_envvar\n        \"ANOTHER_VARIABLE=ANOTHER_VALUE\"\n        \"$<TARGET_PROPERTY:program_requiring_rust_lib_with_envvar,INDIRECT_VAR_TEST>\"\n        \"COR_CARGO_VERSION_MAJOR=${Rust_CARGO_VERSION_MAJOR}\"\n        \"COR_CARGO_VERSION_MINOR=${Rust_CARGO_VERSION_MINOR}\"\n)\n\nadd_executable(program_requiring_rust_lib_with_envvar main.cpp)\n\nset_property(\n    TARGET program_requiring_rust_lib_with_envvar\n    APPEND\n    PROPERTY INDIRECT_VAR_TEST\n    \"REQUIRED_VARIABLE=EXPECTED_VALUE\"\n)\n\ntarget_link_libraries(program_requiring_rust_lib_with_envvar PUBLIC rust_lib_requiring_envvar)\n"
  },
  {
    "path": "test/envvar/envvar/Cargo.toml",
    "content": "[package]\nname = \"rust-lib-requiring-envvar\"\nversion = \"0.1.0\"\nauthors = [\"Olivier Goffart <ogoffart@sixtyfps.io>\"]\nedition = \"2018\"\nbuild = \"build.rs\"\n\n[lib]\ncrate-type = [ \"lib\", \"cdylib\" ]\n"
  },
  {
    "path": "test/envvar/envvar/build.rs",
    "content": "fn main() {\n    assert_eq!(env!(\"REQUIRED_VARIABLE\"), \"EXPECTED_VALUE\");\n    assert_eq!(std::env::var(\"ANOTHER_VARIABLE\").unwrap(), \"ANOTHER_VALUE\");\n    let cargo_major = env!(\"COR_CARGO_VERSION_MAJOR\")\n        .parse::<u32>()\n        .expect(\"Invalid Major version\");\n    let cargo_minor = env!(\"COR_CARGO_VERSION_MINOR\")\n        .parse::<u32>()\n        .expect(\"Invalid Minor version\");\n\n    // The `[env]` section in `.cargo/config.toml` was added in version 1.56.\n    if cargo_major > 1 || (cargo_major == 1 && cargo_minor >= 56) {\n        // Check if cargo picks up the config.toml, which sets this additional env variable.\n        let env_value = option_env!(\"COR_CONFIG_TOML_ENV_VAR\")\n            .expect(\"Test failure! Cargo >= 1.56.0 should set this environment variable\");\n        assert_eq!(env_value, \"EnvVariableSetViaConfig.toml\");\n    }\n}\n"
  },
  {
    "path": "test/envvar/envvar/main.cpp",
    "content": "#include <iostream>\n\nint main() {\n    std::cout << \"Ok\";\n}\n"
  },
  {
    "path": "test/envvar/envvar/src/lib.rs",
    "content": "#[cfg(test)]\nmod tests {\n    #[test]\n    fn it_works() {\n        assert_eq!(2 + 2, 4);\n    }\n}\n"
  },
  {
    "path": "test/features/CMakeLists.txt",
    "content": "corrosion_tests_add_test(features \"features-cpp-exe\")\n\nset_tests_properties(\"features_run_features-cpp-exe\" PROPERTIES PASS_REGULAR_EXPRESSION\n        \"Hello, Cpp! I'm Rust!\\r?\\nHello, Cpp again! I'm Rust again!\\r?\\nHello, Cpp again! I'm Rust again, third time the charm!\"\n        )\n"
  },
  {
    "path": "test/features/features/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\ncorrosion_import_crate(MANIFEST_PATH rust/Cargo.toml FEATURES thirdfeature ALL_FEATURES)\n\nadd_executable(features-cpp-exe main.cpp)\ntarget_link_libraries(features-cpp-exe PUBLIC rust_feature_lib)\n\ncorrosion_set_features(rust_feature_lib\n        ALL_FEATURES OFF\n        NO_DEFAULT_FEATURES\n        FEATURES\n            $<TARGET_PROPERTY:features-cpp-exe,app_features>\n)\n\nset_property(\n    TARGET features-cpp-exe\n    APPEND\n    PROPERTY app_features myfeature\n)\nset_property(\n    TARGET features-cpp-exe\n    APPEND\n    PROPERTY app_features secondfeature\n)\n\n"
  },
  {
    "path": "test/features/features/main.cpp",
    "content": "extern \"C\" void rust_function(char const *name);\nextern \"C\" void rust_second_function(char const *name);\nextern \"C\" void rust_third_function(char const *name);\n\nint main(int argc, char **argv) {\n    if (argc < 2) {\n        rust_function(\"Cpp\");\n        rust_second_function(\"Cpp again\");\n        rust_third_function(\"Cpp again\");\n    } else {\n        rust_function(argv[1]);\n    }\n}\n"
  },
  {
    "path": "test/features/features/rust/Cargo.toml",
    "content": "[package]\nname = \"rust-feature-lib\"\nversion = \"0.1.0\"\nauthors = [\"Andrew Gaspar <andrew.gaspar@outlook.com>\"]\nlicense = \"MIT\"\nedition = \"2018\"\n\n[dependencies]\n\n[lib]\ncrate-type=[\"staticlib\"]\n\n[features]\ndefault = [\"compile-breakage\"]\nmyfeature = []\nsecondfeature = []\nthirdfeature = []\ncompile-breakage = []"
  },
  {
    "path": "test/features/features/rust/src/lib.rs",
    "content": "#[cfg(feature = \"myfeature\")]\nuse std::os::raw::c_char;\n\n#[no_mangle]\n#[cfg(feature = \"myfeature\")]\npub extern \"C\" fn rust_function(name: *const c_char) {\n    let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() };\n    println!(\"Hello, {}! I'm Rust!\", name);\n}\n\n#[no_mangle]\n#[cfg(feature = \"secondfeature\")]\npub extern \"C\" fn rust_second_function(name: *const c_char) {\n    let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() };\n    println!(\"Hello, {}! I'm Rust again!\", name);\n}\n\n#[no_mangle]\n#[cfg(feature = \"thirdfeature\")]\npub extern \"C\" fn rust_third_function(name: *const c_char) {\n    let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() };\n    println!(\"Hello, {}! I'm Rust again, third time the charm!\", name);\n}\n\n#[cfg(feature = \"compile-breakage\")]\nconst _: [(); 1] = [(); 2]; // Trigger a compile error to make sure that we succeeded in de-activating this feature\n"
  },
  {
    "path": "test/find_rust/CMakeLists.txt",
    "content": "corrosion_tests_add_test(find_rust \"\")\ncorrosion_tests_add_test(rustup_proxy \"\")\n\nfind_program(rustup rustup)\nif(NOT rustup)\n    set_tests_properties(rustup_proxy_build rustup_proxy_cleanup PROPERTIES DISABLED 1)\nendif()\n"
  },
  {
    "path": "test/find_rust/find_rust/CMakeLists.txt",
    "content": "\ncmake_minimum_required(VERSION 3.15)\nproject(FindRust LANGUAGES CXX)\n\nset(CMAKE_MODULE_PATH \"${CMAKE_SOURCE_DIR}/../../../cmake\" ${CMAKE_MODULE_PATH})\n\n# make sure find_package(Rust) can be used more than once\nfind_package(Rust REQUIRED)\nfind_package(Rust REQUIRED)\n"
  },
  {
    "path": "test/find_rust/rustup_proxy/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(RustupProxy LANGUAGES CXX)\n\nset(CMAKE_MODULE_PATH \"${CMAKE_SOURCE_DIR}/../../../cmake\" ${CMAKE_MODULE_PATH})\n\nfunction(_assert_is_rustup_proxy executable_path)\n    execute_process(\n        COMMAND\n            ${CMAKE_COMMAND} -E env\n                RUSTUP_FORCE_ARG0=rustup\n            \"${executable_path}\" --version\n        OUTPUT_VARIABLE _VERSION_RAW\n        ERROR_VARIABLE _VERSION_STDERR\n        RESULT_VARIABLE _VERSION_RESULT\n    )\n\n    if(NOT _VERSION_RESULT EQUAL \"0\")\n        message(FATAL_ERROR \"`${executable_path} --version` failed with ${_VERSION_RESULT}\\n\"\n            \"stderr:\\n${_VERSION_STDERR}\"\n        )\n    endif()\n\n    if (NOT _VERSION_RAW MATCHES \"rustup [0-9\\\\.]+\")\n        message(FATAL_ERROR \"`${executable_path} --version` output does not match rustup: ${_VERSION_RAW}\\n\")\n    endif()\nendfunction()\n\nset(Rust_RESOLVE_RUSTUP_TOOLCHAINS OFF CACHE BOOL \"\" FORCE)\nfind_package(Rust REQUIRED)\n\nif (NOT Rust_FOUND)\n    message(FATAL_ERROR \"Rustup not found\")\nendif()\n\nget_property(\n    RUSTC_EXECUTABLE\n    TARGET Rust::Rustc PROPERTY IMPORTED_LOCATION\n)\n\n_assert_is_rustup_proxy(${RUSTC_EXECUTABLE})\n\nget_property(\n    CARGO_EXECUTABLE\n    TARGET Rust::Cargo PROPERTY IMPORTED_LOCATION\n)\n\n_assert_is_rustup_proxy(${CARGO_EXECUTABLE})\n"
  },
  {
    "path": "test/gensource/CMakeLists.txt",
    "content": "corrosion_tests_add_test(gensource \"\")\n\n#set_tests_properties(\"features_run_features-cpp-exe\" PROPERTIES PASS_REGULAR_EXPRESSION\n#        \"Hello, Cpp! I'm Rust!\\r?\\nHello, Cpp again! I'm Rust again!\\r?\\nHello, Cpp again! I'm Rust again, third time the charm!\"\n#        )"
  },
  {
    "path": "test/gensource/gensource/.gitignore",
    "content": "src/foo.rs\n"
  },
  {
    "path": "test/gensource/gensource/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\nadd_subdirectory(generator)\n\nadd_custom_command(\n\tOUTPUT \"${CMAKE_CURRENT_SOURCE_DIR}/src/foo.rs\"\n\tDEPENDS $<TARGET_FILE:srcgen>\n\tCOMMAND $<TARGET_FILE:srcgen> \"${CMAKE_CURRENT_SOURCE_DIR}/src/foo.rs\"\n)\n\nadd_custom_target(after_generation DEPENDS \"${CMAKE_CURRENT_SOURCE_DIR}/src/foo.rs\")\nadd_custom_target(genexdebug COMMAND ${CMAKE_COMMAND} -E echo \"Config DEBUG: $<TARGET_PROPERTY:srcgen,IMPORTED_LOCATION_DEBUG> Config Release: $<TARGET_PROPERTY:srcgen,IMPORTED_LOCATION_RELEASE> IMPORTED_LOCATION: $<TARGET_PROPERTY:srcgen,IMPORTED_LOCATION>\")\n\ncorrosion_import_crate(MANIFEST_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml)\nadd_dependencies(cargo-prebuild_generated after_generation)\n\n# Simple test for corrosion_parse_package_version\ncorrosion_parse_package_version(\"${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml\" srcgen_version)\nif (NOT \"${srcgen_version}\" VERSION_EQUAL \"0.1.0\")\n\tmessage(FATAL_ERROR \"Test failed to parse expected version\")\nendif()\n"
  },
  {
    "path": "test/gensource/gensource/Cargo.toml",
    "content": "[package]\nname = \"generated\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n[lib]\ncrate-type = [\"lib\", \"cdylib\"]\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "test/gensource/gensource/generator/CMakeLists.txt",
    "content": "corrosion_import_crate(MANIFEST_PATH Cargo.toml)\ncorrosion_set_hostbuild(srcgen)\n"
  },
  {
    "path": "test/gensource/gensource/generator/Cargo.toml",
    "content": "[package]\nname = \"srcgen\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "test/gensource/gensource/generator/src/main.rs",
    "content": "use std::io::Write;\nfn main() -> Result<(), std::io::Error> {\n    let out_name = std::env::args().skip(1).next().unwrap();\n    let mut out_file = std::fs::File::create(out_name)?;\n    Ok(write!(out_file, \"const _: () = ();\")?)\n}\n"
  },
  {
    "path": "test/gensource/gensource/src/lib.rs",
    "content": "mod foo;\n\n#[cfg(test)]\nmod tests {\n    #[test]\n    fn it_works() {\n        let result = 2 + 2;\n        assert_eq!(result, 4);\n    }\n}\n"
  },
  {
    "path": "test/hostbuild/CMakeLists.txt",
    "content": "corrosion_tests_add_test(hostbuild \"rust-host-program\" IS_HOSTBUILD)\n\nset_tests_properties(\"hostbuild_run_rust-host-program\" PROPERTIES PASS_REGULAR_EXPRESSION\n        \"^ok\\r?\\nHello Rust Hostbuild, I am an external C function\"\n        )\n\n"
  },
  {
    "path": "test/hostbuild/hostbuild/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\ncorrosion_import_crate(MANIFEST_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml)\n\ncorrosion_set_hostbuild(rust-host-program)\n"
  },
  {
    "path": "test/hostbuild/hostbuild/Cargo.toml",
    "content": "[package]\nname = \"rust-host-program\"\nversion = \"0.1.0\"\nauthors = [\"Olivier Goffart <ogoffart@sixtyfps.io>\"]\nedition = \"2018\"\n\n[build-dependencies]\ncc = \"1.0\"\n"
  },
  {
    "path": "test/hostbuild/hostbuild/build.rs",
    "content": "fn main() {\n    let out_dir = std::env::var(\"OUT_DIR\").unwrap();\n    cc::Build::new()\n        .file(\"src/lib.c\")\n        .compile(\"hello\");\n\n    println!(\"cargo:rustc-link-search=native={}\", out_dir);\n    println!(\"cargo:rustc-link-lib=hello\");\n    println!(\"cargo:rerun-if-changed=src/lib.c\");\n}"
  },
  {
    "path": "test/hostbuild/hostbuild/src/lib.c",
    "content": "#include <stdio.h>\n\nvoid c_function(char const *name) {\n   printf(\"Hello %s, I am an external C function\\n\", name);\n}\n"
  },
  {
    "path": "test/hostbuild/hostbuild/src/main.rs",
    "content": "use std::os::raw::c_char;\n\nextern \"C\" {\n    fn c_function(name: *const c_char);\n}\n\nfn main() {\n    println!(\"ok\");\n    let name = b\"Rust Hostbuild\\0\";\n    unsafe {\n        c_function(name.as_ptr() as _);\n    }\n}\n"
  },
  {
    "path": "test/multitarget/CMakeLists.txt",
    "content": "corrosion_tests_add_test(multitarget \"bin1;bin2;bin3\")\n\n# Don't run this test in parallel with others, since the target directory size may cause issues.\nset_tests_properties(\"multitarget_build\" PROPERTIES RUN_SERIAL TRUE)\n\nset_tests_properties(\"multitarget_run_bin1\" PROPERTIES PASS_REGULAR_EXPRESSION\n        \"Hello, world!\\r?\\nHello, bin1! I'm Cpp!\"\n        RUN_SERIAL\n        TRUE\n        )\n\nset_tests_properties(\"multitarget_run_bin2\" PROPERTIES PASS_REGULAR_EXPRESSION\n        \"Hello, world!\\r?\\nHello, bin2! I'm Cpp!\"\n        RUN_SERIAL\n        TRUE\n        )\n\nset_tests_properties(\"multitarget_run_bin3\" PROPERTIES PASS_REGULAR_EXPRESSION\n        \"Hello, world!\\r?\\nHello, bin3! I'm Cpp!\"\n        RUN_SERIAL\n        TRUE\n        )\n"
  },
  {
    "path": "test/multitarget/multitarget/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\ncorrosion_import_crate(MANIFEST_PATH Cargo.toml)\n\nadd_library(cpp-lib4 lib.cpp)\ntarget_compile_features(cpp-lib4 PRIVATE cxx_std_14)\nset_property(TARGET cpp-lib4 PROPERTY POSITION_INDEPENDENT_CODE ON)\ncorrosion_link_libraries(bin1 cpp-lib4)\ncorrosion_link_libraries(bin2 cpp-lib4)\ncorrosion_link_libraries(bin3 cpp-lib4)\n"
  },
  {
    "path": "test/multitarget/multitarget/Cargo.toml",
    "content": "[package]\nname = \"multitarget-crate\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n[dependencies]\n\n[lib]\nname = \"multitarget_lib\"\ncrate-type=[\"lib\", \"staticlib\", \"cdylib\"]\n\n[[bin]]\nname = \"bin1\"\n\n[[bin]]\nname = \"bin2\"\n\n[[bin]]\nname = \"bin3\"\n"
  },
  {
    "path": "test/multitarget/multitarget/lib.cpp",
    "content": "#include <iostream>\n\nextern \"C\" void cpp_function(char const *name) {\n    std::cout << \"Hello, \" << name << \"! I'm Cpp!\\n\";\n}\n"
  },
  {
    "path": "test/multitarget/multitarget/src/bin/bin1.rs",
    "content": "use multitarget_lib::hello_world;\n\nfn main() {\n    hello_world();\n    unsafe {\n        multitarget_lib::cpp_function(\"bin1\\0\".as_ptr() as *const _);\n    }\n}\n"
  },
  {
    "path": "test/multitarget/multitarget/src/bin/bin2.rs",
    "content": "use multitarget_lib::hello_world;\n\nfn main() {\n    hello_world();\n    unsafe {\n        multitarget_lib::cpp_function(\"bin2\\0\".as_ptr() as *const _);\n    }\n}\n"
  },
  {
    "path": "test/multitarget/multitarget/src/bin/bin3.rs",
    "content": "use multitarget_lib::hello_world;\n\nfn main() {\n    hello_world();\n    unsafe {\n        multitarget_lib::cpp_function(\"bin3\\0\".as_ptr() as *const _);\n    }\n}\n"
  },
  {
    "path": "test/multitarget/multitarget/src/lib.rs",
    "content": "use std::os::raw::c_char;\n\npub fn hello_world() {\n    println!(\"Hello, world!\");\n}\n\nextern \"C\" {\n    pub fn cpp_function(name: *const c_char);\n}\n"
  },
  {
    "path": "test/nostd/CMakeLists.txt",
    "content": "corrosion_tests_add_test(nostd \"\")\n"
  },
  {
    "path": "test/nostd/nostd/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\ncorrosion_import_crate(MANIFEST_PATH rust/Cargo.toml NO_STD)\n\nset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -nostdlib\")\nlist(REMOVE_ITEM CMAKE_CXX_IMPLICIT_LINK_LIBRARIES stdc++)\n\nadd_library(nostd-cpp-lib STATIC main.cpp)\ntarget_link_libraries(nostd-cpp-lib PUBLIC rust-nostd-lib)\n"
  },
  {
    "path": "test/nostd/nostd/main.cpp",
    "content": "extern \"C\" void rust_function();\n\nextern \"C\" void cpp_function() {\n    // Fail on linking issues\n    rust_function();\n}"
  },
  {
    "path": "test/nostd/nostd/rust/Cargo.toml",
    "content": "[package]\nname = \"rust-nostd-lib\"\nversion = \"0.1.0\"\nedition = \"2015\"\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n\n[lib]\ncrate-type=[\"staticlib\"]\n\n[profile.release]\npanic = \"abort\"\n\n[profile.dev]\npanic = \"abort\"\n"
  },
  {
    "path": "test/nostd/nostd/rust/src/lib.rs",
    "content": "#![no_std]\nuse core::panic::PanicInfo;\n\n#[no_mangle]\npub extern \"C\" fn rust_function() {}\n\n#[panic_handler]\nfn panic(_panic: &PanicInfo<'_>) -> ! {\n    loop {}\n}"
  },
  {
    "path": "test/output directory/CMakeLists.txt",
    "content": "set(configure_cmake_args)\nif(CMAKE_C_COMPILER)\n    list(APPEND configure_cmake_args \"C_COMPILER\" \"${CMAKE_C_COMPILER}\")\nendif()\nif(CMAKE_CXX_COMPILER)\n    list(APPEND configure_cmake_args \"CXX_COMPILER\" \"${CMAKE_CXX_COMPILER}\")\nendif()\nif(CMAKE_C_COMPILER_TARGET)\n    list(APPEND configure_cmake_args \"C_COMPILER_TARGET\" \"${CMAKE_C_COMPILER_TARGET}\")\nendif()\nif(CMAKE_CXX_COMPILER_TARGET)\n    list(APPEND configure_cmake_args \"CXX_COMPILER_TARGET\" \"${CMAKE_CXX_COMPILER_TARGET}\")\nendif()\nif(CMAKE_GENERATOR_PLATFORM)\n    list(APPEND configure_cmake_args \"GENERATOR_PLATFORM\" \"${CMAKE_GENERATOR_PLATFORM}\")\nendif()\nif(CMAKE_OSX_ARCHITECTURES)\n    list(APPEND configure_cmake_args OSX_ARCHITECTURES \"${CMAKE_OSX_ARCHITECTURES}\")\nendif()\nif(CMAKE_OSX_SYSROOT)\n    list(APPEND configure_cmake_args OSX_SYSROOT \"${CMAKE_OSX_SYSROOT}\")\nendif()\nif(CMAKE_TOOLCHAIN_FILE)\n    list(APPEND configure_cmake_args TOOLCHAIN_FILE \"${CMAKE_TOOLCHAIN_FILE}\")\nendif()\n\nadd_test(NAME \"output_directory_build\"\n    COMMAND\n        ${CMAKE_COMMAND}\n        -P \"${CMAKE_SOURCE_DIR}/test/ConfigureAndBuild.cmake\"\n        SOURCE_DIR \"${CMAKE_CURRENT_SOURCE_DIR}/output directory\"\n        BINARY_DIR \"${CMAKE_CURRENT_BINARY_DIR}/build\"\n        GENERATOR \"${CMAKE_GENERATOR}\"\n        RUST_TOOLCHAIN \"${Rust_TOOLCHAIN}\"\n        CARGO_TARGET \"${Rust_CARGO_TARGET}\"\n        SYSTEM_NAME \"${CMAKE_SYSTEM_NAME}\"\n        ${configure_cmake_args}\n        COMMAND_EXPAND_LISTS\n)\nset_tests_properties(\"output_directory_build\" PROPERTIES FIXTURES_SETUP \"build_fixture_output_directory\")\nif(CORROSION_TESTS_INSTALL_CORROSION)\n    set_tests_properties(\"output_directory_build\" PROPERTIES FIXTURES_REQUIRED \"fixture_corrosion_install\")\nendif()\n\nget_cmake_property(IS_MULTI_CONFIG GENERATOR_IS_MULTI_CONFIG)\n\nif (IS_MULTI_CONFIG)\n    set(config_path_str \"$<CONFIG>/\")\nelse()\n    set(config_path_str \"\")\nendif()\n\nforeach(output_approach targetprop var targetprop_pdb_fallback)\n    if(output_approach STREQUAL \"targetprop\")\n       set(rust_proj_suffix \"1\")\n    elseif(output_approach STREQUAL \"var\")\n        set(rust_proj_suffix \"2\")\n    elseif(output_approach STREQUAL \"targetprop_pdb_fallback\")\n        set(rust_proj_suffix \"3\")\n    else()\n        message(FATAL_ERROR \"specify rust project suffix for new output approach ${output_approach}\")\n    endif()\n\n    set(bin_name \"rust_bin${rust_proj_suffix}${CMAKE_EXECUTABLE_SUFFIX}\")\n\n    add_test(NAME output_directory_bin_${output_approach}\n            COMMAND\n            \"${CMAKE_COMMAND}\"\n            -P \"${CMAKE_CURRENT_SOURCE_DIR}/../TestFileExists.cmake\"\n            \"${CMAKE_CURRENT_BINARY_DIR}/build/custom_bin_${output_approach}/${config_path_str}${bin_name}\"\n    )\n    set_tests_properties(\"output_directory_bin_${output_approach}\" PROPERTIES FIXTURES_REQUIRED \"build_fixture_output_directory\")\n\n    set(lib_name \"rust_lib${rust_proj_suffix}\")\n\n    set(static_lib_name \"${CMAKE_STATIC_LIBRARY_PREFIX}${lib_name}${CMAKE_STATIC_LIBRARY_SUFFIX}\")\n\n    add_test(NAME output_directory_staticlib_${output_approach}\n            COMMAND\n            \"${CMAKE_COMMAND}\"\n            -P \"${CMAKE_CURRENT_SOURCE_DIR}/../TestFileExists.cmake\"\n            \"${CMAKE_CURRENT_BINARY_DIR}/build/custom_archive_${output_approach}/${config_path_str}${static_lib_name}\"\n    )\n    set_tests_properties(\"output_directory_staticlib_${output_approach}\" PROPERTIES FIXTURES_REQUIRED \"build_fixture_output_directory\")\n\n    if(MINGW)\n        # Windows-GNU defines \"lib\" as prefix for DLLs, but cargo creates foo.dll instead of libfoo.dll\n        set(dynamic_lib_prefix \"\")\n    else()\n        set(dynamic_lib_prefix \"${CMAKE_SHARED_LIBRARY_PREFIX}\")\n    endif()\n    set(dynamic_lib_name \"${dynamic_lib_prefix}${lib_name}${CMAKE_SHARED_LIBRARY_SUFFIX}\")\n\n    add_test(NAME output_directory_cdylib_${output_approach}\n            COMMAND\n            \"${CMAKE_COMMAND}\"\n            -P \"${CMAKE_CURRENT_SOURCE_DIR}/../TestFileExists.cmake\"\n            \"${CMAKE_CURRENT_BINARY_DIR}/build/custom_lib_${output_approach}/${config_path_str}${dynamic_lib_name}\"\n    )\n    set_tests_properties(\"output_directory_cdylib_${output_approach}\" PROPERTIES FIXTURES_REQUIRED \"build_fixture_output_directory\")\n\n    if(WIN32)\n        set(implib_name ${CMAKE_IMPORT_LIBRARY_PREFIX}${lib_name}${CMAKE_IMPORT_LIBRARY_SUFFIX})\n\n        add_test(NAME output_directory_implib_${output_approach}\n            COMMAND\n            \"${CMAKE_COMMAND}\"\n            -P \"${CMAKE_CURRENT_SOURCE_DIR}/../TestFileExists.cmake\"\n            # Implib is an ARCHIVE artifact, see:\n            # https://cmake.org/cmake/help/v3.25/manual/cmake-buildsystem.7.html#archive-output-artifacts\n            \"${CMAKE_CURRENT_BINARY_DIR}/build/custom_archive_${output_approach}/${config_path_str}${implib_name}\"\n            )\n        set_tests_properties(\"output_directory_implib_${output_approach}\" PROPERTIES FIXTURES_REQUIRED \"build_fixture_output_directory\")\n\n        if(MSVC)\n            if(output_approach STREQUAL \"targetprop\")\n                set(expected_lib_pdb_path \"custom_lib_pdb_targetprop\")\n                set(expected_bin_pdb_path \"custom_bin_pdb_targetprop\")\n            elseif(output_approach STREQUAL \"var\")\n                # When using a CMAKE_ variable instead of a target property, both targets\n                # end up in the same directory.\n                set(expected_lib_pdb_path \"custom_binlib_pdb_var\")\n                set(expected_bin_pdb_path \"custom_binlib_pdb_var\")\n            elseif(output_approach STREQUAL \"targetprop_pdb_fallback\")\n                set(expected_lib_pdb_path \"custom_lib_targetprop_pdb_fallback\")\n                set(expected_bin_pdb_path \"custom_bin_targetprop_pdb_fallback\")\n            else()\n                message(FATAL_ERROR \"specify rust project suffix for new output approach ${output_approach}\")\n            endif()\n\n            set(lib_pdb_name \"${lib_name}.pdb\")\n            add_test(NAME output_directory_cdylib_pdb_${output_approach}\n                COMMAND\n                \"${CMAKE_COMMAND}\"\n                -P \"${CMAKE_CURRENT_SOURCE_DIR}/../TestFileExists.cmake\"\n                \"${CMAKE_CURRENT_BINARY_DIR}/build/${expected_lib_pdb_path}/${config_path_str}${lib_pdb_name}\"\n                )\n            set_tests_properties(\"output_directory_cdylib_pdb_${output_approach}\" PROPERTIES FIXTURES_REQUIRED \"build_fixture_output_directory\")\n\n            set(bin_pdb_name \"rust_bin${rust_proj_suffix}.pdb\")\n            add_test(NAME output_directory_bin_pdb_${output_approach}\n                COMMAND\n                \"${CMAKE_COMMAND}\"\n                -P \"${CMAKE_CURRENT_SOURCE_DIR}/../TestFileExists.cmake\"\n                \"${CMAKE_CURRENT_BINARY_DIR}/build/${expected_bin_pdb_path}/${config_path_str}${bin_pdb_name}\"\n                )\n            set_tests_properties(\"output_directory_bin_pdb_${output_approach}\" PROPERTIES FIXTURES_REQUIRED \"build_fixture_output_directory\")\n        endif()\n    endif()\n\nendforeach()\n\nadd_test(NAME postbuild_custom_command\n    COMMAND\n    \"${CMAKE_COMMAND}\"\n    -P \"${CMAKE_CURRENT_SOURCE_DIR}/../TestFileExists.cmake\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/build/another_dir/moved_bin\"\n    )\nset_tests_properties(\"postbuild_custom_command\" PROPERTIES FIXTURES_REQUIRED \"build_fixture_output_directory\")\n\nadd_test(NAME \"output_directory_cleanup\" COMMAND \"${CMAKE_COMMAND}\" -E remove_directory \"${CMAKE_CURRENT_BINARY_DIR}/build\")\nset_tests_properties(\"output_directory_cleanup\" PROPERTIES FIXTURES_CLEANUP \"build_fixture_output_directory\")\n\n####################################\n# output_directory_config\n####################################\n\n\n corrosion_tests_add_test(output_directory_config \"consumer\")\n\n set_tests_properties(\"output_directory_config_run_consumer\" PROPERTIES PASS_REGULAR_EXPRESSION\n         \"^Hello from output_directory_config_test_executable\"\n    )\n\n"
  },
  {
    "path": "test/output directory/output directory/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\ncorrosion_import_crate(MANIFEST_PATH proj1/Cargo.toml)\n\n# Note: The output directories defined here must be manually kept in sync with the expected test location.\nset_target_properties(rust_bin1\n    PROPERTIES\n        RUNTIME_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/custom_bin_targetprop\"\n        PDB_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/custom_bin_pdb_targetprop\"\n\n)\nset_target_properties(rust_lib1 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/custom_archive_targetprop\")\nset_target_properties(rust_lib1\n    PROPERTIES\n        LIBRARY_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/custom_lib_targetprop\"\n        PDB_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/custom_lib_pdb_targetprop\"\n)\n\nadd_custom_command(TARGET cargo-build_rust_bin1 POST_BUILD\n    COMMAND\n    ${CMAKE_COMMAND} -E make_directory \"${CMAKE_CURRENT_BINARY_DIR}/another_dir\"\n    COMMAND\n    ${CMAKE_COMMAND} -E copy_if_different \"$<TARGET_PROPERTY:rust_bin1,LOCATION_$<CONFIG>>\" \"${CMAKE_CURRENT_BINARY_DIR}/another_dir/moved_bin\"\n    )\n\nset(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/custom_bin_var\")\nset(CMAKE_PDB_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/custom_binlib_pdb_var\")\nset(CMAKE_ARCHIVE_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/custom_archive_var\")\nset(CMAKE_LIBRARY_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/custom_lib_var\")\n\ncorrosion_import_crate(MANIFEST_PATH proj2/Cargo.toml)\n\nunset(CMAKE_RUNTIME_OUTPUT_DIRECTORY)\nunset(CMAKE_PDB_OUTPUT_DIRECTORY)\nunset(CMAKE_ARCHIVE_OUTPUT_DIRECTORY)\nunset(CMAKE_LIBRARY_OUTPUT_DIRECTORY)\nunset(CMAKE_PDB_OUTPUT_DIRECTORY)\n\nadd_executable(consumer consumer.cpp)\nadd_dependencies(consumer cargo-build_rust_lib1 cargo-build_rust_lib2)\n\ntarget_link_libraries(consumer rust_lib1 rust_lib2)\n\n\ncorrosion_import_crate(MANIFEST_PATH proj3/Cargo.toml)\n\n# Note: The output directories defined here must be manually kept in sync with the expected test location.\nset_target_properties(rust_bin3\n                      PROPERTIES\n                      RUNTIME_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/custom_bin_targetprop_pdb_fallback\"\n)\nset_target_properties(rust_lib3\n                      PROPERTIES\n                      ARCHIVE_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/custom_archive_targetprop_pdb_fallback\"\n                      LIBRARY_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/custom_lib_targetprop_pdb_fallback\"\n)\n"
  },
  {
    "path": "test/output directory/output directory/consumer.cpp",
    "content": "#include <iostream>\n#include <cstdlib>\n\nextern \"C\" unsigned int ret_12();\n\n\nint main(int argc, char *argv[])\n{\n    std::cout << \"HI\\n\";\n    unsigned int a = ret_12();\n    if (a != 12) {\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "test/output directory/output directory/proj1/Cargo.toml",
    "content": "[package]\nname = \"rust_package1\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n[lib]\nname = \"rust_lib1\"\ncrate-type=[\"staticlib\", \"cdylib\"]\n\n[[bin]]\nname = \"rust_bin1\"\n"
  },
  {
    "path": "test/output directory/output directory/proj1/src/bin/rust_bin1.rs",
    "content": "fn main() {\n    println!(\"Hello, world from test rust binary\");\n}\n"
  },
  {
    "path": "test/output directory/output directory/proj1/src/lib.rs",
    "content": "#[no_mangle]\npub extern \"C\" fn ret_12() -> u32 {\n    12\n}\n"
  },
  {
    "path": "test/output directory/output directory/proj2/Cargo.toml",
    "content": "[package]\nname = \"rust_package2\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n[lib]\nname = \"rust_lib2\"\ncrate-type=[\"staticlib\", \"cdylib\"]\n\n[[bin]]\nname = \"rust_bin2\"\n"
  },
  {
    "path": "test/output directory/output directory/proj2/src/bin/rust_bin2.rs",
    "content": "fn main() {\n    println!(\"Hello, world from test rust binary\");\n}\n"
  },
  {
    "path": "test/output directory/output directory/proj2/src/lib.rs",
    "content": "#[no_mangle]\npub extern \"C\" fn ret_12() -> u32 {\n    12\n}\n"
  },
  {
    "path": "test/output directory/output directory/proj3/Cargo.toml",
    "content": "[package]\nname = \"rust_package3\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n[lib]\nname = \"rust_lib3\"\ncrate-type=[\"staticlib\", \"cdylib\"]\n\n[[bin]]\nname = \"rust_bin3\"\n"
  },
  {
    "path": "test/output directory/output directory/proj3/src/bin/rust_bin3.rs",
    "content": "fn main() {\n    println!(\"Hello, world from test rust binary\");\n}\n"
  },
  {
    "path": "test/output directory/output directory/proj3/src/lib.rs",
    "content": "#[no_mangle]\npub extern \"C\" fn ret_12() -> u32 {\n    12\n}\n"
  },
  {
    "path": "test/output directory/output_directory_config/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\ncorrosion_import_crate(MANIFEST_PATH proj1/Cargo.toml)\n\n# Note: The output directories defined here must be manually kept in sync with the expected test location.\nset_target_properties(rust_bin1\n    PROPERTIES\n        RUNTIME_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/bin\"\n        PDB_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/bin\"\n)\n\nset_target_properties(rust_lib1 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/lib\")\nset_target_properties(rust_lib1\n                      PROPERTIES\n                      LIBRARY_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/lib\"\n                      PDB_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/lib\"\n)\n\nadd_executable(consumer consumer.cpp)\nadd_dependencies(consumer cargo-build_rust_lib1)\ntarget_link_libraries(consumer rust_lib1)\n"
  },
  {
    "path": "test/output directory/output_directory_config/consumer.cpp",
    "content": "#include <iostream>\n#include <cstdlib>\n\nextern \"C\" unsigned int ret_12();\n\n\nint main(int argc, char *argv[])\n{\n    std::cout << \"Hello from output_directory_config_test_executable\\n\";\n    unsigned int a = ret_12();\n    if (a != 12) {\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "test/output directory/output_directory_config/proj1/Cargo.toml",
    "content": "[package]\nname = \"rust_package1\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n[lib]\nname = \"rust_lib1\"\ncrate-type=[\"staticlib\", \"cdylib\"]\n\n[[bin]]\nname = \"rust_bin1\"\n"
  },
  {
    "path": "test/output directory/output_directory_config/proj1/src/bin/rust_bin1.rs",
    "content": "fn main() {\n    println!(\"Hello, world from test rust binary\");\n}\n"
  },
  {
    "path": "test/output directory/output_directory_config/proj1/src/lib.rs",
    "content": "#[no_mangle]\npub extern \"C\" fn ret_12() -> u32 {\n    12\n}\n"
  },
  {
    "path": "test/override_crate_type/CMakeLists.txt",
    "content": "corrosion_tests_add_test(override_crate_type \"cpp-exe;cpp-exe-shared\")\n\nset_tests_properties(\"override_crate_type_run_cpp-exe\" PROPERTIES PASS_REGULAR_EXPRESSION\n        \"^Hello, Cpp! I'm Rust!\\r?\\n$\"\n        )\n\nset_tests_properties(\"override_crate_type_run_cpp-exe-shared\" PROPERTIES PASS_REGULAR_EXPRESSION\n        \"^Hello, Cpp! I'm Rust!\\r?\\n$\"\n        )\n"
  },
  {
    "path": "test/override_crate_type/override_crate_type/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\ncorrosion_import_crate(MANIFEST_PATH rust/Cargo.toml OVERRIDE_CRATE_TYPE my_rust_lib=staticlib,cdylib)\n\nadd_executable(cpp-exe main.cpp)\ntarget_link_libraries(cpp-exe PUBLIC my_rust_lib)\n\nadd_executable(cpp-exe-shared main.cpp)\ntarget_link_libraries(cpp-exe-shared\n        PUBLIC my_rust_lib-shared)\n"
  },
  {
    "path": "test/override_crate_type/override_crate_type/main.cpp",
    "content": "extern \"C\" void rust_function(char const *name);\n\nint main(int argc, char **argv) {\n    if (argc < 2) {\n        rust_function(\"Cpp\");\n    } else {\n        rust_function(argv[1]);\n    }\n}\n"
  },
  {
    "path": "test/override_crate_type/override_crate_type/rust/Cargo.toml",
    "content": "[package]\nname = \"rust-lib\"\nversion = \"0.1.0\"\nauthors = [\"Andrew Gaspar <andrew.gaspar@outlook.com>\"]\nlicense = \"MIT\"\nedition = \"2018\"\n\n\n[lib]\nname = \"my_rust_lib\"\n"
  },
  {
    "path": "test/override_crate_type/override_crate_type/rust/build.rs",
    "content": "// Build-scripts also need to be linked, so just add a dummy buildscript ensuring this works.\nfn main() {\n    println!(\"Build-script is running.\")\n}\n"
  },
  {
    "path": "test/override_crate_type/override_crate_type/rust/src/lib.rs",
    "content": "use std::os::raw::c_char;\n\n#[no_mangle]\npub extern \"C\" fn rust_function(name: *const c_char) {\n    let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() };\n    println!(\"Hello, {}! I'm Rust!\", name);\n}\n"
  },
  {
    "path": "test/parse_target_triple/CMakeLists.txt",
    "content": "corrosion_tests_add_test(parse_target_triple \"\")\ncorrosion_tests_add_test(parse_target_triple_should_fail \"\")\n\nset_tests_properties(\"parse_target_triple_build\" PROPERTIES FAIL_REGULAR_EXPRESSION\n         \"CMake Warning at [^\\r\\n]*FindRust\\.cmake:.*(\\r)?\\n[ \\t]*Failed to parse target-triple `\"\n        )\n\nset_tests_properties(\"parse_target_triple_should_fail_build\" PROPERTIES PASS_REGULAR_EXPRESSION\n         \"CMake Warning at [^\\r\\n]*FindRust\\.cmake:.*(\\r)?\\n[ \\t]*Failed to parse target-triple `\"\n    )\n"
  },
  {
    "path": "test/parse_target_triple/parse_target_triple/CMakeLists.txt",
    "content": "# This test is supposed to ensure that the regex in _corrosion_parse_platform works as expected.\ncmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\n# Todo: Test if the output matches expectations.\n_corrosion_parse_target_triple(\"../../blah/x86_64-unknown-custom-gnu.json\" arch vendor os env)\n_corrosion_parse_target_triple(\"x86_64-unknown-custom-gnu.json\" arch vendor os env)\n_corrosion_parse_target_triple(\"/path/to/x86_64-unknown-custom-musl.json\" arch vendor os env)\n_corrosion_parse_target_triple(\"../../blah/x86_64-custom_os.json\" arch vendor os env)\n\n# List of builtin targets aquired via `rustup target list` with rust 1.64 on Linux.\nset(rustup_shipped_targets\n        \"aarch64-apple-darwin\"\n        \"aarch64-apple-ios\"\n        \"aarch64-apple-ios-sim\"\n        \"aarch64-fuchsia\"\n        \"aarch64-linux-android\"\n        \"aarch64-pc-windows-msvc\"\n        \"aarch64-unknown-linux-gnu\"\n        \"aarch64-unknown-linux-musl\"\n        \"aarch64-unknown-none\"\n        \"aarch64-unknown-none-softfloat\"\n        \"arm-linux-androideabi\"\n        \"arm-unknown-linux-gnueabi\"\n        \"arm-unknown-linux-gnueabihf\"\n        \"arm-unknown-linux-musleabi\"\n        \"arm-unknown-linux-musleabihf\"\n        \"armebv7r-none-eabi\"\n        \"armebv7r-none-eabihf\"\n        \"armv5te-unknown-linux-gnueabi\"\n        \"armv5te-unknown-linux-musleabi\"\n        \"armv7-linux-androideabi\"\n        \"armv7-unknown-linux-gnueabi\"\n        \"armv7-unknown-linux-gnueabihf\"\n        \"armv7-unknown-linux-musleabi\"\n        \"armv7-unknown-linux-musleabihf\"\n        \"armv7a-none-eabi\"\n        \"armv7r-none-eabi\"\n        \"armv7r-none-eabihf\"\n        \"asmjs-unknown-emscripten\"\n        \"i586-pc-windows-msvc\"\n        \"i586-unknown-linux-gnu\"\n        \"i586-unknown-linux-musl\"\n        \"i686-linux-android\"\n        \"i686-pc-windows-gnu\"\n        \"i686-pc-windows-msvc\"\n        \"i686-unknown-freebsd\"\n        \"i686-unknown-linux-gnu\"\n        \"i686-unknown-linux-musl\"\n        \"mips-unknown-linux-gnu\"\n        \"mips-unknown-linux-musl\"\n        \"mips64-unknown-linux-gnuabi64\"\n        \"mips64-unknown-linux-muslabi64\"\n        \"mips64el-unknown-linux-gnuabi64\"\n        \"mips64el-unknown-linux-muslabi64\"\n        \"mipsel-unknown-linux-gnu\"\n        \"mipsel-unknown-linux-musl\"\n        \"nvptx64-nvidia-cuda\"\n        \"powerpc-unknown-linux-gnu\"\n        \"powerpc64-unknown-linux-gnu\"\n        \"powerpc64le-unknown-linux-gnu\"\n        \"riscv32i-unknown-none-elf\"\n        \"riscv32imac-unknown-none-elf\"\n        \"riscv32imc-unknown-none-elf\"\n        \"riscv64gc-unknown-linux-gnu\"\n        \"riscv64gc-unknown-none-elf\"\n        \"riscv64imac-unknown-none-elf\"\n        \"s390x-unknown-linux-gnu\"\n        \"sparc64-unknown-linux-gnu\"\n        \"sparcv9-sun-solaris\"\n        \"thumbv6m-none-eabi\"\n        \"thumbv7em-none-eabi\"\n        \"thumbv7em-none-eabihf\"\n        \"thumbv7m-none-eabi\"\n        \"thumbv7neon-linux-androideabi\"\n        \"thumbv7neon-unknown-linux-gnueabihf\"\n        \"thumbv8m.base-none-eabi\"\n        \"thumbv8m.main-none-eabi\"\n        \"thumbv8m.main-none-eabihf\"\n        \"wasm32-unknown-emscripten\"\n        \"wasm32-unknown-unknown\"\n        \"wasm32-wasi\"\n        \"x86_64-apple-darwin\"\n        \"x86_64-apple-ios\"\n        \"x86_64-fortanix-unknown-sgx\"\n        \"x86_64-fuchsia\"\n        \"x86_64-linux-android\"\n        \"x86_64-pc-solaris\"\n        \"x86_64-pc-windows-gnu\"\n        \"x86_64-pc-windows-msvc\"\n        \"x86_64-sun-solaris\"\n        \"x86_64-unknown-freebsd\"\n        \"x86_64-unknown-illumos\"\n        \"x86_64-unknown-linux-gnu\"\n        \"x86_64-unknown-linux-gnux32\"\n        \"x86_64-unknown-linux-musl\"\n        \"x86_64-unknown-netbsd\"\n        \"x86_64-unknown-none\"\n        \"x86_64-unknown-redox\"\n)\nset(other_targets riscv32imc-esp-espidf xtensa-esp32s3-none-elf)\n\nforeach(target ${rustup_shipped_targets} ${other_targets})\n    _corrosion_parse_target_triple(\"${target}\"  arch vendor os env)\nendforeach()\n"
  },
  {
    "path": "test/parse_target_triple/parse_target_triple_should_fail/CMakeLists.txt",
    "content": "# This test is supposed to ensure that the regex in _corrosion_parse_platform works as expected.\ncmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\n_corrosion_parse_target_triple(\"x86_64-unknown-linux-gnu-toomuch\" arch vendor os env)\n"
  },
  {
    "path": "test/rust2cpp/CMakeLists.txt",
    "content": "corrosion_tests_add_test(rust2cpp \"cpp-exe;cpp-exe-shared\")\n\nset_tests_properties(\"rust2cpp_run_cpp-exe\" PROPERTIES PASS_REGULAR_EXPRESSION\n        \"^Hello, Cpp! I'm Rust!\\r?\\n$\"\n        )\n\nset_tests_properties(\"rust2cpp_run_cpp-exe-shared\" PROPERTIES PASS_REGULAR_EXPRESSION\n        \"^Hello, Cpp! I'm Rust!\\r?\\n$\"\n        )\n"
  },
  {
    "path": "test/rust2cpp/rust2cpp/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\ncorrosion_import_crate(MANIFEST_PATH rust/Cargo.toml)\n\nadd_executable(cpp-exe main.cpp)\ntarget_link_libraries(cpp-exe PUBLIC rust_lib)\n\nadd_executable(cpp-exe-shared main.cpp)\ntarget_link_libraries(cpp-exe-shared\n        PUBLIC rust_lib-shared)\n"
  },
  {
    "path": "test/rust2cpp/rust2cpp/main.cpp",
    "content": "extern \"C\" void rust_function(char const *name);\n\nint main(int argc, char **argv) {\n    if (argc < 2) {\n        rust_function(\"Cpp\");\n    } else {\n        rust_function(argv[1]);\n    }\n}\n"
  },
  {
    "path": "test/rust2cpp/rust2cpp/rust/Cargo.toml",
    "content": "[package]\nname = \"rust-lib\"\nversion = \"0.1.0\"\nauthors = [\"Andrew Gaspar <andrew.gaspar@outlook.com>\"]\nlicense = \"MIT\"\nedition = \"2018\"\n\n[dependencies]\n\n[lib]\ncrate-type=[\"staticlib\", \"cdylib\"]\n"
  },
  {
    "path": "test/rust2cpp/rust2cpp/rust/build.rs",
    "content": "// Build-scripts also need to be linked, so just add a dummy buildscript ensuring this works.\nfn main() {\n    println!(\"Build-script is running.\")\n}\n"
  },
  {
    "path": "test/rust2cpp/rust2cpp/rust/src/lib.rs",
    "content": "use std::os::raw::c_char;\n\n#[no_mangle]\npub extern \"C\" fn rust_function(name: *const c_char) {\n    let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() };\n    println!(\"Hello, {}! I'm Rust!\", name);\n}\n"
  },
  {
    "path": "test/rustflags/CMakeLists.txt",
    "content": "corrosion_tests_add_test(rustflags \"rustflags-cpp-exe\")\n\nset_tests_properties(\"rustflags_run_rustflags-cpp-exe\" PROPERTIES PASS_REGULAR_EXPRESSION\n        \"Hello, Cpp! I'm Rust!\\r?\\nHello, Cpp again! I'm Rust in (Debug|Release) mode again!\\r?\\nHello, Cpp again! I'm Rust again, third time the charm!\\r?\\n$\"\n        )\n\ncorrosion_tests_add_test(cargo_config_rustflags \"cargo_config_rustflags\")\n"
  },
  {
    "path": "test/rustflags/cargo_config_rustflags/.cargo/config.toml",
    "content": "[build]\nrustflags = [\"--cfg=some_cargo_config_rustflag\"]\n"
  },
  {
    "path": "test/rustflags/cargo_config_rustflags/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\ncorrosion_import_crate(MANIFEST_PATH Cargo.toml)\n\n# Do not use `corrosion_add_target_rustflags()` here, since we want to test if the rustflag from `.cargo/config.toml`\n# is picked up.\n\n# Local rustflags should not interfere with `.cargo/config.toml`, so enable one.\ncorrosion_add_target_local_rustflags(cargo_config_rustflags \"--cfg=local_rustflag\")\n"
  },
  {
    "path": "test/rustflags/cargo_config_rustflags/Cargo.toml",
    "content": "[package]\nname = \"cargo_config_rustflags\"\nversion = \"0.1.0\"\nedition = \"2018\"\n"
  },
  {
    "path": "test/rustflags/cargo_config_rustflags/src/main.rs",
    "content": "\n#[cfg(some_cargo_config_rustflag)]\nfn print_line() {\n    println!(\"Rustflag is enabled\");\n}\n\n// test that local rustflags don't override global rustflags set via `.cargo/config`\n#[cfg(local_rustflag)]\nfn test_local_rustflag() {\n    println!(\"local_rustflag was enabled\");\n}\n\nfn main() {\n    print_line();\n    test_local_rustflag();\n}\n"
  },
  {
    "path": "test/rustflags/rustflags/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\ncorrosion_import_crate(MANIFEST_PATH rust/Cargo.toml)\n\nadd_executable(rustflags-cpp-exe main.cpp)\ntarget_link_libraries(rustflags-cpp-exe PUBLIC rustflag_test_lib)\n\n# Test --cfg=key=\"value\" rustflag.\ncorrosion_add_target_rustflags(rustflag_test_lib --cfg=test_rustflag_cfg1=\"test_rustflag_cfg1_value\")\n\n# Test using a generator expression to produce a rustflag and passing multiple rustflags.\ncorrosion_add_target_rustflags(rustflag_test_lib\n        --cfg=test_rustflag_cfg2=\"$<IF:$<OR:$<CONFIG:Debug>,$<CONFIG:>>,debug,release>\"\n        \"--cfg=test_rustflag_cfg3\"\n)\n\ncorrosion_add_target_local_rustflags(rustflag_test_lib \"--cfg=test_local_rustflag1\")\ncorrosion_add_target_local_rustflags(rustflag_test_lib --cfg=test_local_rustflag2=\"value\")\n"
  },
  {
    "path": "test/rustflags/rustflags/main.cpp",
    "content": "extern \"C\" void rust_function(char const *name);\nextern \"C\" void rust_second_function(char const *name);\nextern \"C\" void rust_third_function(char const *name);\n\nint main(int argc, char **argv) {\n    if (argc < 2) {\n        rust_function(\"Cpp\");\n        rust_second_function(\"Cpp again\");\n        rust_third_function(\"Cpp again\");\n    } else {\n        rust_function(argv[1]);\n    }\n}\n"
  },
  {
    "path": "test/rustflags/rustflags/rust/Cargo.toml",
    "content": "[package]\nname = \"rustflag-test-lib\"\nversion = \"0.1.0\"\nlicense = \"MIT\"\nedition = \"2018\"\n\n[dependencies]\nsome_dependency = { path = \"some_dependency\" }\n\n[lib]\ncrate-type=[\"staticlib\"]\n"
  },
  {
    "path": "test/rustflags/rustflags/rust/some_dependency/Cargo.toml",
    "content": "[package]\nname = \"some_dependency\"\nversion = \"0.1.0\"\nlicense = \"MIT\"\nedition = \"2018\"\n\n"
  },
  {
    "path": "test/rustflags/rustflags/rust/some_dependency/src/lib.rs",
    "content": "//! Test that the local rustflags are only passed to the main crate and not to dependencies.\n#[cfg(test_local_rustflag1)]\nconst _: [(); 1] = [(); 2];\n\n#[cfg(test_local_rustflag2 = \"value\")]\nconst _: [(); 1] = [(); 2];\n\npub fn some_function() -> u32 {\n    42\n}\n"
  },
  {
    "path": "test/rustflags/rustflags/rust/src/lib.rs",
    "content": "#[cfg(test_rustflag_cfg1 = \"test_rustflag_cfg1_value\")]\nuse std::os::raw::c_char;\n\n#[no_mangle]\n#[cfg(test_rustflag_cfg1 = \"test_rustflag_cfg1_value\")]\npub extern \"C\" fn rust_function(name: *const c_char) {\n    let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() };\n    println!(\"Hello, {}! I'm Rust!\", name);\n}\n\n#[no_mangle]\n#[cfg(all(debug_assertions, test_rustflag_cfg2 = \"debug\"))]\npub extern \"C\" fn rust_second_function(name: *const c_char) {\n    let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() };\n    println!(\"Hello, {}! I'm Rust in Debug mode again!\", name);\n}\n\n#[no_mangle]\n#[cfg(all(not(debug_assertions), test_rustflag_cfg2 = \"release\"))]\npub extern \"C\" fn rust_second_function(name: *const c_char) {\n    let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() };\n    println!(\"Hello, {}! I'm Rust in Release mode again!\", name);\n}\n\n#[no_mangle]\n#[cfg(test_rustflag_cfg3)]\npub extern \"C\" fn rust_third_function(name: *const c_char) {\n    let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() };\n    println!(\"Hello, {}! I'm Rust again, third time the charm!\", name);\n    assert_eq!(some_dependency::some_function(), 42);\n}\n\n#[cfg(not(test_rustflag_cfg3))]\nconst _: [(); 1] = [(); 2];\n\n#[cfg(not(test_local_rustflag1))]\nconst _: [(); 1] = [(); 2];\n\n#[cfg(not(test_local_rustflag2 = \"value\"))]\nconst _: [(); 1] = [(); 2];\n"
  },
  {
    "path": "test/workspace/CMakeLists.txt",
    "content": "corrosion_tests_add_test(workspace \"my_program\")\n\nset_tests_properties(\"workspace_run_my_program\" PROPERTIES PASS_REGULAR_EXPRESSION\n        \"^Ok\\r?\\n$\"\n        )\n\n"
  },
  {
    "path": "test/workspace/workspace/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(test_project VERSION 0.1.0)\ninclude(../../test_header.cmake)\n\ncorrosion_import_crate(\n    MANIFEST_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml\n    CRATES member1 member2\n    IMPORTED_CRATES imported_crate_list\n)\n\n#NOTE: member3 also contains a binary called my_program, but that shouldn't be a problem since it is not imported\nadd_executable(my_program main.cpp)\ntarget_link_libraries(my_program PUBLIC member1 member2)\n\n# Test that the list of imported crates matches our expectations.\nif(NOT DEFINED imported_crate_list)\n    message(FATAL_ERROR \"Corrosion failed to set the variable passed via IMPORTED_CRATES.\")\nendif()\nset(expected_crates member1 member2)\nforeach(crate ${expected_crates})\n    if(NOT \"${crate}\" IN_LIST imported_crate_list)\n        message(FATAL_ERROR \"Expected ${crate} to be imported, but it wasn't. Imported crate list:\\n\"\n            \"${imported_crate_list}\"\n        )\n    endif()\nendforeach()\nset(additional_crates ${imported_crate_list})\nlist(REMOVE_ITEM additional_crates ${expected_crates})\nif(additional_crates)\n    message(FATAL_ERROR \"Corrosion unexpectedly imported the following crates: ${additional_crates}\")\nendif()\n\n"
  },
  {
    "path": "test/workspace/workspace/Cargo.toml",
    "content": "[workspace]\nmembers=[\"member1\", \"member2\", \"member3\"]\n\n[workspace.package]\nversion = \"0.1.0\"\n"
  },
  {
    "path": "test/workspace/workspace/main.cpp",
    "content": "#include <iostream>\nint main() {\n        std::cout << \"Ok\";\n}\n"
  },
  {
    "path": "test/workspace/workspace/member1/Cargo.toml",
    "content": "[package]\nname = \"member1\"\nversion = \"0.1.0\"\nedition = \"2018\"\ndescription = \"descr;\\\"hello\\\\\"\n\n[lib]\ncrate-type = [ \"lib\", \"cdylib\" ]\n"
  },
  {
    "path": "test/workspace/workspace/member1/src/lib.rs",
    "content": "#[cfg(test)]\nmod tests {\n    #[test]\n    fn it_works() {\n        assert_eq!(2 + 2, 4);\n    }\n}\n"
  },
  {
    "path": "test/workspace/workspace/member2/Cargo.toml",
    "content": "[package]\nname = \"member2\"\nversion = \"0.1.0\"\nauthors = [\"Olivier Goffart <ogoffart@sixtyfps.io>\"]\nedition = \"2018\"\n\n[lib]\ncrate-type = [\"staticlib\"]\n"
  },
  {
    "path": "test/workspace/workspace/member2/src/lib.rs",
    "content": "#[cfg(test)]\nmod tests {\n    #[test]\n    fn it_works() {\n        assert_eq!(2 + 2, 4);\n    }\n}\n"
  },
  {
    "path": "test/workspace/workspace/member3/Cargo.toml",
    "content": "[package]\nname = \"member3\"\nversion = \"0.1.0\"\nauthors = [\"Olivier Goffart <ogoffart@sixtyfps.io>\"]\nedition = \"2018\"\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[[bin]]\nname = \"my_program\"\npath = \"src/main.rs\"\n\n[dependencies]\nmember1 = { path = \"../member1\" }\n"
  },
  {
    "path": "test/workspace/workspace/member3/src/main.rs",
    "content": "fn main() {\n    println!(\"Hello, world!\");\n}\n"
  }
]