diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..997504b46 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# SCM syntax highlighting & preventing 3-way merges +pixi.lock merge=binary linguist-language=YAML linguist-generated=true -diff diff --git a/.github/workflows/build-llvm.yml b/.github/workflows/build-llvm.yml new file mode 100644 index 000000000..9b3bdd16b --- /dev/null +++ b/.github/workflows/build-llvm.yml @@ -0,0 +1,196 @@ +name: build llvm + +on: + pull_request: + # if you want to run this workflow, change the branch name to main, + # if you want to turn off it, change it to non existent branch. + branches: [main-turn-off] + +jobs: + build: + strategy: + fail-fast: false + matrix: + include: + # Windows + - os: windows-2025 + llvm_mode: Debug + lto: OFF + - os: windows-2025 + llvm_mode: RelWithDebInfo + lto: OFF + - os: windows-2025 + llvm_mode: RelWithDebInfo + lto: ON + # Linux + - os: ubuntu-24.04 + llvm_mode: Debug + lto: OFF + - os: ubuntu-24.04 + llvm_mode: RelWithDebInfo + lto: OFF + - os: ubuntu-24.04 + llvm_mode: RelWithDebInfo + lto: ON + # macOS + - os: macos-15 + llvm_mode: Debug + lto: OFF + - os: macos-15 + llvm_mode: RelWithDebInfo + lto: OFF + - os: macos-15 + llvm_mode: RelWithDebInfo + lto: ON + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Free Disk Space + if: runner.os == 'Linux' + uses: jlumbroso/free-disk-space@main + + - name: Increase Swap Space + if: runner.os == 'Linux' + run: | + echo "===== Initial Status =====" + sudo swapon --show + free -h + + echo "===== Creating Swap File =====" + sudo swapoff -a + sudo fallocate -l 16G /mnt/swapfile + sudo chmod 600 /mnt/swapfile + sudo mkswap /mnt/swapfile + sudo swapon /mnt/swapfile + + echo "===== Final Status =====" + sudo swapon --show + free -h + df -h + + - name: Setup Pixi + uses: prefix-dev/setup-pixi@v0.9.3 + with: + pixi-version: v0.59.0 + environments: package + activate-environment: true + cache: true + locked: true + + - name: Clone llvm-project (21.1.4) + shell: bash + run: | + git clone --branch llvmorg-21.1.4 --depth 1 https://github.com/llvm/llvm-project.git .llvm + + - name: Build LLVM (install-distribution) + shell: bash + run: | + pixi run build-llvm --llvm-src=.llvm --mode="${{ matrix.llvm_mode }}" --lto="${{ matrix.lto }}" --build-dir=build + + - name: Build clice using installed LLVM + shell: bash + run: | + cmake -B build -G Ninja \ + -DCMAKE_BUILD_TYPE=${{ matrix.llvm_mode }} \ + -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain.cmake \ + -DCLICE_ENABLE_TEST=ON \ + -DCLICE_CI_ENVIRONMENT=ON \ + -DCLICE_ENABLE_LTO=${{ matrix.lto }} \ + -DLLVM_INSTALL_PATH=".llvm/build-install" + cmake --build build + + - name: Run tests + shell: bash + run: | + EXE_EXT="" + if [[ "${{ runner.os }}" == "Windows" ]]; then + EXE_EXT=".exe" + fi + ./build/bin/unit_tests${EXE_EXT} --test-dir="./tests/data" + uv run --project tests pytest -s --log-cli-level=INFO tests/integration --executable=./build/bin/clice${EXE_EXT} + + - name: Prune LLVM static libraries (Debug/RelWithDebInfo no LTO) + if: matrix.llvm_mode == 'Debug' || (matrix.llvm_mode == 'RelWithDebInfo' && matrix.lto == 'OFF') + shell: bash + run: | + MANIFEST="pruned-libs-${{ matrix.os }}.json" + echo "LLVM_PRUNED_MANIFEST=${MANIFEST}" >> "${GITHUB_ENV}" + python3 scripts/prune-llvm-bin.py \ + --action discover \ + --install-dir ".llvm/build-install/lib" \ + --build-dir "build" \ + --max-attempts 60 \ + --sleep-seconds 60 \ + --manifest "${MANIFEST}" + + - name: Upload pruned-libs manifest + if: matrix.llvm_mode == 'RelWithDebInfo' && matrix.lto == 'OFF' + uses: actions/upload-artifact@v4 + with: + name: llvm-pruned-libs-${{ matrix.os }} + path: ${{ env.LLVM_PRUNED_MANIFEST }} + if-no-files-found: error + compression-level: 0 + + - name: Apply pruned-libs manifest (RelWithDebInfo + LTO) + if: matrix.llvm_mode == 'RelWithDebInfo' && matrix.lto == 'ON' + shell: bash + env: + GH_TOKEN: ${{ github.token }} + run: | + MANIFEST="pruned-libs-${{ matrix.os }}.json" + python3 scripts/prune-llvm-bin.py \ + --action apply \ + --manifest "${MANIFEST}" \ + --install-dir ".llvm/build-install/lib" \ + --build-dir "build" \ + --gh-run-id "${{ github.run_id }}" \ + --gh-artifact "llvm-pruned-libs-${{ matrix.os }}" \ + --gh-download-dir "artifacts" \ + --max-attempts 60 \ + --sleep-seconds 60 + + - name: Package LLVM install directory + shell: bash + run: | + MODE_TAG="releasedbg" + if [[ "${{ matrix.llvm_mode }}" == "Debug" ]]; then + MODE_TAG="debug" + fi + + ARCH="x64" + PLATFORM="linux" + TOOLCHAIN="gnu" + if [[ "${{ matrix.os }}" == windows-* ]]; then + PLATFORM="windows" + TOOLCHAIN="msvc" + elif [[ "${{ matrix.os }}" == macos-* ]]; then + ARCH="arm64" + PLATFORM="macos" + TOOLCHAIN="clang" + fi + + SUFFIX="" + if [[ "${{ matrix.lto }}" == "ON" ]]; then + SUFFIX="-lto" + fi + if [[ "${{ matrix.llvm_mode }}" == "Debug" ]]; then + SUFFIX="${SUFFIX}-asan" + fi + + ARCHIVE="${ARCH}-${PLATFORM}-${TOOLCHAIN}-${MODE_TAG}${SUFFIX}.tar.xz" + + set -eo pipefail + tar -C .llvm -cf - build-install | xz -T0 -9 -c > "${ARCHIVE}" + echo "LLVM_INSTALL_ARCHIVE=${ARCHIVE}" >> "${GITHUB_ENV}" + + - name: Upload LLVM install artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ env.LLVM_INSTALL_ARCHIVE }} + path: ${{ env.LLVM_INSTALL_ARCHIVE }} + if-no-files-found: error diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index dd888d4a4..5473b4552 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -9,6 +9,7 @@ on: - "src/**" - "tests/**" - "CMakeLists.txt" + pull_request: branches: [main] paths: @@ -27,75 +28,36 @@ jobs: include: - os: windows-2025 build_type: RelWithDebInfo - cc: clang - cxx: clang++ - os: ubuntu-24.04 build_type: Debug - cc: clang-20 - cxx: clang++-20 - os: macos-15 build_type: Debug - cc: clang - cxx: clang++ runs-on: ${{ matrix.os }} steps: - - name: Setup dependencies (Windows) - if: runner.os == 'Windows' - uses: MinoruSekine/setup-scoop@v4.0.1 - with: - buckets: main - apps: ninja - - - name: Setup dependencies (Linux) - if: runner.os == 'Linux' - run: | - sudo apt update - sudo apt install -y gcc-14 g++-14 libstdc++-14-dev - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 100 - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-14 100 - sudo update-alternatives --set gcc /usr/bin/gcc-14 - sudo update-alternatives --set g++ /usr/bin/g++-14 - wget https://apt.llvm.org/llvm.sh - chmod +x llvm.sh - sudo ./llvm.sh 20 all - sudo apt install -y cmake ninja-build - - - name: Setup dependencies (MacOS) - if: runner.os == 'macOS' - env: - HOMEBREW_NO_AUTO_UPDATE: 1 - run: | - brew install llvm@20 lld@20 - - name: Checkout repository uses: actions/checkout@v4 - - name: Setup msvc sysroot for cmake - if: runner.os == 'Windows' - uses: ilammy/msvc-dev-cmd@v1 + - name: Setup Pixi + uses: prefix-dev/setup-pixi@v0.9.3 + with: + pixi-version: v0.59.0 + environments: develop + activate-environment: true + cache: true + locked: true - name: Build clice shell: bash run: | - if [[ "${{ runner.os }}" == "macOS" ]]; then - export SDKROOT=$(xcrun --show-sdk-path) - export PATH="/opt/homebrew/opt/llvm@20/bin:/opt/homebrew/opt/lld@20/bin:$PATH" - fi - cmake -B build -G Ninja \ -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ - -DCMAKE_C_COMPILER=${{ matrix.cc }} \ - -DCMAKE_CXX_COMPILER=${{ matrix.cxx }} \ + -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain.cmake \ -DCLICE_ENABLE_TEST=ON \ -DCLICE_CI_ENVIRONMENT=ON - cmake --build build - - name: Install uv for integration tests - uses: astral-sh/setup-uv@v6 - - name: Run tests shell: bash run: | @@ -103,10 +65,5 @@ jobs: if [[ "${{ runner.os }}" == "Windows" ]]; then EXE_EXT=".exe" fi - - if [[ "${{ runner.os }}" == "macOS" ]]; then - export PATH="/opt/homebrew/opt/llvm@20/bin:/opt/homebrew/opt/lld@20/bin:$PATH" - fi - ./build/bin/unit_tests${EXE_EXT} --test-dir="./tests/data" uv run --project tests pytest -s --log-cli-level=INFO tests/integration --executable=./build/bin/clice${EXE_EXT} diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml deleted file mode 100644 index bac7d0c66..000000000 --- a/.github/workflows/docker.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: docker -on: - release: - types: [created] - workflow_dispatch: - -env: - REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} - PLATFORMS: linux/amd64,darwin/arm64 - -jobs: - build-and-publish: - runs-on: ubuntu-24.04 - permissions: - contents: read - packages: write - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - with: - submodules: recursive - - - name: Setup Docker buildx - uses: docker/setup-buildx-action@v2.5.0 - with: - platforms: ${{ env.PLATFORMS }} - - - name: Log into registry ${{ env.REGISTRY }} - uses: docker/login-action@v2.1.0 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract Docker metadata - id: meta - uses: docker/metadata-action@v4.3.0 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - - # https://stackoverflow.com/questions/71157844/how-can-i-copy-git-directory-to-the-container-with-github-actions - - name: Build and push Docker image - id: build-and-push - uses: docker/build-push-action@v4.0.0 - with: - push: true - context: . - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - platforms: ${{ env.PLATFORMS }} - cache-from: type=gha - cache-to: type=gha,mode=max diff --git a/.github/workflows/upload-llvm.yml b/.github/workflows/upload-llvm.yml new file mode 100644 index 000000000..6ad5def10 --- /dev/null +++ b/.github/workflows/upload-llvm.yml @@ -0,0 +1,38 @@ +name: upload-llvm + +permissions: + contents: write + +on: + pull_request: + # if you want to run this workflow, change the branch name to main, + # if you want to turn off it, change it to non existent branch. + branches: [main-turn-off] + + workflow_dispatch: + inputs: + workflow_id: + description: "Workflow run ID to pull artifacts from" + required: true + type: string + version: + description: "Release version/tag to publish (e.g., v1.2.3)" + required: true + type: string + +jobs: + upload: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + + - name: Download artifacts from workflow + env: + GH_TOKEN: ${{ github.token }} + run: scripts/download-llvm.sh "${{ inputs.workflow_id }}" + + - name: Recreate release with artifacts + env: + GH_TOKEN: ${{ secrets.UPLOAD_LLVM }} + TARGET_REPO: clice-io/clice-llvm + run: python3 scripts/upload-llvm.py "${{ inputs.version }}" "${TARGET_REPO}" "${{ inputs.workflow_id }}" diff --git a/.github/workflows/xmake.yml b/.github/workflows/xmake.yml index 4bba3801d..e1c806867 100644 --- a/.github/workflows/xmake.yml +++ b/.github/workflows/xmake.yml @@ -9,8 +9,9 @@ on: - "src/**" - "tests/**" - "xmake.lua" + pull_request: - branches: [main] + branches: [main-test] paths: - ".github/workflows/xmake.yml" - "include/**" diff --git a/.gitignore b/.gitignore index 30e0cfebe..8a8c67b28 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,8 @@ tests/unit/Local/ .vs/ .idea/ .claude + +# pixi environments +.env +.pixi/* +!.pixi/config.toml diff --git a/CMakeLists.txt b/CMakeLists.txt index b45ecc7f4..bfdc47490 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,10 @@ -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.30) + project(CLICE_PROJECT LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_SCAN_FOR_MODULES OFF) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) include(GNUInstallDirs) @@ -10,6 +12,8 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin") +option(CLICE_ENABLE_LTO "Enable ThinLTO for all targets" OFF) + # Make sure all third libraries are affected by ABI related options if(CLICE_USE_LIBCXX) string(APPEND CMAKE_CXX_FLAGS " -stdlib=libc++") @@ -17,10 +21,49 @@ if(CLICE_USE_LIBCXX) string(APPEND CMAKE_SHARED_LINKER_FLAGS " -stdlib=libc++") endif() -if(NOT WIN32 AND CMAKE_BUILD_TYPE STREQUAL "Debug") - string(APPEND CMAKE_CXX_FLAGS " -fsanitize=address") - string(APPEND CMAKE_EXE_LINKER_FLAGS " -fsanitize=address") - string(APPEND CMAKE_SHARED_LINKER_FLAGS " -fsanitize=address") +if(CLICE_ENABLE_LTO) + string(APPEND CMAKE_C_FLAGS " -flto=thin") + string(APPEND CMAKE_CXX_FLAGS " -flto=thin") + string(APPEND CMAKE_EXE_LINKER_FLAGS " -flto=thin") + string(APPEND CMAKE_SHARED_LINKER_FLAGS " -flto=thin") + string(APPEND CMAKE_MODULE_LINKER_FLAGS " -flto=thin") +endif() + + + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + add_compile_options(-fsanitize=address) + + if(NOT WIN32) + string(APPEND CMAKE_EXE_LINKER_FLAGS " -fsanitize=address") + string(APPEND CMAKE_SHARED_LINKER_FLAGS " -fsanitize=address") + endif() + + if(MSVC AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") + execute_process( + COMMAND ${CMAKE_CXX_COMPILER} --print-resource-dir + OUTPUT_VARIABLE CLANG_RESOURCE_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + set(ASAN_LIB_PATH "${CLANG_RESOURCE_DIR}/lib/windows") + link_directories(${ASAN_LIB_PATH}) + + set(ASAN_LINK_FLAGS "") + + list(APPEND ASAN_LINK_FLAGS "clang_rt.asan_dynamic-x86_64.lib") + list(APPEND ASAN_LINK_FLAGS "/wholearchive:clang_rt.asan_dynamic_runtime_thunk-x86_64.lib") + + foreach(flag ${ASAN_LINK_FLAGS}) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${flag}") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${flag}") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${flag}") + endforeach() + endif() +endif() + +if(APPLE) + # https://conda-forge.org/docs/maintainer/knowledge_base/#newer-c-features-with-old-sdk + string(APPEND CMAKE_CXX_FLAGS " -D_LIBCPP_DISABLE_AVAILABILITY=1") endif() include("${PROJECT_SOURCE_DIR}/cmake/package.cmake") @@ -35,11 +78,16 @@ if(CLICE_CI_ENVIRONMENT) target_compile_definitions(clice_options INTERFACE CLICE_CI_ENVIRONMENT=1) endif() +if(WIN32) + target_link_libraries(clice_options INTERFACE version ntdll) +endif() + if(WIN32) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL") target_link_options(clice_options INTERFACE -fuse-ld=lld-link -Wl,/OPT:REF + #,/OPT:NOICF ) elseif(APPLE) target_link_options(clice_options INTERFACE @@ -49,11 +97,13 @@ elseif(APPLE) elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") target_link_options(clice_options INTERFACE -fuse-ld=lld + -static-libstdc++ -static-libgcc -Wl,--gc-sections ) endif() -if (MSVC) +if(MSVC OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND + CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")) target_compile_options(clice_options INTERFACE /GR- /EHsc- diff --git a/cmake/github.cmake b/cmake/github.cmake deleted file mode 100644 index c59d75926..000000000 --- a/cmake/github.cmake +++ /dev/null @@ -1,57 +0,0 @@ -include(${CMAKE_CURRENT_LIST_DIR}/utils.cmake) - -# Look up a Git tag's corresponding commit SHA from a GitHub repository -function(github_lookup_tag_commit REPO_OWNER REPO_NAME TAG_NAME OUTPUT_VAR) - set(GITHUB_API_URL "https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/git/ref/tags/${TAG_NAME}") - - message(STATUS "Fetching tag info from: ${GITHUB_API_URL}") - - # Download tag info directly into a string - download_to_string(${GITHUB_API_URL} TAG_JSON DOWNLOAD_RESULT) - if(NOT DOWNLOAD_RESULT EQUAL "0") - message(WARNING "Failed to fetch tag info. Result: ${DOWNLOAD_RESULT}") - set(${OUTPUT_VAR} "NOTFOUND" PARENT_SCOPE) - return() - endif() - - # Parse the JSON to get object type and SHA - parse_json_field_from_string("${TAG_JSON}" object "type" OBJECT_TYPE) - parse_json_field_from_string("${TAG_JSON}" object "sha" OBJECT_SHA) - - if(OBJECT_TYPE STREQUAL "NOTFOUND" OR OBJECT_SHA STREQUAL "NOTFOUND") - message(WARNING "Could not find object type or SHA in the JSON response.") - set(${OUTPUT_VAR} "NOTFOUND" PARENT_SCOPE) - return() - endif() - - set(COMMIT_SHA "NOTFOUND") - - if(OBJECT_TYPE STREQUAL "commit") - # Direct commit reference - set(COMMIT_SHA ${OBJECT_SHA}) - elseif(OBJECT_TYPE STREQUAL "tag") - # Annotated tag - need to fetch the actual commit - set(TAG_API_URL "https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/git/tags/${OBJECT_SHA}") - - message(STATUS "Fetching annotated tag info from: ${TAG_API_URL}") - - # Download annotated tag info directly into a string - download_to_string(${TAG_API_URL} ANNOTATED_TAG_JSON TAG_DOWNLOAD_RESULT) - if(NOT TAG_DOWNLOAD_RESULT EQUAL "0") - message(WARNING "Failed to fetch annotated tag info. Result: ${TAG_DOWNLOAD_RESULT}") - set(${OUTPUT_VAR} "NOTFOUND" PARENT_SCOPE) - return() - endif() - - # Parse the annotated tag JSON to get the commit SHA - parse_json_field_from_string("${ANNOTATED_TAG_JSON}" object "sha" COMMIT_SHA_FROM_TAG) - - if(NOT COMMIT_SHA_FROM_TAG STREQUAL "NOTFOUND") - set(COMMIT_SHA ${COMMIT_SHA_FROM_TAG}) - endif() - else() - message(WARNING "Unknown object type: ${OBJECT_TYPE}") - endif() - - set(${OUTPUT_VAR} ${COMMIT_SHA} PARENT_SCOPE) -endfunction() diff --git a/cmake/llvm.cmake b/cmake/llvm.cmake new file mode 100644 index 000000000..be527c22e --- /dev/null +++ b/cmake/llvm.cmake @@ -0,0 +1,108 @@ +include_guard() + +function(setup_llvm LLVM_VERSION) + find_package(Python3 COMPONENTS Interpreter REQUIRED) + + set(LLVM_SETUP_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/.llvm/setup-llvm.json") + set(LLVM_SETUP_SCRIPT "${PROJECT_SOURCE_DIR}/scripts/setup-llvm.py") + set(LLVM_SETUP_ARGS + "--version" "${LLVM_VERSION}" + "--build-type" "${CMAKE_BUILD_TYPE}" + "--binary-dir" "${CMAKE_CURRENT_BINARY_DIR}" + "--manifest" "${PROJECT_SOURCE_DIR}/config/llvm-manifest.json" + "--output" "${LLVM_SETUP_OUTPUT}" + ) + + if(CLICE_ENABLE_LTO) + list(APPEND LLVM_SETUP_ARGS "--enable-lto") + endif() + + if(DEFINED LLVM_INSTALL_PATH AND NOT LLVM_INSTALL_PATH STREQUAL "") + list(APPEND LLVM_SETUP_ARGS "--install-path" "${LLVM_INSTALL_PATH}") + endif() + + if(DEFINED CLICE_OFFLINE_BUILD AND CLICE_OFFLINE_BUILD) + list(APPEND LLVM_SETUP_ARGS "--offline") + endif() + + execute_process( + COMMAND "${Python3_EXECUTABLE}" "${LLVM_SETUP_SCRIPT}" ${LLVM_SETUP_ARGS} + RESULT_VARIABLE LLVM_SETUP_RESULT + OUTPUT_VARIABLE LLVM_SETUP_STDOUT + ERROR_VARIABLE LLVM_SETUP_STDERR + ECHO_OUTPUT_VARIABLE + ECHO_ERROR_VARIABLE + COMMAND_ERROR_IS_FATAL ANY + ) + + file(READ "${LLVM_SETUP_OUTPUT}" LLVM_SETUP_JSON) + string(JSON LLVM_INSTALL_PATH GET "${LLVM_SETUP_JSON}" install_path) + string(JSON LLVM_CMAKE_DIR GET "${LLVM_SETUP_JSON}" cmake_dir) + set(LLVM_INSTALL_PATH "${LLVM_INSTALL_PATH}" CACHE PATH "Path to LLVM installation" FORCE) + set(LLVM_CMAKE_DIR "${LLVM_CMAKE_DIR}" CACHE PATH "Path to LLVM CMake files" FORCE) + + get_filename_component(LLVM_INSTALL_PATH "${LLVM_INSTALL_PATH}" ABSOLUTE) + + if(NOT EXISTS "${LLVM_INSTALL_PATH}") + message(FATAL_ERROR "Error: The specified LLVM_INSTALL_PATH does not exist: ${LLVM_INSTALL_PATH}") + endif() + + # set llvm include and lib path + add_library(llvm-libs INTERFACE IMPORTED) + + # add to include directories + target_include_directories(llvm-libs INTERFACE "${LLVM_INSTALL_PATH}/include") + + if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT WIN32) + target_link_directories(llvm-libs INTERFACE "${LLVM_INSTALL_PATH}/lib") + target_link_libraries(llvm-libs INTERFACE + LLVMSupport + LLVMFrontendOpenMP + LLVMOption + LLVMTargetParser + clangAST + clangASTMatchers + clangBasic + clangDriver + clangFormat + clangFrontend + clangLex + clangSema + clangSerialization + clangTidy + clangTidyUtils + clangTidyAndroidModule + clangTidyAbseilModule + clangTidyAlteraModule + clangTidyBoostModule + clangTidyBugproneModule + clangTidyCERTModule + clangTidyConcurrencyModule + clangTidyCppCoreGuidelinesModule + clangTidyDarwinModule + clangTidyFuchsiaModule + clangTidyGoogleModule + clangTidyHICPPModule + clangTidyLinuxKernelModule + clangTidyLLVMModule + clangTidyLLVMLibcModule + clangTidyMiscModule + clangTidyModernizeModule + clangTidyObjCModule + clangTidyOpenMPModule + clangTidyPerformanceModule + clangTidyPortabilityModule + clangTidyReadabilityModule + clangTidyZirconModule + clangTooling + clangToolingCore + clangToolingInclusions + clangToolingInclusionsStdlib + clangToolingSyntax + ) + else() + file(GLOB LLVM_LIBRARIES CONFIGURE_DEPENDS "${LLVM_INSTALL_PATH}/lib/*${CMAKE_STATIC_LIBRARY_SUFFIX}") + target_link_libraries(llvm-libs INTERFACE ${LLVM_LIBRARIES}) + target_compile_definitions(llvm-libs INTERFACE CLANG_BUILD_STATIC=1) + endif() +endfunction() diff --git a/cmake/llvm_setup.cmake b/cmake/llvm_setup.cmake deleted file mode 100644 index cd522a213..000000000 --- a/cmake/llvm_setup.cmake +++ /dev/null @@ -1,217 +0,0 @@ -include_guard() - -include(${CMAKE_CURRENT_LIST_DIR}/github.cmake) - -# Check if LLVM version is supported -function(check_llvm_version LOCAL_LLVM_VERSION LLVM_VERSION OUTPUT_VAR) - if((NOT DEFINED LOCAL_LLVM_VERSION) OR (LOCAL_LLVM_VERSION STREQUAL "")) - message(WARNING "LLVM version is not set.") - set(${OUTPUT_VAR} FALSE PARENT_SCOPE) - elseif(NOT (LOCAL_LLVM_VERSION VERSION_GREATER_EQUAL LLVM_VERSION)) - message(WARNING "Unsupported LLVM version: ${LOCAL_LLVM_VERSION}. Only LLVM ${LLVM_VERSION} is supported.") - set(${OUTPUT_VAR} FALSE PARENT_SCOPE) - else() - set(${OUTPUT_VAR} TRUE PARENT_SCOPE) - endif() -endfunction() - -# Look up LLVM version's corresponding commit SHA -function(lookup_commit LLVM_VERSION OUTPUT_VAR) - set(LLVM_TAG "llvmorg-${LLVM_VERSION}") - github_lookup_tag_commit("llvm" "llvm-project" ${LLVM_TAG} COMMIT_SHA) - set(${OUTPUT_VAR} ${COMMIT_SHA} PARENT_SCOPE) -endfunction() - -# Fetch private Clang header files from LLVM source -function(fetch_private_clang_files LLVM_VERSION) - set(PRIVATE_CLANG_FILE_LIST - "Sema/CoroutineStmtBuilder.h" - "Sema/TypeLocBuilder.h" - "Sema/TreeTransform.h" - ) - - # Check if all files already exist - set(PRIVATE_FILE_EXISTS TRUE) - foreach(FILE ${PRIVATE_CLANG_FILE_LIST}) - if(EXISTS "${LLVM_INSTALL_PATH}/include/clang/${FILE}") - message(STATUS "Private clang file found in LLVM installation: ${FILE}") - elseif(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/include/clang/${FILE}") - message(STATUS "Private clang file already exists: ${FILE}") - else() - set(PRIVATE_FILE_EXISTS FALSE) - break() - endif() - endforeach() - - if(PRIVATE_FILE_EXISTS) - message(STATUS "All required private clang files already exist.") - return() - endif() - - # Skip download in offline build mode - if(CLICE_OFFLINE_BUILD) - message(WARNING "CLICE_OFFLINE_BUILD is enabled, skipping private clang files download") - message(WARNING "Build may fail if required private headers are missing") - return() - endif() - - message(WARNING "Required private clang files incomplete, fetching from llvm-project source...") - - # Get the commit SHA for this LLVM version - lookup_commit(${LLVM_VERSION} LLVM_COMMIT) - if(LLVM_COMMIT STREQUAL "NOTFOUND") - message(WARNING "Failed to lookup commit for LLVM ${LLVM_VERSION}, skipping private clang files download") - return() - endif() - - message(STATUS "LLVM ${LLVM_VERSION} corresponds to commit ${LLVM_COMMIT}") - - # Download missing files - file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include/clang") - foreach(FILE ${PRIVATE_CLANG_FILE_LIST}) - set(FILE_PATH "${CMAKE_CURRENT_BINARY_DIR}/include/clang/${FILE}") - if(NOT EXISTS "${FILE_PATH}") - message(STATUS "Downloading ${FILE}...") - file(DOWNLOAD "https://raw.githubusercontent.com/llvm/llvm-project/${LLVM_COMMIT}/clang/lib/${FILE}" - "${FILE_PATH}" - STATUS DOWNLOAD_STATUS - TLS_VERIFY ON) - list(GET DOWNLOAD_STATUS 0 STATUS_CODE) - if(NOT STATUS_CODE EQUAL 0) - message(FATAL_ERROR "Failed to download private clang file: ${FILE}") - endif() - endif() - endforeach() -endfunction() - -# Detect system-installed LLVM using llvm-config -function(detect_llvm OUTPUT_VAR) - find_program(LLVM_CONFIG_EXEC llvm-config) - - if(NOT LLVM_CONFIG_EXEC) - set(${OUTPUT_VAR} "" PARENT_SCOPE) - return() - endif() - - # Get LLVM version and paths - execute_process( - COMMAND "${LLVM_CONFIG_EXEC}" --version - OUTPUT_VARIABLE LLVM_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - execute_process( - COMMAND "${LLVM_CONFIG_EXEC}" --prefix - OUTPUT_VARIABLE LLVM_INSTALL_PATH_DETECTED - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - execute_process( - COMMAND "${LLVM_CONFIG_EXEC}" --cmakedir - OUTPUT_VARIABLE LLVM_CMAKE_DIR_DETECTED - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - - # Set cache variables - set(LLVM_INSTALL_PATH "${LLVM_INSTALL_PATH_DETECTED}" CACHE PATH "Path to LLVM installation" FORCE) - set(LLVM_CMAKE_DIR "${LLVM_CMAKE_DIR_DETECTED}" CACHE PATH "Path to LLVM CMake files" FORCE) - set(${OUTPUT_VAR} ${LLVM_VERSION} PARENT_SCOPE) -endfunction() - -# Download and install prebuilt LLVM binaries with error checking -function(install_prebuilt_llvm LLVM_VERSION) - file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.llvm") - - # Determine platform-specific package name - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(LLVM_BUILD_TYPE "debug") - elseif(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") - set(LLVM_BUILD_TYPE "releasedbg") - else() - set(LLVM_BUILD_TYPE "release-lto") - endif() - - if(WIN32) - set(LLVM_PACKAGE "x64-windows-msvc-${LLVM_BUILD_TYPE}.7z") - elseif(APPLE) - set(LLVM_PACKAGE "arm64-macosx-apple-${LLVM_BUILD_TYPE}.tar.xz") - elseif(UNIX) - set(LLVM_PACKAGE "x86_64-linux-gnu-${LLVM_BUILD_TYPE}.tar.xz") - endif() - - if(NOT LLVM_PACKAGE) - message(FATAL_ERROR "Unsupported platform or build type for prebuilt LLVM.") - endif() - - set(DOWNLOAD_PATH "${CMAKE_CURRENT_BINARY_DIR}/${LLVM_PACKAGE}") - - # Download if file does not exist - if(NOT EXISTS "${DOWNLOAD_PATH}") - message(STATUS "Downloading prebuilt LLVM package: ${LLVM_PACKAGE}") - set(DOWNLOAD_URL "https://github.com/clice-io/clice-llvm/releases/download/${LLVM_VERSION}/${LLVM_PACKAGE}") - file(DOWNLOAD "${DOWNLOAD_URL}" - "${DOWNLOAD_PATH}" - STATUS DOWNLOAD_STATUS - SHOW_PROGRESS - TLS_VERIFY ON) - list(GET DOWNLOAD_STATUS 0 STATUS_CODE) - list(GET DOWNLOAD_STATUS 1 ERROR_MESSAGE) - - if(NOT STATUS_CODE EQUAL 0) - # Download failed, remove the incomplete file to force a fresh download next time - if(EXISTS "${DOWNLOAD_PATH}") - file(REMOVE "${DOWNLOAD_PATH}") - message(STATUS "Removed incomplete file: ${DOWNLOAD_PATH}") - endif() - message(FATAL_ERROR "Failed to download prebuilt LLVM package from ${DOWNLOAD_URL}.\nError: ${ERROR_MESSAGE}") - endif() - else() - message(STATUS "Prebuilt LLVM package already exists, skipping download.") - endif() - - message(STATUS "Extracting LLVM package: ${LLVM_PACKAGE}") - execute_process( - COMMAND "${CMAKE_COMMAND}" -E tar xvf "${DOWNLOAD_PATH}" - WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.llvm" - RESULT_VARIABLE TAR_RESULT - OUTPUT_QUIET - ERROR_QUIET - ) - - if(NOT TAR_RESULT EQUAL "0") - message(FATAL_ERROR "Failed to extract archive. The file may be corrupted or the tool is missing.") - endif() - - # Set installation paths - set(LLVM_INSTALL_PATH "${CMAKE_CURRENT_BINARY_DIR}/.llvm" CACHE PATH "Path to LLVM installation" FORCE) - set(LLVM_CMAKE_DIR "${LLVM_INSTALL_PATH}/lib/cmake/llvm" CACHE PATH "Path to LLVM CMake files" FORCE) - message(STATUS "LLVM installation path set to: ${LLVM_INSTALL_PATH}") -endfunction() - -# Main function to set up LLVM for the project -function(setup_llvm LLVM_VERSION) - if(NOT DEFINED LLVM_VERSION OR LLVM_VERSION STREQUAL "") - message(FATAL_ERROR "setup_llvm() requires a LLVM_VERSION argument (e.g., '21.1.4').") - endif() - - # Use existing LLVM installation if path is already set - if(DEFINED LLVM_INSTALL_PATH AND NOT LLVM_INSTALL_PATH STREQUAL "") - message(STATUS "LLVM_INSTALL_PATH is set to ${LLVM_INSTALL_PATH}, using it directly.") - return() - endif() - - set(LLVM_VERSION_OK false) - if (CMAKE_BUILD_TYPE STREQUAL "Release") - # Try to detect system LLVM - detect_llvm(LOCAL_LLVM_VERSION) - check_llvm_version("${LOCAL_LLVM_VERSION}" "${LLVM_VERSION}" LLVM_VERSION_OK) - endif() - - # Download prebuilt LLVM if system version is not suitable - if(NOT LLVM_VERSION_OK) - message(WARNING "System LLVM not found, version mismatch or incompatible build type.") - message(WARNING "Downloading prebuilt LLVM ${LLVM_VERSION} ...") - install_prebuilt_llvm("${LLVM_VERSION}") - endif() - - # Fetch required private Clang headers - fetch_private_clang_files("${LLVM_VERSION}") -endfunction() diff --git a/cmake/package.cmake b/cmake/package.cmake index dfd62e63d..769c4550c 100644 --- a/cmake/package.cmake +++ b/cmake/package.cmake @@ -1,81 +1,11 @@ include_guard() -include(${CMAKE_CURRENT_LIST_DIR}/llvm_setup.cmake) - -setup_llvm("21.1.4") - -get_filename_component(LLVM_INSTALL_PATH "${LLVM_INSTALL_PATH}" ABSOLUTE) - -if(NOT EXISTS "${LLVM_INSTALL_PATH}") - message(FATAL_ERROR "Error: The specified LLVM_INSTALL_PATH does not exist: ${LLVM_INSTALL_PATH}") -endif() - -# set llvm include and lib path -add_library(llvm-libs INTERFACE IMPORTED) - -# add to include directories -target_include_directories(llvm-libs INTERFACE "${LLVM_INSTALL_PATH}/include") - -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - target_link_directories(llvm-libs INTERFACE "${LLVM_INSTALL_PATH}/lib") - target_link_libraries(llvm-libs INTERFACE - LLVMSupport - LLVMFrontendOpenMP - LLVMOption - LLVMTargetParser - clangAST - clangASTMatchers - clangBasic - clangDriver - clangFormat - clangFrontend - clangLex - clangSema - clangSerialization - clangTidy - clangTidyUtils - # ALL_CLANG_TIDY_CHECKS - clangTidyAndroidModule - clangTidyAbseilModule - clangTidyAlteraModule - clangTidyBoostModule - clangTidyBugproneModule - clangTidyCERTModule - clangTidyConcurrencyModule - clangTidyCppCoreGuidelinesModule - clangTidyDarwinModule - clangTidyFuchsiaModule - clangTidyGoogleModule - clangTidyHICPPModule - clangTidyLinuxKernelModule - clangTidyLLVMModule - clangTidyLLVMLibcModule - clangTidyMiscModule - clangTidyModernizeModule - clangTidyObjCModule - clangTidyOpenMPModule - clangTidyPerformanceModule - clangTidyPortabilityModule - clangTidyReadabilityModule - clangTidyZirconModule - clangTooling - clangToolingCore - clangToolingInclusions - clangToolingInclusionsStdlib - clangToolingSyntax - ) -else() - file(GLOB LLVM_LIBRARIES CONFIGURE_DEPENDS "${LLVM_INSTALL_PATH}/lib/*${CMAKE_STATIC_LIBRARY_SUFFIX}") - target_link_libraries(llvm-libs INTERFACE ${LLVM_LIBRARIES}) - target_compile_definitions(llvm-libs INTERFACE CLANG_BUILD_STATIC=1) -endif() - -if(WIN32) - target_link_libraries(llvm-libs INTERFACE version ntdll) -endif() +include(${CMAKE_CURRENT_LIST_DIR}/llvm.cmake) +setup_llvm("21.1.4+r1") # install dependencies include(FetchContent) +set(FETCHCONTENT_UPDATES_DISCONNECTED ON) if(WIN32) set(NULL_DEVICE NUL) @@ -88,6 +18,8 @@ FetchContent_Declare( libuv GIT_REPOSITORY https://github.com/libuv/libuv.git GIT_TAG v1.x + GIT_SHALLOW TRUE + ) if(NOT WIN32 AND CMAKE_BUILD_TYPE STREQUAL "Debug") @@ -101,13 +33,16 @@ set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) FetchContent_Declare( spdlog GIT_REPOSITORY https://github.com/gabime/spdlog.git - GIT_TAG v1.15.3 + GIT_TAG v1.15.3 + GIT_SHALLOW TRUE ) # tomlplusplus FetchContent_Declare( tomlplusplus GIT_REPOSITORY https://github.com/marzer/tomlplusplus.git + GIT_TAG v3.4.0 + GIT_SHALLOW TRUE ) # croaring @@ -115,6 +50,7 @@ FetchContent_Declare( croaring GIT_REPOSITORY https://github.com/RoaringBitmap/CRoaring.git GIT_TAG v4.4.2 + GIT_SHALLOW TRUE ) set(ENABLE_ROARING_TESTS OFF CACHE INTERNAL "" FORCE) set(ENABLE_ROARING_MICROBENCHMARKS OFF CACHE INTERNAL "" FORCE) @@ -124,6 +60,7 @@ FetchContent_Declare( flatbuffers GIT_REPOSITORY https://github.com/google/flatbuffers.git GIT_TAG v25.9.23 + GIT_SHALLOW TRUE ) set(FLATBUFFERS_BUILD_GRPC OFF CACHE BOOL "" FORCE) set(FLATBUFFERS_BUILD_TESTS OFF CACHE BOOL "" FORCE) @@ -134,7 +71,9 @@ FetchContent_Declare( cpptrace GIT_REPOSITORY https://github.com/jeremy-rifkin/cpptrace.git GIT_TAG v1.0.4 + GIT_SHALLOW TRUE ) +set(CPPTRACE_DISABLE_CXX_20_MODULES ON CACHE BOOL "" FORCE) FetchContent_MakeAvailable(libuv spdlog tomlplusplus croaring flatbuffers cpptrace) diff --git a/cmake/toolchain.cmake b/cmake/toolchain.cmake new file mode 100644 index 000000000..b08dd81ab --- /dev/null +++ b/cmake/toolchain.cmake @@ -0,0 +1,44 @@ +cmake_minimum_required(VERSION 3.30) + +if(WIN32) + set(CMAKE_C_COMPILER clang-cl CACHE STRING "C compiler") + set(CMAKE_CXX_COMPILER clang-cl CACHE STRING "C++ compiler") + set(AR_PROGRAM_NAME "llvm-lib") + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL" CACHE STRING "MSVC runtime") + + find_program(LLVM_LLD_LINK_PATH "lld-link") + if(LLVM_LLD_LINK_PATH) + set(CMAKE_LINKER "${LLVM_LLD_LINK_PATH}" CACHE FILEPATH "Linker") + endif() +else() + set(CMAKE_C_COMPILER clang CACHE STRING "C compiler") + set(CMAKE_CXX_COMPILER clang++ CACHE STRING "C++ compiler") + set(AR_PROGRAM_NAME "llvm-ar") + set(CMAKE_EXE_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "Executable linker flags") + set(CMAKE_SHARED_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "Shared library linker flags") + set(CMAKE_MODULE_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "Module linker flags") +endif() + +find_program(LLVM_AR_PATH ${AR_PROGRAM_NAME}) +if(LLVM_AR_PATH) + set(CMAKE_AR "${LLVM_AR_PATH}" CACHE FILEPATH "Archiver") + set(CMAKE_C_COMPILER_AR "${LLVM_AR_PATH}" CACHE FILEPATH "C archiver") + set(CMAKE_CXX_COMPILER_AR "${LLVM_AR_PATH}" CACHE FILEPATH "C++ archiver") +endif() + +find_program(LLVM_RANLIB_PATH "llvm-ranlib") +if(LLVM_RANLIB_PATH) + set(CMAKE_RANLIB "${LLVM_RANLIB_PATH}" CACHE FILEPATH "Ranlib") + set(CMAKE_C_COMPILER_RANLIB "${LLVM_RANLIB_PATH}" CACHE FILEPATH "C ranlib") + set(CMAKE_CXX_COMPILER_RANLIB "${LLVM_RANLIB_PATH}" CACHE FILEPATH "C++ ranlib") +endif() + +find_program(LLVM_NM_PATH "llvm-nm") +if(LLVM_NM_PATH) + set(CMAKE_NM "${LLVM_NM_PATH}" CACHE FILEPATH "Symbol lister") +endif() + +find_program(LLVM_RC_PATH "llvm-rc") +if(LLVM_RC_PATH) + set(CMAKE_RC_COMPILER "${LLVM_RC_PATH}" CACHE FILEPATH "Resource compiler") +endif() diff --git a/cmake/utils.cmake b/cmake/utils.cmake deleted file mode 100644 index 33b8ade65..000000000 --- a/cmake/utils.cmake +++ /dev/null @@ -1,55 +0,0 @@ -include_guard() - -# Download content from URL directly into a string. -# Usage: download_to_string(URL OUTPUT_VAR RESULT_VAR) -# - URL: The URL to download from. -# - OUTPUT_VAR: The variable to store the downloaded content. -# - RESULT_VAR: The variable to store the status code (0 on success). -function(download_to_string URL OUTPUT_VAR RESULT_VAR) - file(DOWNLOAD - ${URL} - ${CMAKE_CURRENT_BINARY_DIR}/temp_download_file - STATUS DOWNLOAD_STATUS - TLS_VERIFY ON - TIMEOUT 10 # Set a reasonable timeout - ) - - list(GET DOWNLOAD_STATUS 0 STATUS_CODE) - - if(NOT STATUS_CODE EQUAL 0) - list(GET DOWNLOAD_STATUS 1 ERROR_MSG) - message(WARNING "Failed to download from ${URL}: ${ERROR_MSG}") - set(${RESULT_VAR} ${STATUS_CODE} PARENT_SCOPE) - return() - endif() - - file(READ ${CMAKE_CURRENT_BINARY_DIR}/temp_download_file DOWNLOADED_CONTENT) - file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/temp_download_file) - - set(${OUTPUT_VAR} ${DOWNLOADED_CONTENT} PARENT_SCOPE) - set(${RESULT_VAR} 0 PARENT_SCOPE) -endfunction() - -# Parse a nested JSON field from a string. -# Usage: parse_json_field_from_string(JSON_STRING PARENT_KEY FIELD_NAME OUTPUT_VAR) -# - JSON_STRING: A variable containing the JSON content as a string. -# - PARENT_KEY: A key string to get from the JSON content. -# - FIELD_NAME: The field name to extract. -# - OUTPUT_VAR: The variable to store the extracted value. -function(parse_json_field_from_string JSON_CONTENT) - # Get the last argument as the output variable name - set(ARGS "${ARGN}") - list(GET ARGS -1 OUTPUT_VAR) - list(REMOVE_AT ARGS -1) - - string(JSON FIELD_VALUE GET "${JSON_CONTENT}" ${ARGS}) - - if(NOT FIELD_VALUE) - string(JOIN " " FIELD_PATH_STR ${ARGS}) - message(WARNING "Could not parse field '${FIELD_PATH_STR}' from JSON.") - set(${OUTPUT_VAR} "NOTFOUND" PARENT_SCOPE) - return() - endif() - - set(${OUTPUT_VAR} ${FIELD_VALUE} PARENT_SCOPE) -endfunction() diff --git a/config/default-toolchain-version b/config/default-toolchain-version deleted file mode 100644 index 8a2b780ec..000000000 --- a/config/default-toolchain-version +++ /dev/null @@ -1,6 +0,0 @@ -xmake,3.0.2 -cmake,3.31.8 -python,3.13 -gcc,14 -clang,20 -msvc diff --git a/config/llvm-manifest.json b/config/llvm-manifest.json new file mode 100644 index 000000000..1e3dca4ea --- /dev/null +++ b/config/llvm-manifest.json @@ -0,0 +1,83 @@ +[ + { + "version": "21.1.4+r1", + "filename": "arm64-macos-clang-debug-asan.tar.xz", + "sha256": "7da4b7d63edefecaf11773e7e701c575140d1a07329bbbb038673b6ee4516ff5", + "lto": false, + "asan": true, + "platform": "macosx", + "build_type": "Debug" + }, + { + "version": "21.1.4+r1", + "filename": "arm64-macos-clang-releasedbg-lto.tar.xz", + "sha256": "300455b169448f9f01ae95e3bc269f489558a4ca3955e3032171cc75feca0e30", + "lto": true, + "asan": false, + "platform": "macosx", + "build_type": "RelWithDebInfo" + }, + { + "version": "21.1.4+r1", + "filename": "arm64-macos-clang-releasedbg.tar.xz", + "sha256": "9abfc6cd65b957d734ffb97610a634fb4a66d3fbe0fcfb5a1c9124ef693c1495", + "lto": false, + "asan": false, + "platform": "macosx", + "build_type": "RelWithDebInfo" + }, + { + "version": "21.1.4+r1", + "filename": "x64-linux-gnu-debug-asan.tar.xz", + "sha256": "c1ad3ec476911596a842ac67dd9c9c9475ce9f0a77b81101d3c801840292e7bc", + "lto": false, + "asan": true, + "platform": "linux", + "build_type": "Debug" + }, + { + "version": "21.1.4+r1", + "filename": "x64-linux-gnu-releasedbg-lto.tar.xz", + "sha256": "8a869c2184d139dbba704e2d712e7a68336458ad2d70622b3eb906c3e3511e54", + "lto": true, + "asan": false, + "platform": "linux", + "build_type": "RelWithDebInfo" + }, + { + "version": "21.1.4+r1", + "filename": "x64-linux-gnu-releasedbg.tar.xz", + "sha256": "552bab86f715d4f2c027f07eaaf5b3d6b8e430af0b74b470142f3f00da4feec6", + "lto": false, + "asan": false, + "platform": "linux", + "build_type": "RelWithDebInfo" + }, + { + "version": "21.1.4+r1", + "filename": "x64-windows-msvc-debug-asan.tar.xz", + "sha256": "093667a493d336c22ff3c604c5f1fea2a7d2c927c1179cec44e9a03726906ac1", + "lto": false, + "asan": true, + "platform": "windows", + "build_type": "Debug" + }, + { + "version": "21.1.4+r1", + "filename": "x64-windows-msvc-releasedbg-lto.tar.xz", + "sha256": "010539e85621dc3c6ecf359d899feb4075aeca5d0bba6625cdbec0e570e79129", + "lto": true, + "asan": false, + "platform": "windows", + "build_type": "RelWithDebInfo" + }, + { + "version": "21.1.4+r1", + "filename": "x64-windows-msvc-releasedbg.tar.xz", + "sha256": "f473c09fbea10053fac00be409d75dc228d4a38bcbc5e4aeb58b56a4b0dde78e", + "lto": false, + "asan": false, + "platform": "windows", + "build_type": "RelWithDebInfo" + } +] diff --git a/config/prebuilt-llvm.json b/config/prebuilt-llvm.json deleted file mode 100644 index 9c4f41461..000000000 --- a/config/prebuilt-llvm.json +++ /dev/null @@ -1,66 +0,0 @@ -[ - { - "platform": "Windows", - "build_type": "Release", - "is_lto": false, - "filename": "x64-windows-msvc-releasedbg.7z", - "version": "21.1.4", - "sha256": "02634ff12194994d93e9c76902866c03516c836ab7b55952933fd9ebcf039664" - }, - { - "platform": "Windows", - "build_type": "Release", - "is_lto": true, - "filename": "x64-windows-msvc-releasedbg-lto.7z", - "version": "21.1.4", - "sha256": "7792cfd1e2d9240b49e3db81a6a04f33cbc44afa91e9a637c0490c28d4eee95c" - }, - { - "platform": "Linux", - "build_type": "Debug", - "is_lto": false, - "filename": "x86_64-linux-gnu-debug.tar.xz", - "version": "21.1.4", - "sha256": "9c7b98e198ce1c5611e153c3602fb1dc03912f230bded99baaaa56ac1ea21cb4" - }, - { - "platform": "Linux", - "build_type": "Release", - "is_lto": false, - "filename": "x86_64-linux-gnu-releasedbg.tar.xz", - "version": "21.1.4", - "sha256": "99269acd2d9c5debf30062bf57d7bfd41154f2d0baee94abdb56b421c8e5b92c" - }, - { - "platform": "Linux", - "build_type": "Release", - "is_lto": true, - "filename": "x86_64-linux-gnu-releasedbg-lto.tar.xz", - "version": "21.1.4", - "sha256": "e5a6c567e30cbe51e4b98151f52071d0013839e7b5eabe7a2a2767c8234d06b2" - }, - { - "platform": "macosx", - "build_type": "Debug", - "is_lto": false, - "filename": "arm64-macosx-apple-debug.tar.xz", - "version": "21.1.4", - "sha256": "ae5509d8d1cfc7441c34f6ee4fcac6eb31aae30d8b54a8f9ba3e9948a22fbc8e" - }, - { - "platform": "macosx", - "build_type": "Release", - "is_lto": false, - "filename": "arm64-macosx-apple-releasedbg.tar.xz", - "version": "21.1.4", - "sha256": "dc308b0057f472e82c2eb14b300db6ee58fb4160f3428948b5a9dcae931a3378" - }, - { - "platform": "macosx", - "build_type": "Release", - "is_lto": true, - "filename": "arm64-macosx-apple-releasedbg-lto.tar.xz", - "version": "21.1.4", - "sha256": "c92d0323ff83e678fec7496c8b024a64b1731c3840752be9a4ade3b99dfd52ff" - } -] diff --git a/docker/.dockerignore b/docker/.dockerignore deleted file mode 100644 index 115b42958..000000000 --- a/docker/.dockerignore +++ /dev/null @@ -1,9 +0,0 @@ -build/ -out/ -.cache - -.clice/ -.llvm*/ -.xmake/ -.vscode/ -.vs/ diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index 6ceac5e32..000000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,39 +0,0 @@ - -FROM debian:13 AS builder - -# Installs System Dependencies -RUN apt-get update && apt-get install -y \ - ninja-build cmake build-essential curl gcc-14 g++-14 git - -# Installs LLVM 20 -RUN curl https://apt.llvm.org/llvm-snapshot.gpg.key | tee /usr/share/keyrings/llvm-snapshot.gpg.key && \ - echo "deb [signed-by=/usr/share/keyrings/llvm-snapshot.gpg.key] http://apt.llvm.org/trixie/ llvm-toolchain-trixie main" >> /etc/apt/sources.list && \ - echo "deb [signed-by=/usr/share/keyrings/llvm-snapshot.gpg.key] http://apt.llvm.org/trixie/ llvm-toolchain-trixie-20 main" >> /etc/apt/sources.list && \ - apt-get update && apt-get install -y \ - clang-20 lld-20 -RUN ln -s /usr/bin/lld-20 /usr/bin/lld - -# Adds source code -COPY include /app/include -COPY cmake /app/cmake -COPY src /app/src -COPY tests /app/tests -COPY CMakeLists.txt /app/CMakeLists.txt -COPY scripts /app/scripts - -WORKDIR /app -# Initializes and installs dependencies -RUN cmake -B build -G Ninja -DCMAKE_C_COMPILER=clang-20 -DCMAKE_CXX_COMPILER=clang++-20 -DCMAKE_BUILD_TYPE=Release -DCLICE_ENABLE_TEST=ON -# Builds clice -RUN cmake --build build -j && \ - cmake --install build --prefix=/opt/clice - -FROM debian:13 - -COPY --from=builder /opt/clice /opt/clice/ -COPY LICENSE /opt/clice/LICENSE -COPY README.md /opt/clice/README.md - -RUN ln -s /opt/clice/bin/clice /usr/local/bin/clice - -ENTRYPOINT ["clice"] diff --git a/docker/linux/Dockerfile b/docker/linux/Dockerfile deleted file mode 100644 index 1226ba688..000000000 --- a/docker/linux/Dockerfile +++ /dev/null @@ -1,265 +0,0 @@ -# build with multi-stage for cache efficiency -FROM ubuntu:24.04 AS basic-tools - -# allow build script to bind-mount project source into build container (host path) -ARG BUILD_SRC - -# set non-interactive frontend to avoid prompts -ENV DEBIAN_FRONTEND=noninteractive -# ensure user-local bin is on PATH for non-apt installs (xmake, uv, python) -ENV PATH="/root/.local/bin:${PATH}" - -# install basic tools -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,target=/var/lib/apt,sharing=locked \ - # TODO: support more cache for python, xmake installation - # TODO: check why cache doesn't work after add-apt-repository, may we change it to cache? -bash -eux - <<'BASH' - - set -e - apt update - # first install minimal apt prerequisites - # software-properties-common for add-apt-repository - # gnupg for gpg to verify cmake installer - # curl, git for downloading sources - # xz-utils, unzip for extracting archives - # make for xmake installation - apt install -y --no-install-recommends \ - software-properties-common \ - curl \ - gnupg \ - git \ - xz-utils \ - unzip \ - make - - # gcc, llvm PPA - add-apt-repository -y ppa:ubuntu-toolchain-r/ppa - apt update -BASH - -# Compiler stage -FROM basic-tools AS compiler-stage - -# passed from build arg -ARG COMPILER - -# copy instead of bind-mount, to avoid docker build cache invalidation -COPY config/default-toolchain-version /clice/config/default-toolchain-version - -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,target=/var/lib/apt,sharing=locked \ - bash -eux - <<'BASH' - set -e - - # Always install libstdc++ development files, required for both gcc and clang to link against libstdc++ - GCC_VERSION=$(grep -E '^gcc,' /clice/config/default-toolchain-version | cut -d',' -f2) - apt install -y --no-install-recommends "libstdc++-${GCC_VERSION}-dev" - - if [ "$COMPILER" = "gcc" ]; then - apt install -y --no-install-recommends "gcc-${GCC_VERSION}" "g++-${GCC_VERSION}" - update-alternatives --install /usr/bin/cc cc "/usr/bin/gcc-${GCC_VERSION}" 100 - update-alternatives --install /usr/bin/gcc gcc "/usr/bin/gcc-${GCC_VERSION}" 100 - update-alternatives --install /usr/bin/c++ c++ "/usr/bin/g++-${GCC_VERSION}" 100 - update-alternatives --install /usr/bin/g++ g++ "/usr/bin/g++-${GCC_VERSION}" 100 - elif [ "$COMPILER" = "clang" ]; then - CLANG_VERSION=$(grep -E '^clang,' /clice/config/default-toolchain-version | cut -d',' -f2) - # install clang toolchain, libstdc++ is already installed - apt install -y --no-install-recommends "clang-${CLANG_VERSION}" "clang-tools-${CLANG_VERSION}" "lld-${CLANG_VERSION}" "libclang-rt-${CLANG_VERSION}-dev" - update-alternatives --install /usr/bin/clang clang "/usr/bin/clang-${CLANG_VERSION}" 100 - update-alternatives --install /usr/bin/clang++ clang++ "/usr/bin/clang++-${CLANG_VERSION}" 100 - update-alternatives --install /usr/bin/c++ c++ "/usr/bin/clang++-${CLANG_VERSION}" 100 - update-alternatives --install /usr/bin/cc cc "/usr/bin/clang-${CLANG_VERSION}" 100 - update-alternatives --install /usr/bin/ld ld "/usr/bin/lld-${CLANG_VERSION}" 100 - else - echo "Error: Unsupported compiler '$COMPILER'. Use 'gcc' or 'clang'." >&2; exit 1 - fi -BASH - -FROM compiler-stage AS build-tool-stage - -ARG XMAKE_CACHE_DIR="/docker-build-cache/xmake" -ARG CMAKE_CACHE_DIR="/docker-build-cache/cmake" -ARG UV_CACHE_DIR="/var/cache/uv" - -ENV XMAKE_CACHE_DIR=${XMAKE_CACHE_DIR} -ENV CMAKE_CACHE_DIR=${CMAKE_CACHE_DIR} -ENV UV_CACHE_DIR=${UV_CACHE_DIR} - -COPY ./pyproject.toml /clice/pyproject.toml - -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,target=/var/lib/apt,sharing=locked \ - --mount=type=cache,target=${XMAKE_CACHE_DIR},sharing=locked \ - --mount=type=cache,target=${CMAKE_CACHE_DIR},sharing=locked \ - --mount=type=cache,target=${UV_CACHE_DIR},sharing=locked \ -bash -eux - <<'BASH' - -install_xmake() { - set -e - - XMAKE_VERSION=$(grep -E '^xmake,' /clice/config/default-toolchain-version | cut -d',' -f2) - XMAKE_BASE_URL="https://github.com/xmake-io/xmake/releases/download/v${XMAKE_VERSION}" - XMAKE_FILENAME="xmake-bundle-v${XMAKE_VERSION}.linux.x86_64" - XMAKE_CACHED_FILE="${XMAKE_CACHE_DIR}/${XMAKE_FILENAME}" - - if [ ! -f "${XMAKE_CACHED_FILE}" ] ; then - rm -f "${XMAKE_CACHE_DIR}/*" - curl -fsSL --retry 3 -o "${XMAKE_CACHED_FILE}" "${XMAKE_BASE_URL}/${XMAKE_FILENAME}" - fi - - XMAKE_INSTALL_DIR="/usr/bin" - XMAKE_INSTALLED_FILE="${XMAKE_INSTALL_DIR}/${XMAKE_FILENAME}" - - cp "${XMAKE_CACHED_FILE}" "${XMAKE_INSTALLED_FILE}" - chmod +x "${XMAKE_INSTALLED_FILE}" - - update-alternatives --install /usr/bin/xmake xmake "${XMAKE_INSTALLED_FILE}" 100 - - echo "export XMAKE_ROOT=y" >> ~/.bashrc -} - -# Attention: DO NOT install cmake via PPA with apt, which would have to install required build-essential compiler tool chain -# We SHOULD NOT install another compiler toolchain, which could cause a lot trouble -# And we should not install compiler toolchain away from compiler stage -# So we install cmake from official installer script, and cache the downloaded files -install_cmake() { - set -e - - # cached downloads live under /docker-build-cache/cmake (BuildKit cache mount) - CMAKE_VERSION=$(grep -E '^cmake,' /clice/config/default-toolchain-version | cut -d',' -f2) - ARCH="x86_64" - - BASE_URL="https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}" - INSTALLER_FILENAME="cmake-${CMAKE_VERSION}-linux-${ARCH}.sh" - SHA_FILENAME="cmake-${CMAKE_VERSION}-SHA-256.txt" - ASC_FILENAME="${SHA_FILENAME}.asc" - - INSTALLER_PATH="${CMAKE_CACHE_DIR}/${INSTALLER_FILENAME}" - SHA_PATH="${CMAKE_CACHE_DIR}/${SHA_FILENAME}" - ASC_PATH="${CMAKE_CACHE_DIR}/${ASC_FILENAME}" - - verify_cmake_installer() { - if ! gpg --verify "${ASC_PATH}" "${SHA_PATH}"; then - echo "Signature verification failed for ${SHA_FILENAME}." >&2 - return 1 - fi - - local expected_hash - expected_hash=$(grep "${INSTALLER_FILENAME}" "${SHA_PATH}" | awk '{print $1}') - - local actual_hash - actual_hash=$(sha256sum "${INSTALLER_PATH}" | awk '{print $1}') - if [ "${expected_hash}" != "${actual_hash}" ]; then - echo "Checksum mismatch for ${INSTALLER_FILENAME}." >&2 - return 1 - fi - - echo "Checksum for ${INSTALLER_FILENAME} is valid." - return 0 - } - - gpg --keyserver keys.openpgp.org --recv-keys C6C265324BBEBDC350B513D02D2CEF1034921684 - - if [ ! -f "${INSTALLER_PATH}" ] || ! verify_cmake_installer; then - rm -f "${CMAKE_CACHE_DIR}/*" - - curl -fsSL --retry 3 -o "${INSTALLER_PATH}" "${BASE_URL}/${INSTALLER_FILENAME}" - curl -fsSL --retry 3 -o "${SHA_PATH}" "${BASE_URL}/${SHA_FILENAME}" - curl -fsSL --retry 3 -o "${ASC_PATH}" "${BASE_URL}/${ASC_FILENAME}" - - if ! verify_cmake_installer; then - echo "Verification of the downloaded installer failed. Cleaning cache." >&2 - rm -f "${CMAKE_CACHE_DIR}/*" - exit 1 - fi - fi - - sh "${INSTALLER_PATH}" --skip-license --prefix=/usr/local -} - -install_python() { - set -e - PYTHON_VERSION=$(grep -E '^python,' /clice/config/default-toolchain-version | cut -d',' -f2) - curl -LsSf https://astral.sh/uv/install.sh | sh - uv python install "${PYTHON_VERSION}" - uv sync -} - -do_install() { - set -e - - cd /clice - - export PATH="/root/.local/bin:${PATH}" - echo "export XMAKE_ROOT=y" >> ~/.bashrc - - install_cmake & - install_xmake & - install_python & - - for job in $(jobs -p); do - wait $job || exit 1 - done -} - -do_install - -BASH - -# download compile dependencies -FROM build-tool-stage AS dependency-cache-stage - -# passed from build arg -# "lto" or "non_lto" -ARG BUILD_SRC -# ARG LTO_TYPE="" - -RUN --mount=type=bind,src=./,target=/clice,rw \ -bash -eux - <<'BASH' - -# cache_xmake_packages() { -# set -e - -# export PATH="/root/.local/bin:${PATH}" -# export XMAKE_ROOT=y - -# LTO_FLAG="" -# if [ "$LTO_TYPE" = "lto" ]; then -# LTO_FLAG="--release" -# fi - -# xmake f -y -v --mode=release ${LTO_FLAG} -# xmake f -y -v --mode=debug ${LTO_FLAG} -# } - -do_prepare_dependency() { - set -e - - cd /clice - - # cache_xmake_packages & - - for job in $(jobs -p); do - wait $job || exit 1 - done -} - -do_prepare_dependency - -BASH - -FROM dependency-cache-stage AS final - -RUN bash -eux - <<'BASH' -set -e - # clice is mounted here, so remove everything to reduce image size - rm -rf /clice - - # disable git exception in cmake build when Fetch-Content - git config --global --add safe.directory '*' -BASH - -WORKDIR /clice - -CMD ["/bin/bash"] diff --git a/docker/linux/build.sh b/docker/linux/build.sh deleted file mode 100644 index b47ecc696..000000000 --- a/docker/linux/build.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash -set -e - -# Save original working directory and switch to project root -ORIG_PWD="$(pwd)" -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -echo "${SCRIPT_DIR}" -cd "${SCRIPT_DIR}/../.." -PROJECT_ROOT="$(pwd)" - -trap 'cd "${ORIG_PWD}"' EXIT - -# default configurations -COMPILER="clang" -DOCKERFILE_PATH="docker/linux/Dockerfile" - -usage() { -cat <] - -Defaults: - --compiler ${COMPILER} -EOF -} - -# parse command line arguments -while [ "$#" -gt 0 ]; do - case "$1" in - --compiler) - COMPILER="$2"; shift 2;; - -h|--help) - usage; exit 0;; - *) - echo "Unknown parameter: $1" >&2; usage; exit 1;; - esac -done - -IMAGE_TAG="linux-${COMPILER}" -IMAGE_NAME="clice-io/clice-dev:${IMAGE_TAG}" - -echo "===========================================" -echo "Building image: ${IMAGE_NAME}" -echo "Compiler: ${COMPILER}" -echo "Dockerfile: ${DOCKERFILE_PATH}" -echo "===========================================" - -# build the docker image with specified arguments -# must run in clice root dir, so that we can mount the project in docker file to acquire essential files -docker buildx build --progress=plain -t "${IMAGE_NAME}" \ - --build-arg COMPILER="${COMPILER}" \ - --build-arg BUILD_SRC="${PROJECT_ROOT}" \ - -f "${DOCKERFILE_PATH}" . - -echo "Build complete. Image:${IMAGE_NAME}" diff --git a/docker/linux/run.sh b/docker/linux/run.sh deleted file mode 100644 index 3babc8c50..000000000 --- a/docker/linux/run.sh +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/bash -set -e - -# Save original working directory and switch to project root -ORIG_PWD="$(pwd)" -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -echo "${SCRIPT_DIR}" -cd "${SCRIPT_DIR}/../.." -PROJECT_ROOT="$(pwd)" - -trap 'cd "${ORIG_PWD}"' EXIT - -# default configurations -COMPILER="clang" -RESET="false" - -usage() { -cat <] [--reset] - -Defaults: - --compiler ${COMPILER} - --reset (re-create the container) -EOF -} - -# parse command line arguments -while [ "$#" -gt 0 ]; do - case "$1" in - --compiler) - COMPILER="$2"; shift 2;; - --reset) - RESET="true"; shift 1;; - -h|--help) - usage; exit 0;; - *) echo "Unknown parameter: $1"; usage; exit 1;; - esac -done - -IMAGE_TAG="linux-${COMPILER}" -IMAGE_NAME="clice-io/clice-dev:${IMAGE_TAG}" -CONTAINER_NAME="clice-dev-linux-${COMPILER}" - -# If the image doesn't exist, build it automatically by invoking build.sh -if ! docker image inspect "${IMAGE_NAME}" >/dev/null 2>&1; then - echo "Image ${IMAGE_NAME} not found, invoking build.sh to create it..." - ./docker/linux/build.sh --compiler "${COMPILER}" -fi - -# Handle --reset: remove the existing container if it exists -if [ "${RESET}" = "true" ]; then - if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then - echo "Resetting container: stopping and removing existing container ${CONTAINER_NAME}..." - docker stop "${CONTAINER_NAME}" >/dev/null 2>&1 || true - docker rm "${CONTAINER_NAME}" >/dev/null 2>&1 - echo "Container ${CONTAINER_NAME} has been removed." - else - echo "Container ${CONTAINER_NAME} does not exist, no need to reset." - fi - exit 0 -fi - -CONTAINER_WORKDIR="/clice" - -# Check if the container exists -if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then - echo "===========================================" - echo "Attaching to existing container: ${CONTAINER_NAME}" - echo "From image: ${IMAGE_NAME}" - echo "Project mount: ${PROJECT_ROOT} -> ${CONTAINER_WORKDIR}" - echo "===========================================" - docker start "${CONTAINER_NAME}" >/dev/null - docker exec -it -w "${CONTAINER_WORKDIR}" "${CONTAINER_NAME}" /bin/bash - exit 0 -fi - -DOCKER_RUN_ARGS=(-it -w "${CONTAINER_WORKDIR}") -DOCKER_RUN_ARGS+=(--name "${CONTAINER_NAME}") -DOCKER_RUN_ARGS+=(--mount "type=bind,src=${PROJECT_ROOT},target=${CONTAINER_WORKDIR}") - -echo "===========================================" -echo "Creating and running new container: ${CONTAINER_NAME}" -echo "From image: ${IMAGE_NAME}" -echo "Project mount: ${PROJECT_ROOT} -> ${CONTAINER_WORKDIR}" -echo "===========================================" - -docker run "${DOCKER_RUN_ARGS[@]}" "${IMAGE_NAME}" diff --git a/pixi.lock b/pixi.lock new file mode 100644 index 000000000..e80995ecf --- /dev/null +++ b/pixi.lock @@ -0,0 +1,1913 @@ +version: 6 +environments: + default: + channels: + - url: https://conda.anaconda.org/conda-forge/ + options: + pypi-prerelease-mode: if-necessary-or-explicit + packages: + linux-64: + - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45-default_hfdba357_104.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/clang-20-20.1.8-default_h99862b1_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/clang-20.1.8-default_h36abe19_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/clangxx-20.1.8-default_h363a0c9_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cmake-4.2.1-hc85cc9f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/compiler-rt-20.1.8-hb700be7_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_linux-64-20.1.8-hffcefe0_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc-14.2.0-h96c4ede_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.2.0-hdb7739f_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx-14.2.0-h96c4ede_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.2.0-h2ead766_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-3.10.0-he073ed8_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.8-default_h99862b1_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.17.0-h4e3cde8_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.2.0-h9c4974d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.8-hf7376ad_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.2.0-hed042b8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.2.0-h9c4974d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hf2a90c1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h031cc0b_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/lld-20.1.8-hef48ded_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/llvm-tools-20-20.1.8-h3b15d91_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/llvm-tools-20.1.8-hb700be7_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rhash-1.4.6-hb9d3cd8_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.17-h0157908_18.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + osx-arm64: + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-20-20.1.8-default_h73dfc95_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-20.1.8-default_hf9bcbb7_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-20.1.8-default_h36137df_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cmake-4.2.1-h54ad630_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-20.1.8-h855ad52_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-20.1.8-he32a8d3_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.21.3-h237132a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp20.1-20.1.8-default_h73dfc95_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.17.0-hdece5d2_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.7-hf598326_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-20.1.8-h6dc3340_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-20.1.8-h707e725_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm20-20.1.8-h8e0c9ce_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.1-h8eac4d7_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.1-hba2cd1d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lld-20.1.8-ha4b1419_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-20-20.1.8-h91fd4e7_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-20.1.8-h855ad52_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.13.2-h49c215f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.0-h5503f6c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rhash-1.4.6-h5505292_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + win-64: + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/clang-20-20.1.8-default_hac490eb_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/clang-20.1.8-default_hac490eb_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/clangxx-20.1.8-default_hac490eb_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cmake-4.2.1-hdcbee5b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/compiler-rt-20.1.8-h49e36cd_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_win-64-20.1.8-h49e36cd_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.17.0-h43ecb02_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.3-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libllvm20-20.1.8-h830ff33_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libuv-1.51.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.1-h692994f_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.1-h5d26750_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lld-20.1.8-hc465015_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/llvm-tools-20.1.8-h752b59f_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.13.2-h477610d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.0-h725018a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_33.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_33.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_33.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + develop: + channels: + - url: https://conda.anaconda.org/conda-forge/ + options: + pypi-prerelease-mode: if-necessary-or-explicit + packages: + linux-64: + - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45-default_hfdba357_104.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/clang-20-20.1.8-default_h99862b1_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/clang-20.1.8-default_h36abe19_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/clangxx-20.1.8-default_h363a0c9_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cmake-4.2.1-hc85cc9f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/compiler-rt-20.1.8-hb700be7_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_linux-64-20.1.8-hffcefe0_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc-14.2.0-h96c4ede_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.2.0-hdb7739f_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx-14.2.0-h96c4ede_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.2.0-h2ead766_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-3.10.0-he073ed8_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.8-default_h99862b1_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.17.0-h4e3cde8_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.2.0-h9c4974d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.8-hf7376ad_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.2.0-hed042b8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.2.0-h9c4974d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hf2a90c1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h031cc0b_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/lld-20.1.8-hef48ded_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/llvm-tools-20-20.1.8-h3b15d91_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/llvm-tools-20.1.8-hb700be7_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rhash-1.4.6-hb9d3cd8_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.17-h0157908_18.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/uv-0.9.17-h76e24b7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + osx-arm64: + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-20-20.1.8-default_h73dfc95_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-20.1.8-default_hf9bcbb7_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-20.1.8-default_h36137df_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cmake-4.2.1-h54ad630_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-20.1.8-h855ad52_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-20.1.8-he32a8d3_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.21.3-h237132a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp20.1-20.1.8-default_h73dfc95_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.17.0-hdece5d2_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.7-hf598326_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-20.1.8-h6dc3340_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-20.1.8-h707e725_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm20-20.1.8-h8e0c9ce_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.1-h8eac4d7_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.1-hba2cd1d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lld-20.1.8-ha4b1419_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-20-20.1.8-h91fd4e7_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-20.1.8-h855ad52_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.13.2-h49c215f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.0-h5503f6c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rhash-1.4.6-h5505292_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/uv-0.9.17-h1bde295_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + win-64: + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/clang-20-20.1.8-default_hac490eb_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/clang-20.1.8-default_hac490eb_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/clangxx-20.1.8-default_hac490eb_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cmake-4.2.1-hdcbee5b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/compiler-rt-20.1.8-h49e36cd_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_win-64-20.1.8-h49e36cd_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.17.0-h43ecb02_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.3-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libllvm20-20.1.8-h830ff33_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libuv-1.51.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.1-h692994f_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.1-h5d26750_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lld-20.1.8-hc465015_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/llvm-tools-20.1.8-h752b59f_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.13.2-h477610d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.0-h725018a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/uv-0.9.17-h3bd95fe_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_33.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_33.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_33.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + package: + channels: + - url: https://conda.anaconda.org/conda-forge/ + options: + pypi-prerelease-mode: if-necessary-or-explicit + packages: + linux-64: + - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45-default_hfdba357_104.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/clang-20-20.1.8-default_h99862b1_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/clang-20.1.8-default_h36abe19_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/clangxx-20.1.8-default_h363a0c9_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cmake-4.2.1-hc85cc9f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/compiler-rt-20.1.8-hb700be7_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_linux-64-20.1.8-hffcefe0_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc-14.2.0-h96c4ede_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.2.0-hdb7739f_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx-14.2.0-h96c4ede_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.2.0-h2ead766_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-3.10.0-he073ed8_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.8-default_h99862b1_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.17.0-h4e3cde8_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.2.0-h9c4974d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.8-hf7376ad_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-devel-5.8.1-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.2.0-hed042b8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.2.0-h9c4974d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hf2a90c1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h031cc0b_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/lld-20.1.8-hef48ded_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/llvm-tools-20-20.1.8-h3b15d91_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/llvm-tools-20.1.8-hb700be7_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rhash-1.4.6-hb9d3cd8_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.17-h0157908_18.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h8577fbf_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/uv-0.9.17-h76e24b7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xz-5.8.1-hbcc6ac9_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xz-gpl-tools-5.8.1-hbcc6ac9_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xz-tools-5.8.1-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + osx-arm64: + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-20-20.1.8-default_h73dfc95_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-20.1.8-default_hf9bcbb7_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-20.1.8-default_h36137df_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cmake-4.2.1-h54ad630_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-20.1.8-h855ad52_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-20.1.8-he32a8d3_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.21.3-h237132a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp20.1-20.1.8-default_h73dfc95_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.17.0-hdece5d2_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.7-hf598326_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-20.1.8-h6dc3340_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-20.1.8-h707e725_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm20-20.1.8-h8e0c9ce_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-devel-5.8.1-h39f12f2_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.1-h8eac4d7_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.1-hba2cd1d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lld-20.1.8-ha4b1419_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-20-20.1.8-h91fd4e7_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-20.1.8-h855ad52_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.13.2-h49c215f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.0-h5503f6c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rhash-1.4.6-h5505292_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/uv-0.9.17-h1bde295_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xz-5.8.1-h9a6d368_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xz-gpl-tools-5.8.1-h9a6d368_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xz-tools-5.8.1-h39f12f2_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + win-64: + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/clang-20-20.1.8-default_hac490eb_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/clang-20.1.8-default_hac490eb_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/clangxx-20.1.8-default_hac490eb_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cmake-4.2.1-hdcbee5b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/compiler-rt-20.1.8-h49e36cd_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_win-64-20.1.8-h49e36cd_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.17.0-h43ecb02_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.3-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libllvm20-20.1.8-h830ff33_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-devel-5.8.1-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libuv-1.51.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.1-h692994f_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.1-h5d26750_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lld-20.1.8-hc465015_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/llvm-tools-20.1.8-h752b59f_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.13.2-h477610d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.0-h725018a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/uv-0.9.17-h3bd95fe_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_33.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_33.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_33.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xz-5.8.1-h208afaa_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xz-tools-5.8.1-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda +packages: +- conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 + sha256: fe51de6107f9edc7aa4f786a70f4a883943bc9d39b3bb7307c04c41410990726 + md5: d7c89558ba9fa0495403155b64376d81 + license: None + size: 2562 + timestamp: 1578324546067 +- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 + build_number: 16 + sha256: fbe2c5e56a653bebb982eda4876a9178aedfc2b545f25d0ce9c4c0b508253d22 + md5: 73aaf86a425cc6e73fcf236a5a46396d + depends: + - _libgcc_mutex 0.1 conda_forge + - libgomp >=7.5.0 + constrains: + - openmp_impl 9999 + license: BSD-3-Clause + license_family: BSD + size: 23621 + timestamp: 1650670423406 +- conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45-default_hfdba357_104.conda + sha256: 054a77ccab631071a803737ea8e5d04b5b18e57db5b0826a04495bd3fdf39a7c + md5: a7a67bf132a4a2dea92a7cb498cdc5b1 + depends: + - ld_impl_linux-64 2.45 default_hbd61a6d_104 + - sysroot_linux-64 + - zstd >=1.5.7,<1.6.0a0 + license: GPL-3.0-only + license_family: GPL + size: 3747046 + timestamp: 1764007847963 +- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda + sha256: c30daba32ddebbb7ded490f0e371eae90f51e72db620554089103b4a6934b0d5 + md5: 51a19bba1b8ebfb60df25cde030b7ebc + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: bzip2-1.0.6 + license_family: BSD + size: 260341 + timestamp: 1757437258798 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda + sha256: b456200636bd5fecb2bec63f7e0985ad2097cf1b83d60ce0b6968dffa6d02aa1 + md5: 58fd217444c2a5701a44244faf518206 + depends: + - __osx >=11.0 + license: bzip2-1.0.6 + license_family: BSD + size: 125061 + timestamp: 1757437486465 +- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda + sha256: d882712855624641f48aa9dc3f5feea2ed6b4e6004585d3616386a18186fe692 + md5: 1077e9333c41ff0be8edd1a5ec0ddace + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: bzip2-1.0.6 + license_family: BSD + size: 55977 + timestamp: 1757437738856 +- conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + sha256: cc9accf72fa028d31c2a038460787751127317dcfa991f8d1f1babf216bb454e + md5: 920bb03579f15389b9e512095ad995b7 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + size: 207882 + timestamp: 1765214722852 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + sha256: 2995f2aed4e53725e5efbc28199b46bf311c3cab2648fc4f10c2227d6d5fa196 + md5: bcb3cba70cf1eec964a03b4ba7775f01 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + size: 180327 + timestamp: 1765215064054 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-h4c7d964_0.conda + sha256: 686a13bd2d4024fc99a22c1e0e68a7356af3ed3304a8d3ff6bb56249ad4e82f0 + md5: f98fb7db808b94bc1ec5b0e62f9f1069 + depends: + - __win + license: ISC + size: 152827 + timestamp: 1762967310929 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda + sha256: b986ba796d42c9d3265602bc038f6f5264095702dd546c14bc684e60c385e773 + md5: f0991f0f84902f6b6009b4d2350a83aa + depends: + - __unix + license: ISC + size: 152432 + timestamp: 1762967197890 +- conda: https://conda.anaconda.org/conda-forge/linux-64/clang-20.1.8-default_h36abe19_5.conda + sha256: dfce7b8de6be7a988dab1092e2ad54fc544a572cc5ac7df28f8f48ab409814bc + md5: b6ab4982173dcae265d545bec3a76a6c + depends: + - binutils_impl_linux-64 + - clang-20 20.1.8 default_h99862b1_5 + - libgcc-devel_linux-64 + - sysroot_linux-64 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 69507 + timestamp: 1764393877870 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-20.1.8-default_hf9bcbb7_5.conda + sha256: 18a3c82f91af7551f686c680456cecfc472cf70e5a3f894f2ca3d8171dbfe928 + md5: a53f0e70b6c18388381b387cd9c0f448 + depends: + - clang-20 20.1.8 default_h73dfc95_5 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 70094 + timestamp: 1764398225317 +- conda: https://conda.anaconda.org/conda-forge/win-64/clang-20.1.8-default_hac490eb_5.conda + sha256: 0fe71febfdf008de060c897ed93be0ec59d5acaa4179757ef6b385003700c5be + md5: 5872f7faf69f4a3cd620ae2977b7b62e + depends: + - clang-20 20.1.8 default_hac490eb_5 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 108981467 + timestamp: 1764399230779 +- conda: https://conda.anaconda.org/conda-forge/linux-64/clang-20-20.1.8-default_h99862b1_5.conda + sha256: 8c1cd16b814763792420aa0ee12d6b449d11e5978a1c05b1e41e75990c4d7478 + md5: 21cd9b3eabc4ad3c4d824bf4e9edef5a + depends: + - __glibc >=2.17,<3.0.a0 + - libclang-cpp20.1 20.1.8 default_h99862b1_5 + - libgcc >=14 + - libllvm20 >=20.1.8,<20.2.0a0 + - libstdcxx >=14 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 865216 + timestamp: 1764393818684 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-20-20.1.8-default_h73dfc95_5.conda + sha256: d283acae6b725f6ca9b647049630c4bc4e1240c46ea906643e762363214789a3 + md5: 6191d65e848fc8ab429d2627cae7b322 + depends: + - __osx >=11.0 + - libclang-cpp20.1 20.1.8 default_h73dfc95_5 + - libcxx >=20.1.8 + - libllvm20 >=20.1.8,<20.2.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 850136 + timestamp: 1764397974589 +- conda: https://conda.anaconda.org/conda-forge/win-64/clang-20-20.1.8-default_hac490eb_5.conda + sha256: af5efd61f56030acced4c8bbf5b5f9cfeecc439ee2a6451c560b71c8d3ea7545 + md5: 817f6565e6bc0f7fb9ed50c3fdf503e1 + depends: + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 73427981 + timestamp: 1764398987103 +- conda: https://conda.anaconda.org/conda-forge/linux-64/clangxx-20.1.8-default_h363a0c9_5.conda + sha256: d30843fc1012ff5fb6c95e07c15182d22f03a37c380ae350ba069adf75092828 + md5: 692c84fedd1a3302ff26dbc9a211f626 + depends: + - clang 20.1.8 default_h36abe19_5 + - libstdcxx-devel_linux-64 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 69653 + timestamp: 1764393894282 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-20.1.8-default_h36137df_5.conda + sha256: 7aab017150fc1d0b2a463ffa298b3ed4fd83ed6083fa1fb812ecef75170bf60f + md5: 881b85454ddf23fb46d1ddcbd148146f + depends: + - clang 20.1.8 default_hf9bcbb7_5 + - libcxx-devel 20.1.* + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 70176 + timestamp: 1764398258104 +- conda: https://conda.anaconda.org/conda-forge/win-64/clangxx-20.1.8-default_hac490eb_5.conda + sha256: b84853552d15ad6f6198b8803842853bb8e133f1feb4e15ac1d38a24fe0c68c9 + md5: 4275ccf7c108d6cf4e4eb715bfec8cef + depends: + - clang 20.1.8 default_hac490eb_5 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 36371198 + timestamp: 1764399473710 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cmake-4.2.1-hc85cc9f_0.conda + sha256: 655db6eddb370306d6d0ed3ac1d679ca044e45e03a43fc98cccfc5cafc341c5f + md5: e4afa0cb7943cc9810546f70f02223d5 + depends: + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - libcurl >=8.17.0,<9.0a0 + - libexpat >=2.7.3,<3.0a0 + - libgcc >=14 + - liblzma >=5.8.1,<6.0a0 + - libstdcxx >=14 + - libuv >=1.51.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - rhash >=1.4.6,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause + license_family: BSD + size: 22303088 + timestamp: 1765229009574 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cmake-4.2.1-h54ad630_0.conda + sha256: a881f3379ff18a98bbc2456e9a74d748bdbd930799c2b98dd266733b0d8fbd90 + md5: 11a1d109b6d7882b5f2f93fe9824af4a + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libcurl >=8.17.0,<9.0a0 + - libcxx >=19 + - libexpat >=2.7.3,<3.0a0 + - liblzma >=5.8.1,<6.0a0 + - libuv >=1.51.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - rhash >=1.4.6,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause + license_family: BSD + size: 17740888 + timestamp: 1765231308407 +- conda: https://conda.anaconda.org/conda-forge/win-64/cmake-4.2.1-hdcbee5b_0.conda + sha256: 03d85d6493ad6c410708f243aeb680c491075c89f0cae7e3afab718f27f28967 + md5: dd8c71fb422275f652743068455e9acd + depends: + - bzip2 >=1.0.8,<2.0a0 + - libcurl >=8.17.0,<9.0a0 + - libexpat >=2.7.3,<3.0a0 + - liblzma >=5.8.1,<6.0a0 + - libuv >=1.51.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc14_runtime >=14.44.35208 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause + license_family: BSD + size: 15739640 + timestamp: 1765230626010 +- conda: https://conda.anaconda.org/conda-forge/linux-64/compiler-rt-20.1.8-hb700be7_1.conda + sha256: 8dd25cb56ec529b43b05f93f1b501848ba1f958501f2da2ab8b5d3f910afcbff + md5: 76dfabc5943bd8ab2a916b276c5f7a59 + depends: + - __glibc >=2.17,<3.0.a0 + - clang 20.1.8.* + - compiler-rt_linux-64 20.1.8.* + - libgcc >=14 + - libstdcxx >=14 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + size: 114057 + timestamp: 1757411545630 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-20.1.8-h855ad52_1.conda + sha256: 7f0ede04667d5c0307acef1a6a24174ed57721d0ddedafa49fc23a9e7ef8b3c8 + md5: 0e093e6ebcab8549d8bc6e3e1541ce8f + depends: + - __osx >=11.0 + - clang 20.1.8.* + - compiler-rt_osx-arm64 20.1.8.* + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + size: 98152 + timestamp: 1757412625141 +- conda: https://conda.anaconda.org/conda-forge/win-64/compiler-rt-20.1.8-h49e36cd_1.conda + sha256: d7efdf6f489e3843bc926613e8f9722fd437236e13cf6251176e7432e7e13065 + md5: 7e784535b46dc00138b53ef6dca85581 + depends: + - clang 20.1.8.* + - compiler-rt_win-64 20.1.8.* + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + size: 3724179 + timestamp: 1757411777671 +- conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_linux-64-20.1.8-hffcefe0_1.conda + sha256: 790aa3aea6bf79a9a0ef73c888bb5dc9b6782257727dcc63acd320366ee7f26b + md5: f8c27e527fa2a97c9fca43e367461b7f + depends: + - clang 20.1.8.* + constrains: + - clangxx 20.1.8 + - compiler-rt 20.1.8 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + size: 49731196 + timestamp: 1757411421407 +- conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-20.1.8-he32a8d3_1.conda + sha256: 96eff0041b6c73d85a30810fb381db73a55209000eaf1f10a12e701068cea3ee + md5: 81175797ba08c2755feaede0919aabca + depends: + - clang 20.1.8.* + constrains: + - compiler-rt 20.1.8 + - clangxx 20.1.8 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + size: 10661528 + timestamp: 1757412560488 +- conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_win-64-20.1.8-h49e36cd_1.conda + sha256: 6685e190d417106c4bc723571f85bf7d1579333e86a12fc16b4b29ddb8500ca0 + md5: f96e2e3844ad678c8a6a519f99b2a905 + depends: + - clang 20.1.8.* + constrains: + - compiler-rt 20.1.8 + - clangxx 20.1.8 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + size: 3970670 + timestamp: 1757411730313 +- conda: https://conda.anaconda.org/conda-forge/linux-64/gcc-14.2.0-h96c4ede_2.conda + sha256: 6592ff15983759799df89d0a992268809e9ce0376933e053716660ecda19d87e + md5: 7f23fa6a103277a8491d3d10240ebd09 + depends: + - gcc_impl_linux-64 14.2.0.* + license: BSD-3-Clause + license_family: BSD + size: 55422 + timestamp: 1740240900938 +- conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.2.0-hdb7739f_2.conda + sha256: bbbc4baa66558f4d1805ff7f81050bfe798f2f0ca24f6b509c5c5d152f72bfbe + md5: 2d9b7363abe1f9aaf1fe129b215371e3 + depends: + - binutils_impl_linux-64 >=2.40 + - libgcc >=14.2.0 + - libgcc-devel_linux-64 14.2.0 h9c4974d_102 + - libgomp >=14.2.0 + - libsanitizer 14.2.0 hed042b8_2 + - libstdcxx >=14.2.0 + - sysroot_linux-64 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 73545585 + timestamp: 1740240767348 +- conda: https://conda.anaconda.org/conda-forge/linux-64/gxx-14.2.0-h96c4ede_2.conda + sha256: 9294f1a33a629102d2c1e0965dc8c23cd39f8608dba38defea81f2c517d69750 + md5: d82a920bedd11c9d8195bcb662d3dc89 + depends: + - gcc 14.2.0.* + - gxx_impl_linux-64 14.2.0.* + license: BSD-3-Clause + license_family: BSD + size: 54904 + timestamp: 1740241052394 +- conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.2.0-h2ead766_2.conda + sha256: 9c8cd2f0d9e8b424ff15ed6f9a0f7f329228722e750021d74e7eca3847120c93 + md5: 2deb107f39008fa08d78e661a42d9d9f + depends: + - gcc_impl_linux-64 14.2.0 hdb7739f_2 + - libstdcxx-devel_linux-64 14.2.0 h9c4974d_102 + - sysroot_linux-64 + - tzdata + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 14611960 + timestamp: 1740241005796 +- conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-3.10.0-he073ed8_18.conda + sha256: a922841ad80bd7b222502e65c07ecb67e4176c4fa5b03678a005f39fcc98be4b + md5: ad8527bf134a90e1c9ed35fa0b64318c + constrains: + - sysroot_linux-64 ==2.17 + license: LGPL-2.0-or-later AND LGPL-2.0-or-later WITH exceptions AND GPL-2.0-or-later AND MPL-2.0 + license_family: GPL + size: 943486 + timestamp: 1729794504440 +- conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + sha256: 0960d06048a7185d3542d850986d807c6e37ca2e644342dd0c72feefcf26c2a4 + md5: b38117a3c920364aff79f870c984b4a3 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: LGPL-2.1-or-later + size: 134088 + timestamp: 1754905959823 +- conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda + sha256: 99df692f7a8a5c27cd14b5fb1374ee55e756631b9c3d659ed3ee60830249b238 + md5: 3f43953b7d3fb3aaa1d0d0723d91e368 + depends: + - keyutils >=1.6.1,<2.0a0 + - libedit >=3.1.20191231,<3.2.0a0 + - libedit >=3.1.20191231,<4.0a0 + - libgcc-ng >=12 + - libstdcxx-ng >=12 + - openssl >=3.3.1,<4.0a0 + license: MIT + license_family: MIT + size: 1370023 + timestamp: 1719463201255 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.21.3-h237132a_0.conda + sha256: 4442f957c3c77d69d9da3521268cad5d54c9033f1a73f99cde0a3658937b159b + md5: c6dc8a0fdec13a0565936655c33069a1 + depends: + - __osx >=11.0 + - libcxx >=16 + - libedit >=3.1.20191231,<3.2.0a0 + - libedit >=3.1.20191231,<4.0a0 + - openssl >=3.3.1,<4.0a0 + license: MIT + license_family: MIT + size: 1155530 + timestamp: 1719463474401 +- conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda + sha256: 18e8b3430d7d232dad132f574268f56b3eb1a19431d6d5de8c53c29e6c18fa81 + md5: 31aec030344e962fbd7dbbbbd68e60a9 + depends: + - openssl >=3.3.1,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + size: 712034 + timestamp: 1719463874284 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda + sha256: 9e191baf2426a19507f1d0a17be0fdb7aa155cdf0f61d5a09c808e0a69464312 + md5: a6abd2796fc332536735f68ba23f7901 + depends: + - __glibc >=2.17,<3.0.a0 + - zstd >=1.5.7,<1.6.0a0 + constrains: + - binutils_impl_linux-64 2.45 + license: GPL-3.0-only + license_family: GPL + size: 725545 + timestamp: 1764007826689 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.8-default_h99862b1_5.conda + sha256: b9f0e167cdf5cbe076231788fcb3affe25914534d84ab249258161b693c4cfd2 + md5: 33acc83688f092f96ea2ead08e3b4dcd + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libllvm20 >=20.1.8,<20.2.0a0 + - libstdcxx >=14 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 21305254 + timestamp: 1764393708507 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp20.1-20.1.8-default_h73dfc95_5.conda + sha256: 40004708b66fc2873fb9b9a5a9b6bd31ce227aefe915e9e1383abdedb78e96de + md5: e33ebe1ae6bc0210cb241477efbb6474 + depends: + - __osx >=11.0 + - libcxx >=20.1.8 + - libllvm20 >=20.1.8,<20.2.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 13959982 + timestamp: 1764397711426 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.17.0-h4e3cde8_1.conda + sha256: 2d7be2fe0f58a0945692abee7bb909f8b19284b518d958747e5ff51d0655c303 + md5: 117499f93e892ea1e57fdca16c2e8351 + depends: + - __glibc >=2.17,<3.0.a0 + - krb5 >=1.21.3,<1.22.0a0 + - libgcc >=14 + - libnghttp2 >=1.67.0,<2.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.4,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: curl + license_family: MIT + size: 459417 + timestamp: 1765379027010 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.17.0-hdece5d2_1.conda + sha256: 1a8a958448610ca3f8facddfe261fdbb010e7029a1571b84052ec9770fc0a36e + md5: 1d6e791c6e264ae139d469ce011aab51 + depends: + - __osx >=11.0 + - krb5 >=1.21.3,<1.22.0a0 + - libnghttp2 >=1.67.0,<2.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.4,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: curl + license_family: MIT + size: 394471 + timestamp: 1765379821294 +- conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.17.0-h43ecb02_1.conda + sha256: 5ebab5c980c09d31b35a25095b295124d89fd8bdffdb3487604218ad56512885 + md5: c02248f96a0073904bb085a437143895 + depends: + - krb5 >=1.21.3,<1.22.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: curl + license_family: MIT + size: 379189 + timestamp: 1765379273605 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.7-hf598326_0.conda + sha256: 4bdbef0241b52e7a8552e8af7425f0b56d5621dd69df46c816546fefa17d77ab + md5: 0de94f39727c31c0447e408c5a210a56 + depends: + - __osx >=11.0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 568715 + timestamp: 1764676451068 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-20.1.8-h6dc3340_3.conda + sha256: 860588fb7b8c9227cfae68cf410c885fb0e05a635f3daddef9457c429a9704ba + md5: 78233f1b892fc02bca12b2daf3bd8d48 + depends: + - libcxx >=20.1.8 + - libcxx-headers >=20.1.8,<20.1.9.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 21836 + timestamp: 1764631868552 +- conda: https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-20.1.8-h707e725_3.conda + sha256: e6bbb58c0fe22ce1e6680a969bdfd05fc7b649c192707534d38c782d3a82bce2 + md5: 3db57f91c60623258287599641e974f7 + depends: + - __unix + constrains: + - libcxx-devel 20.1.8 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 1282493 + timestamp: 1764631510271 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + sha256: d789471216e7aba3c184cd054ed61ce3f6dac6f87a50ec69291b9297f8c18724 + md5: c277e0a4d549b03ac1e9d6cbbe3d017b + depends: + - ncurses + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - ncurses >=6.5,<7.0a0 + license: BSD-2-Clause + license_family: BSD + size: 134676 + timestamp: 1738479519902 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + sha256: 66aa216a403de0bb0c1340a88d1a06adaff66bae2cfd196731aa24db9859d631 + md5: 44083d2d2c2025afca315c7a172eab2b + depends: + - ncurses + - __osx >=11.0 + - ncurses >=6.5,<7.0a0 + license: BSD-2-Clause + license_family: BSD + size: 107691 + timestamp: 1738479560845 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + sha256: 1cd6048169fa0395af74ed5d8f1716e22c19a81a8a36f934c110ca3ad4dd27b4 + md5: 172bf1cd1ff8629f2b1179945ed45055 + depends: + - libgcc-ng >=12 + license: BSD-2-Clause + license_family: BSD + size: 112766 + timestamp: 1702146165126 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + sha256: 95cecb3902fbe0399c3a7e67a5bed1db813e5ab0e22f4023a5e0f722f2cc214f + md5: 36d33e440c31857372a72137f78bacf5 + license: BSD-2-Clause + license_family: BSD + size: 107458 + timestamp: 1702146414478 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda + sha256: 1e1b08f6211629cbc2efe7a5bca5953f8f6b3cae0eeb04ca4dacee1bd4e2db2f + md5: 8b09ae86839581147ef2e5c5e229d164 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - expat 2.7.3.* + license: MIT + license_family: MIT + size: 76643 + timestamp: 1763549731408 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda + sha256: fce22610ecc95e6d149e42a42fbc3cc9d9179bd4eb6232639a60f06e080eec98 + md5: b79875dbb5b1db9a4a22a4520f918e1a + depends: + - __osx >=11.0 + constrains: + - expat 2.7.3.* + license: MIT + license_family: MIT + size: 67800 + timestamp: 1763549994166 +- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.3-hac47afa_0.conda + sha256: 844ab708594bdfbd7b35e1a67c379861bcd180d6efe57b654f482ae2f7f5c21e + md5: 8c9e4f1a0e688eef2e95711178061a0f + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - expat 2.7.3.* + license: MIT + license_family: MIT + size: 70137 + timestamp: 1763550049107 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda + sha256: 6eed58051c2e12b804d53ceff5994a350c61baf117ec83f5f10c953a3f311451 + md5: 6d0363467e6ed84f11435eb309f2ff06 + depends: + - __glibc >=2.17,<3.0.a0 + - _openmp_mutex >=4.5 + constrains: + - libgcc-ng ==15.2.0=*_16 + - libgomp 15.2.0 he0feb66_16 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 1042798 + timestamp: 1765256792743 +- conda: https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.2.0-h9c4974d_102.conda + sha256: d663727f935853d1e94b8eb69fb1bac267339c99236fd26e14d4a2297ac96c91 + md5: 80ecc6e9ecffe737e30a7e5a9b10bcb4 + depends: + - __unix + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 2761178 + timestamp: 1740240568863 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda + sha256: 5f07f9317f596a201cc6e095e5fc92621afca64829785e483738d935f8cab361 + md5: 5a68259fac2da8f2ee6f7bfe49c9eb8b + depends: + - libgcc 15.2.0 he0feb66_16 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 27256 + timestamp: 1765256804124 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda + sha256: 5b3e5e4e9270ecfcd48f47e3a68f037f5ab0f529ccb223e8e5d5ac75a58fc687 + md5: 26c46f90d0e727e95c6c9498a33a09f3 + depends: + - __glibc >=2.17,<3.0.a0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 603284 + timestamp: 1765256703881 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda + sha256: c467851a7312765447155e071752d7bf9bf44d610a5687e32706f480aad2833f + md5: 915f5995e94f60e9a4826e0b0920ee88 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: LGPL-2.1-only + size: 790176 + timestamp: 1754908768807 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda + sha256: de0336e800b2af9a40bdd694b03870ac4a848161b35c8a2325704f123f185f03 + md5: 4d5a7445f0b25b6a3ddbb56e790f5251 + depends: + - __osx >=11.0 + license: LGPL-2.1-only + size: 750379 + timestamp: 1754909073836 +- conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda + sha256: 0dcdb1a5f01863ac4e8ba006a8b0dc1a02d2221ec3319b5915a1863254d7efa7 + md5: 64571d1dd6cdcfa25d0664a5950fdaa2 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.1-only + size: 696926 + timestamp: 1754909290005 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.8-hf7376ad_1.conda + sha256: bd2981488f63afbc234f6c7759f8363c63faf38dd0f4e64f48ef5a06541c12b4 + md5: eafa8fd1dfc9a107fe62f7f12cabbc9c + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - libxml2 + - libxml2-16 >=2.14.5 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 43977914 + timestamp: 1757353652788 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm20-20.1.8-h8e0c9ce_1.conda + sha256: 6639cbbde4143b14b666db9dc33beddbf6772317a42d317c8c5162b9524bd24a + md5: 717f1efdf0a0240255c7c34d55889d58 + depends: + - __osx >=11.0 + - libcxx >=19 + - libxml2 + - libxml2-16 >=2.14.5 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 28800783 + timestamp: 1757354439972 +- conda: https://conda.anaconda.org/conda-forge/win-64/libllvm20-20.1.8-h830ff33_1.conda + sha256: 33524b50fe91a996e428e4017ffe8e488c31faa0fcbe121aa20bb039060ba776 + md5: 3ae8508f52fab5ce9b38af07282a4a02 + depends: + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 55313 + timestamp: 1757354184572 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda + sha256: f2591c0069447bbe28d4d696b7fcb0c5bd0b4ac582769b89addbcf26fb3430d8 + md5: 1a580f7796c7bf6393fddb8bbbde58dc + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + constrains: + - xz 5.8.1.* + license: 0BSD + size: 112894 + timestamp: 1749230047870 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda + sha256: 0cb92a9e026e7bd4842f410a5c5c665c89b2eb97794ffddba519a626b8ce7285 + md5: d6df911d4564d77c4374b02552cb17d1 + depends: + - __osx >=11.0 + constrains: + - xz 5.8.1.* + license: 0BSD + size: 92286 + timestamp: 1749230283517 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda + sha256: 55764956eb9179b98de7cc0e55696f2eff8f7b83fc3ebff5e696ca358bca28cc + md5: c15148b2e18da456f5108ccb5e411446 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + constrains: + - xz 5.8.1.* + license: 0BSD + size: 104935 + timestamp: 1749230611612 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-devel-5.8.1-hb9d3cd8_2.conda + sha256: 329e66330a8f9cbb6a8d5995005478188eb4ba8a6b6391affa849744f4968492 + md5: f61edadbb301530bd65a32646bd81552 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - liblzma 5.8.1 hb9d3cd8_2 + license: 0BSD + size: 439868 + timestamp: 1749230061968 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-devel-5.8.1-h39f12f2_2.conda + sha256: 974804430e24f0b00f3a48b67ec10c9f5441c9bb3d82cc0af51ba45b8a75a241 + md5: 1201137f1a5ec9556032ffc04dcdde8d + depends: + - __osx >=11.0 + - liblzma 5.8.1 h39f12f2_2 + license: 0BSD + size: 116244 + timestamp: 1749230297170 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-devel-5.8.1-h2466b09_2.conda + sha256: 1ccff927a2d768403bad85e36ca3e931d96890adb4f503e1780c3412dd1e1298 + md5: 42c90c4941c59f1b9f8fab627ad8ae76 + depends: + - liblzma 5.8.1 h2466b09_2 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: 0BSD + size: 129344 + timestamp: 1749230637001 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda + sha256: a4a7dab8db4dc81c736e9a9b42bdfd97b087816e029e221380511960ac46c690 + md5: b499ce4b026493a13774bcf0f4c33849 + depends: + - __glibc >=2.17,<3.0.a0 + - c-ares >=1.34.5,<2.0a0 + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 + - libgcc >=14 + - libstdcxx >=14 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.2,<4.0a0 + license: MIT + license_family: MIT + size: 666600 + timestamp: 1756834976695 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda + sha256: a07cb53b5ffa2d5a18afc6fd5a526a5a53dd9523fbc022148bd2f9395697c46d + md5: a4b4dd73c67df470d091312ab87bf6ae + depends: + - __osx >=11.0 + - c-ares >=1.34.5,<2.0a0 + - libcxx >=19 + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.2,<4.0a0 + license: MIT + license_family: MIT + size: 575454 + timestamp: 1756835746393 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.2.0-hed042b8_2.conda + sha256: 489e069ed0a3c376da5d83166a330c1b8a041a3d25a482f692b4fb86846f2a2d + md5: 80f0abb70cd4f10ee15aa5693d89c65a + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14.2.0 + - libstdcxx >=14.2.0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 4507944 + timestamp: 1740240704883 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda + sha256: fa39bfd69228a13e553bd24601332b7cfeb30ca11a3ca50bb028108fe90a7661 + md5: eecce068c7e4eddeb169591baac20ac4 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + license: BSD-3-Clause + license_family: BSD + size: 304790 + timestamp: 1745608545575 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda + sha256: 8bfe837221390ffc6f111ecca24fa12d4a6325da0c8d131333d63d6c37f27e0a + md5: b68e8f66b94b44aaa8de4583d3d4cc40 + depends: + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + license: BSD-3-Clause + license_family: BSD + size: 279193 + timestamp: 1745608793272 +- conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda + sha256: cbdf93898f2e27cefca5f3fe46519335d1fab25c4ea2a11b11502ff63e602c09 + md5: 9dce2f112bfd3400f4f432b3d0ac07b2 + depends: + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + size: 292785 + timestamp: 1745608759342 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda + sha256: 813427918316a00c904723f1dfc3da1bbc1974c5cfe1ed1e704c6f4e0798cbc6 + md5: 68f68355000ec3f1d6f26ea13e8f525f + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc 15.2.0 he0feb66_16 + constrains: + - libstdcxx-ng ==15.2.0=*_16 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 5856456 + timestamp: 1765256838573 +- conda: https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.2.0-h9c4974d_102.conda + sha256: 7bd1943aea09457cca1aa611c71bc3b12990832d3a0ffb4b1f25a83deb035669 + md5: 54bac3d48bc1f91216b5f5fb259d8764 + depends: + - __unix + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 13572040 + timestamp: 1740240603306 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda + sha256: 81f2f246c7533b41c5e0c274172d607829019621c4a0823b5c0b4a8c7028ee84 + md5: 1b3152694d236cf233b76b8c56bf0eae + depends: + - libstdcxx 15.2.0 h934c35e_16 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 27300 + timestamp: 1765256885128 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + sha256: c180f4124a889ac343fc59d15558e93667d894a966ec6fdb61da1604481be26b + md5: 0f03292cc56bf91a077a134ea8747118 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + size: 895108 + timestamp: 1753948278280 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + sha256: 042c7488ad97a5629ec0a991a8b2a3345599401ecc75ad6a5af73b60e6db9689 + md5: c0d87c3c8e075daf1daf6c31b53e8083 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + size: 421195 + timestamp: 1753948426421 +- conda: https://conda.anaconda.org/conda-forge/win-64/libuv-1.51.0-hfd05255_1.conda + sha256: f03dc82e6fb1725788e73ae97f0cd3d820d5af0d351a274104a0767035444c59 + md5: 31e1545994c48efc3e6ea32ca02a8724 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + size: 297087 + timestamp: 1753948490874 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h031cc0b_0.conda + sha256: ee64e507b37b073e0bdad739e35330933dd5be7c639600a096551a6968f1035d + md5: a67cd8f7b0369bbf2c40411f05a62f3b + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libxml2-16 2.15.1 hf2a90c1_0 + - libzlib >=1.3.1,<2.0a0 + constrains: + - icu <0.0a0 + license: MIT + license_family: MIT + size: 45292 + timestamp: 1761015784683 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.1-hba2cd1d_0.conda + sha256: fa01101fe7d95085846c16825f0e7dc0efe1f1c7438a96fe7395c885d6179495 + md5: a53d5f7fff38853ddb6bdc8fb609c039 + depends: + - __osx >=11.0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libxml2-16 2.15.1 h8eac4d7_0 + - libzlib >=1.3.1,<2.0a0 + constrains: + - icu <0.0a0 + license: MIT + license_family: MIT + size: 40611 + timestamp: 1761016283558 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.1-h5d26750_0.conda + sha256: f507960adf64ee9c9c7b7833d8b11980765ebd2bf5345f73d5a3b21b259eaed5 + md5: 9176ee05643a1bfe7f2e7b4c921d2c3d + depends: + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libxml2-16 2.15.1 h692994f_0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - icu <0.0a0 + license: MIT + license_family: MIT + size: 43209 + timestamp: 1761016354235 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hf2a90c1_0.conda + sha256: f5220ff49efc31431279859049199b9250e79f98c1dee1da12feb74bda2d9cf1 + md5: 23720d17346b21efb08d68c2255c8431 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + constrains: + - libxml2 2.15.1 + - icu <0.0a0 + license: MIT + license_family: MIT + size: 554734 + timestamp: 1761015772672 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.1-h8eac4d7_0.conda + sha256: 3f3f9ba64a3fca15802d4eaf2a97696e6dcd916effa6a683756fd9f11245df5a + md5: cf7291a970b93fe3bb726879f2037af8 + depends: + - __osx >=11.0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + constrains: + - libxml2 2.15.1 + - icu <0.0a0 + license: MIT + license_family: MIT + size: 464186 + timestamp: 1761016258891 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.1-h692994f_0.conda + sha256: 04129dc2df47a01c55e5ccf8a18caefab94caddec41b3b10fbc409e980239eb9 + md5: 70ca4626111579c3cd63a7108fe737f9 + depends: + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - icu <0.0a0 + - libxml2 2.15.1 + license: MIT + license_family: MIT + size: 518135 + timestamp: 1761016320405 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda + sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 + md5: edb0dca6bc32e4f4789199455a1dbeb8 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + constrains: + - zlib 1.3.1 *_2 + license: Zlib + license_family: Other + size: 60963 + timestamp: 1727963148474 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda + sha256: ce34669eadaba351cd54910743e6a2261b67009624dbc7daeeafdef93616711b + md5: 369964e85dc26bfe78f41399b366c435 + depends: + - __osx >=11.0 + constrains: + - zlib 1.3.1 *_2 + license: Zlib + license_family: Other + size: 46438 + timestamp: 1727963202283 +- conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda + sha256: ba945c6493449bed0e6e29883c4943817f7c79cbff52b83360f7b341277c6402 + md5: 41fbfac52c601159df6c01f875de31b9 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + constrains: + - zlib 1.3.1 *_2 + license: Zlib + license_family: Other + size: 55476 + timestamp: 1727963768015 +- conda: https://conda.anaconda.org/conda-forge/linux-64/lld-20.1.8-hef48ded_1.conda + sha256: c3294734baa2a30f613447d48333ac3a09b4060e4603ecef727c6a935b59268e + md5: 1284f189f4b05bd1ef935807b05f6a26 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libllvm20 >=20.1.8,<20.2.0a0 + - libstdcxx >=14 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + constrains: + - llvm ==20.1.8 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + size: 11272299 + timestamp: 1757394114845 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/lld-20.1.8-ha4b1419_1.conda + sha256: 3893dfe3f7c012df0238967c10e6045d0375357845e3d824bf61cf176887a2bc + md5: a22a12e559cabf166f8e776e261b6b52 + depends: + - __osx >=11.0 + - libcxx >=19.1.7 + - libllvm20 >=20.1.8,<20.2.0a0 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + constrains: + - llvm ==20.1.8 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + size: 4102855 + timestamp: 1757394904007 +- conda: https://conda.anaconda.org/conda-forge/win-64/lld-20.1.8-hc465015_1.conda + sha256: 0f00d53ab0c36ff51f4e15485ff7c77c4d4f3e94b2b7f99ecb3fba5bceabb24d + md5: 0a27e0a13861a8299e7ad6b1f0d9fb41 + depends: + - libxml2 + - libxml2-16 >=2.14.6 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - zstd >=1.5.7,<1.6.0a0 + constrains: + - llvm ==20.1.8 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + size: 131581380 + timestamp: 1757395097614 +- conda: https://conda.anaconda.org/conda-forge/linux-64/llvm-tools-20.1.8-hb700be7_1.conda + sha256: 153f96ab1ee7d96214a26968c8dc107b96c65ab4d96a302fc602cd84bafc2e0c + md5: 2339a92546214f7ac54557f674c41e99 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libllvm20 20.1.8 hf7376ad_1 + - libstdcxx >=14 + - llvm-tools-20 20.1.8 h3b15d91_1 + constrains: + - llvm 20.1.8 + - clang 20.1.8 + - llvmdev 20.1.8 + - clang-tools 20.1.8 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 87809 + timestamp: 1757353876330 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-20.1.8-h855ad52_1.conda + sha256: 1f94a0336ac63020b8f8c57dca502cae3238f45e9b4cdd6df1fc06d3837ded5e + md5: 626404d8b36c1ce1d1c2f84d91d8b99d + depends: + - __osx >=11.0 + - libllvm20 20.1.8 h8e0c9ce_1 + - llvm-tools-20 20.1.8 h91fd4e7_1 + constrains: + - llvm 20.1.8 + - llvmdev 20.1.8 + - clang 20.1.8 + - clang-tools 20.1.8 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 88740 + timestamp: 1757354697813 +- conda: https://conda.anaconda.org/conda-forge/win-64/llvm-tools-20.1.8-h752b59f_1.conda + sha256: d65478294ab51baf8876907fbbfafbfbef0243b0a9143d5c554e2157bb02baaf + md5: ca976adb4e89d1c993fa777f07b07c8c + depends: + - libllvm20 20.1.8 h830ff33_1 + - libxml2 + - libxml2-16 >=2.14.5 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - zstd >=1.5.7,<1.6.0a0 + constrains: + - clang 20.1.8 + - llvm 20.1.8 + - clang-tools 20.1.8 + - llvmdev 20.1.8 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 425257536 + timestamp: 1757354652746 +- conda: https://conda.anaconda.org/conda-forge/linux-64/llvm-tools-20-20.1.8-h3b15d91_1.conda + sha256: b0ead2b01a2dbfe2672653764a1ac1a5a21b243dbfb4cfc4b7ae45fc6be671a1 + md5: 1a4ce6138495d4ad3d9a66071573f5d9 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libllvm20 20.1.8 hf7376ad_1 + - libstdcxx >=14 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 26528257 + timestamp: 1757353803953 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-20-20.1.8-h91fd4e7_1.conda + sha256: 97d9c549c34e7e16aff4e719c4e0d12e03cde46249297632dcf770fb86e475d6 + md5: 77366ec6038780fbaa5509f064e93d6f + depends: + - __osx >=11.0 + - libcxx >=19 + - libllvm20 20.1.8 h8e0c9ce_1 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 17569405 + timestamp: 1757354613846 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda + sha256: 3fde293232fa3fca98635e1167de6b7c7fda83caf24b9d6c91ec9eefb4f4d586 + md5: 47e340acb35de30501a76c7c799c41d7 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: X11 AND BSD-3-Clause + size: 891641 + timestamp: 1738195959188 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda + sha256: 2827ada40e8d9ca69a153a45f7fd14f32b2ead7045d3bbb5d10964898fe65733 + md5: 068d497125e4bf8a66bf707254fff5ae + depends: + - __osx >=11.0 + license: X11 AND BSD-3-Clause + size: 797030 + timestamp: 1738196177597 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda + sha256: 6f7d59dbec0a7b00bf5d103a4306e8886678b796ff2151b62452d4582b2a53fb + md5: b518e9e92493721281a60fa975bddc65 + depends: + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + license: Apache-2.0 + license_family: APACHE + size: 186323 + timestamp: 1763688260928 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.13.2-h49c215f_0.conda + sha256: 18d33c17b28d4771fc0b91b7b963c9ce31aca0a9af7dc8e9ee7c974bb207192c + md5: 175809cc57b2c67f27a0f238bd7f069d + depends: + - __osx >=11.0 + - libcxx >=19 + license: Apache-2.0 + license_family: APACHE + size: 164450 + timestamp: 1763688228613 +- conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.13.2-h477610d_0.conda + sha256: e41a945c34a5f0bd2109b73a65486cd93023fa0a9bcba3ef98f9a3da40ba1180 + md5: 7ecb9f2f112c66f959d2bb7dbdb89b67 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: Apache-2.0 + license_family: APACHE + size: 309417 + timestamp: 1763688227932 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda + sha256: a47271202f4518a484956968335b2521409c8173e123ab381e775c358c67fe6d + md5: 9ee58d5c534af06558933af3c845a780 + depends: + - __glibc >=2.17,<3.0.a0 + - ca-certificates + - libgcc >=14 + license: Apache-2.0 + license_family: Apache + size: 3165399 + timestamp: 1762839186699 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.0-h5503f6c_0.conda + sha256: ebe93dafcc09e099782fe3907485d4e1671296bc14f8c383cb6f3dfebb773988 + md5: b34dc4172653c13dcf453862f251af2b + depends: + - __osx >=11.0 + - ca-certificates + license: Apache-2.0 + license_family: Apache + size: 3108371 + timestamp: 1762839712322 +- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.0-h725018a_0.conda + sha256: 6d72d6f766293d4f2aa60c28c244c8efed6946c430814175f959ffe8cab899b3 + md5: 84f8fb4afd1157f59098f618cd2437e4 + depends: + - ca-certificates + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + size: 9440812 + timestamp: 1762841722179 +- conda: https://conda.anaconda.org/conda-forge/linux-64/rhash-1.4.6-hb9d3cd8_1.conda + sha256: d5c73079c1dd2c2a313c3bfd81c73dbd066b7eb08d213778c8bff520091ae894 + md5: c1c9b02933fdb2cfb791d936c20e887e + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: MIT + license_family: MIT + size: 193775 + timestamp: 1748644872902 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/rhash-1.4.6-h5505292_1.conda + sha256: f4957c05f4fbcd99577de8838ca4b5b1ae4b400a44be647a0159c14f85b9bfc0 + md5: 029e812c8ae4e0d4cf6ff4f7d8dc9366 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + size: 185448 + timestamp: 1748645057503 +- conda: https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.17-h0157908_18.conda + sha256: 69ab5804bdd2e8e493d5709eebff382a72fab3e9af6adf93a237ccf8f7dbd624 + md5: 460eba7851277ec1fd80a1a24080787a + depends: + - kernel-headers_linux-64 3.10.0 he073ed8_18 + - tzdata + license: LGPL-2.0-or-later AND LGPL-2.0-or-later WITH exceptions AND GPL-2.0-or-later AND MPL-2.0 + license_family: GPL + size: 15166921 + timestamp: 1735290488259 +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda + sha256: 5aaa366385d716557e365f0a4e9c3fca43ba196872abbbe3d56bb610d131e192 + md5: 4222072737ccff51314b5ece9c7d6f5a + license: LicenseRef-Public-Domain + size: 122968 + timestamp: 1742727099393 +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h8577fbf_1.conda + sha256: 865716d3e2ccaca1218462645830d2370ab075a9a118c238728e1231a234bc6c + md5: e4e8496b68cf5f25e76fbe67f3856550 + license: LicenseRef-Public-Domain + size: 119010 + timestamp: 1765580300078 +- conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + sha256: 3005729dce6f3d3f5ec91dfc49fc75a0095f9cd23bab49efb899657297ac91a5 + md5: 71b24316859acd00bdb8b38f5e2ce328 + constrains: + - vc14_runtime >=14.29.30037 + - vs2015_runtime >=14.29.30037 + license: LicenseRef-MicrosoftWindowsSDK10 + size: 694692 + timestamp: 1756385147981 +- conda: https://conda.anaconda.org/conda-forge/linux-64/uv-0.9.17-h76e24b7_0.conda + sha256: f4b58b6fac4950aa39e4e3aa78d07b2a83bdc9295c4fd4b723b9fc9342170a4d + md5: 4cae6aca4d10274f47e4779a5a19a73d + depends: + - __glibc >=2.17,<3.0.a0 + - libstdcxx >=14 + - libgcc >=14 + constrains: + - __glibc >=2.17 + license: Apache-2.0 OR MIT + size: 17685917 + timestamp: 1765353152876 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/uv-0.9.17-h1bde295_0.conda + sha256: 10b90d25fd0e898910743a4a386e326c9a23836b8fcada517b792794fe8cb67f + md5: d6182c2d49e53e8ceb628f5bb677dddb + depends: + - libcxx >=19 + - __osx >=11.0 + constrains: + - __osx >=11.0 + license: Apache-2.0 OR MIT + size: 15488097 + timestamp: 1765353175319 +- conda: https://conda.anaconda.org/conda-forge/win-64/uv-0.9.17-h3bd95fe_0.conda + sha256: 2d2871d0cdb16e09bb2f325c240718553f8dcd6b5a46fe355eb8eacda3808686 + md5: 152e69b3d8e0994030c75ec55152a892 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: Apache-2.0 OR MIT + size: 18199069 + timestamp: 1765353060856 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_33.conda + sha256: 7036945b5fff304064108c22cbc1bb30e7536363782b0456681ee6cf209138bd + md5: 2d1c042360c09498891809a3765261be + depends: + - vc14_runtime >=14.42.34433 + track_features: + - vc14 + license: BSD-3-Clause + license_family: BSD + size: 19070 + timestamp: 1765216452130 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_33.conda + sha256: 7e8f7da25d7ce975bbe7d7e6d6e899bf1f253e524a3427cc135a79f3a79c457c + md5: fb8e4914c5ad1c71b3c519621e1df7b8 + depends: + - ucrt >=10.0.20348.0 + - vcomp14 14.44.35208 h818238b_33 + constrains: + - vs2015_runtime 14.44.35208.* *_33 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + size: 684323 + timestamp: 1765216366832 +- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_33.conda + sha256: f79edd878094e86af2b2bc1455b0a81e02839a784fb093d5996ad4cf7b810101 + md5: 4cb6942b4bd846e51b4849f4a93c7e6d + depends: + - ucrt >=10.0.20348.0 + constrains: + - vs2015_runtime 14.44.35208.* *_33 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + size: 115073 + timestamp: 1765216325898 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xz-5.8.1-hbcc6ac9_2.conda + sha256: 802725371682ea06053971db5b4fb7fbbcaee9cb1804ec688f55e51d74660617 + md5: 68eae977d7d1196d32b636a026dc015d + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - liblzma 5.8.1 hb9d3cd8_2 + - liblzma-devel 5.8.1 hb9d3cd8_2 + - xz-gpl-tools 5.8.1 hbcc6ac9_2 + - xz-tools 5.8.1 hb9d3cd8_2 + license: 0BSD AND LGPL-2.1-or-later AND GPL-2.0-or-later + size: 23987 + timestamp: 1749230104359 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/xz-5.8.1-h9a6d368_2.conda + sha256: afb747cf017b67cc31d54c6e6c4bd1b1e179fe487a3d23a856232ed7fd0b099b + md5: 39435c82e5a007ef64cbb153ecc40cfd + depends: + - __osx >=11.0 + - liblzma 5.8.1 h39f12f2_2 + - liblzma-devel 5.8.1 h39f12f2_2 + - xz-gpl-tools 5.8.1 h9a6d368_2 + - xz-tools 5.8.1 h39f12f2_2 + license: 0BSD AND LGPL-2.1-or-later AND GPL-2.0-or-later + size: 23995 + timestamp: 1749230346887 +- conda: https://conda.anaconda.org/conda-forge/win-64/xz-5.8.1-h208afaa_2.conda + sha256: 22289a81da4698bb8d13ac032a88a4a1f49505b2303885e1add3d8bd1a7b56e6 + md5: fb3fa84ea37de9f12cc8ba730cec0bdc + depends: + - liblzma 5.8.1 h2466b09_2 + - liblzma-devel 5.8.1 h2466b09_2 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - xz-tools 5.8.1 h2466b09_2 + license: 0BSD AND LGPL-2.1-or-later AND GPL-2.0-or-later + size: 24430 + timestamp: 1749230691276 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xz-gpl-tools-5.8.1-hbcc6ac9_2.conda + sha256: 840838dca829ec53f1160f3fca6dbfc43f2388b85f15d3e867e69109b168b87b + md5: bf627c16aa26231720af037a2709ab09 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - liblzma 5.8.1 hb9d3cd8_2 + constrains: + - xz 5.8.1.* + license: 0BSD AND LGPL-2.1-or-later AND GPL-2.0-or-later + size: 33911 + timestamp: 1749230090353 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/xz-gpl-tools-5.8.1-h9a6d368_2.conda + sha256: a0790cfb48d240e7b655b0d797a00040219cf39e3ee38e2104e548515df4f9c2 + md5: 09b1442c1d49ac7c5f758c44695e77d1 + depends: + - __osx >=11.0 + - liblzma 5.8.1 h39f12f2_2 + constrains: + - xz 5.8.1.* + license: 0BSD AND LGPL-2.1-or-later AND GPL-2.0-or-later + size: 34103 + timestamp: 1749230329933 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xz-tools-5.8.1-hb9d3cd8_2.conda + sha256: 58034f3fca491075c14e61568ad8b25de00cb3ae479de3e69be6d7ee5d3ace28 + md5: 1bad2995c8f1c8075c6c331bf96e46fb + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - liblzma 5.8.1 hb9d3cd8_2 + constrains: + - xz 5.8.1.* + license: 0BSD AND LGPL-2.1-or-later + size: 96433 + timestamp: 1749230076687 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/xz-tools-5.8.1-h39f12f2_2.conda + sha256: 9d1232705e3d175f600dc8e344af9182d0341cdaa73d25330591a28532951063 + md5: 37996935aa33138fca43e4b4563b6a28 + depends: + - __osx >=11.0 + - liblzma 5.8.1 h39f12f2_2 + constrains: + - xz 5.8.1.* + license: 0BSD AND LGPL-2.1-or-later + size: 86425 + timestamp: 1749230316106 +- conda: https://conda.anaconda.org/conda-forge/win-64/xz-tools-5.8.1-h2466b09_2.conda + sha256: 38712f0e62f61741ab69d7551fa863099f5be769bdf9fdbc28542134874b4e88 + md5: e1b62ec0457e6ba10287a49854108fdb + depends: + - liblzma 5.8.1 h2466b09_2 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + constrains: + - xz 5.8.1.* + license: 0BSD AND LGPL-2.1-or-later + size: 67419 + timestamp: 1749230666460 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 + md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 + depends: + - __glibc >=2.17,<3.0.a0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + size: 601375 + timestamp: 1764777111296 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + sha256: 9485ba49e8f47d2b597dd399e88f4802e100851b27c21d7525625b0b4025a5d9 + md5: ab136e4c34e97f34fb621d2592a393d8 + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + size: 433413 + timestamp: 1764777166076 +- conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + sha256: 368d8628424966fd8f9c8018326a9c779e06913dd39e646cf331226acc90e5b2 + md5: 053b84beec00b71ea8ff7a4f84b55207 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + size: 388453 + timestamp: 1764777142545 diff --git a/pixi.toml b/pixi.toml new file mode 100644 index 000000000..0d211c5dd --- /dev/null +++ b/pixi.toml @@ -0,0 +1,69 @@ +[workspace] +name = "clice" +version = "0.1.0" +description = "A next-generation C++ language server for modern C++" +authors = [ + "ykiko ", + "clice contributors ", +] + +license = "Apache-2.0" +license-file = "LICENSE" +readme = "README.md" +documentation = "https://clice.io" +repository = "https://github.com/clice-io/clice" + +channels = ["conda-forge"] +platforms = ["win-64", "linux-64", "osx-arm64"] + +[dependencies] +cmake = ">=3.30" +ninja = "*" +clang = "==20.1.8" +clangxx = "==20.1.8" +lld = "==20.1.8" +llvm-tools = "==20.1.8" +compiler-rt = "==20.1.8" + +[target.linux-64.dependencies] +sysroot_linux-64 = "==2.17" +gcc = "==14.2.0" +gxx = "==14.2.0" + +[target.win-64.activation] +scripts = ["scripts/activate_asan.bat"] + +[target.linux-64.activation] +scripts = ["scripts/activate_linux.sh"] + +[feature.test.dependencies] +uv = "*" + +[feature.package.dependencies] +xz = ">=5.8.1,<6" + +[environments] +default = [] +develop = ["test"] +package = ["test", "package"] + +[tasks.build-llvm] +cmd = ["python3", "scripts/build-llvm.py"] + +[tasks.upload-llvm] +args = [ + "workflow_id", + "llvm_version", + { "arg" = "branch", default = "main" }, +] +cmd = [ + "gh", "workflow", "run", "upload-llvm.yml", + "--ref", "{{ branch }}", + "--field", "workflow_id={{workflow_id}}", + "--field", "version={{llvm_version}}", +] + +[tasks.delete-artifacts] +# delete all workflows generated by "file_name" +args = ["file_name"] +cmd = ["scripts/delete-artifacts.bash", "{{ file_name }}"] diff --git a/scripts/activate_asan.bat b/scripts/activate_asan.bat new file mode 100644 index 000000000..d7605f82b --- /dev/null +++ b/scripts/activate_asan.bat @@ -0,0 +1,3 @@ +@echo off +for /f "delims=" %%i in ('clang-cl --print-resource-dir') do set "CLANG_RES=%%i" +set "PATH=%CLANG_RES%\lib\windows;%PATH%" diff --git a/scripts/activate_linux.sh b/scripts/activate_linux.sh new file mode 100644 index 000000000..934462c76 --- /dev/null +++ b/scripts/activate_linux.sh @@ -0,0 +1,2 @@ +#!/bin/sh +export LD_LIBRARY_PATH="$CONDA_PREFIX/lib:$LD_LIBRARY_PATH" diff --git a/scripts/build-llvm-libs.py b/scripts/build-llvm-libs.py deleted file mode 100755 index 058c58c1c..000000000 --- a/scripts/build-llvm-libs.py +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env python3 -import os -import subprocess -import shutil -import argparse -import sys - - -def get_build_config(build_type): - """Return build configuration based on build type""" - configs = { - "debug": { - "build_dir": "build-debug", - "install_dir": "./build-debug-install", - "build_type": "Debug", - "sanitizer": "Address", - "shared_libs": True, - }, - "thread": { - "build_dir": "build-thread", - "install_dir": "./build-thread-install", - "build_type": "Debug", - "sanitizer": "Thread", - "shared_libs": True, - }, - "release": { - "build_dir": "build-release", - "install_dir": "./build-release-install", - "build_type": "Release", - "sanitizer": None, - "shared_libs": False, - }, - } - - if build_type not in configs: - print(f"Error: Unsupported build type '{build_type}'") - print(f"Supported build types: {', '.join(configs.keys())}") - sys.exit(1) - - return configs[build_type] - - -def build_llvm(config): - """Execute LLVM build process""" - print(f"Starting LLVM build ({config['build_type']} mode)") - - # Build CMake command - config_args = [ - "cmake", - "-G", - "Ninja", - "-S", - "./llvm", - "-B", - config["build_dir"], - "-DLLVM_USE_LINKER=lld", - "-DCMAKE_C_COMPILER=clang", - "-DCMAKE_CXX_COMPILER=clang++", - "-DCMAKE_BUILD_TYPE=" + config["build_type"], - # Only build native to speed up building llvm. - "-DLLVM_TARGETS_TO_BUILD=Native", - "-DLLVM_ENABLE_PROJECTS=clang;clang-tools-extra", - "-DCMAKE_INSTALL_PREFIX=" + config["install_dir"], - ] - - # Add optional configurations - - # Build shared lib to reduce binary size and speed up linking - if config["shared_libs"]: - config_args.append("-DBUILD_SHARED_LIBS=ON") - - if config["sanitizer"]: - config_args.append(f"-DLLVM_USE_SANITIZER={config['sanitizer']}") - - # CMake build command list - cmake_commands = [ - config_args, - ["cmake", "--build", config["build_dir"]], - ["cmake", "--install", config["build_dir"]], - ] - - # Execute CMake commands - for i, command in enumerate(cmake_commands): - print(f"Executing command {i + 1}/{len(cmake_commands)}: {' '.join(command)}") - try: - subprocess.run(command, check=True) - except subprocess.CalledProcessError as e: - print(f"Build failed: {e}") - sys.exit(1) - - -def copy_header_files(config): - """Copy header files to installation directory""" - print("Copying header files...") - - src = "./clang/lib/Sema/" - dst = os.path.join(config["install_dir"], "include/clang/Sema/") - files = ["CoroutineStmtBuilder.h", "TypeLocBuilder.h", "TreeTransform.h"] - - # Ensure target directory exists - os.makedirs(dst, exist_ok=True) - - for file in files: - src_file = os.path.join(src, file) - dst_file = os.path.join(dst, file) - - if os.path.exists(src_file): - print(f"Copying {src_file} to {dst_file}") - shutil.copy(src_file, dst_file) - else: - print(f"Warning: Source file does not exist {src_file}") - - -def main(): - parser = argparse.ArgumentParser( - description="Build LLVM libraries with different build configurations", - formatter_class=argparse.RawDescriptionHelpFormatter, - epilog=""" -Build type descriptions: - debug - Debug mode with Address Sanitizer, builds shared libraries - thread - Debug mode with Thread Sanitizer, builds shared libraries - release - Release mode without sanitizer, builds static libraries - -Examples: - python build-llvm-libs.py debug - python build-llvm-libs.py thread - python build-llvm-libs.py release - """, - ) - - parser.add_argument( - "build_type", - choices=["debug", "thread", "release"], - help="Build type (debug/thread/release)", - ) - - parser.add_argument( - "--skip-copy", action="store_true", help="Skip header file copying step" - ) - - args = parser.parse_args() - - # Get build configuration - config = get_build_config(args.build_type) - - print("=== LLVM Build Configuration ===") - print(f"Build type: {args.build_type}") - print(f"Build directory: {config['build_dir']}") - print(f"Install directory: {config['install_dir']}") - print(f"CMake build type: {config['build_type']}") - if config["sanitizer"]: - print(f"Sanitizer: {config['sanitizer']}") - print(f"Shared libraries: {config['shared_libs']}") - print("=" * 30) - - # Execute build - build_llvm(config) - - # Copy header files (unless skipped) - if not args.skip_copy: - copy_header_files(config) - - print(f"\n✅ LLVM {args.build_type} build completed!") - print(f"Install directory: {config['install_dir']}") - - -if __name__ == "__main__": - main() diff --git a/scripts/build-llvm.py b/scripts/build-llvm.py new file mode 100644 index 000000000..97a406586 --- /dev/null +++ b/scripts/build-llvm.py @@ -0,0 +1,340 @@ +#!/usr/bin/env python3 +import sys +import subprocess +import shutil +import argparse +import os +from pathlib import Path + + +def normalize_mode(value: str) -> str: + mapping = { + "debug": "Debug", + "release": "Release", + "relwithdebinfo": "RelWithDebInfo", + "releasedbg": "RelWithDebInfo", + } + key = value.strip().lower() + if key in mapping: + return mapping[key] + raise argparse.ArgumentTypeError( + f"Invalid mode '{value}'. Choose from Debug, Release, RelWithDebInfo." + ) + + +def main(): + parser = argparse.ArgumentParser( + description="Build LLVM with specific configurations." + ) + parser.add_argument( + "--llvm-src", + help="Path to llvm-project source root (defaults to current working directory)", + ) + parser.add_argument( + "--mode", + default="Release", + type=normalize_mode, + choices=["Debug", "Release", "RelWithDebInfo"], + help="Build mode (default: Release)", + ) + parser.add_argument( + "--lto", + default="OFF", + type=lambda s: s.upper(), + choices=["ON", "OFF"], + help="Enable LTO (default: OFF)", + ) + parser.add_argument( + "--build-dir", + help="Custom build directory (relative to project root or absolute)", + ) + + args = parser.parse_args() + + repo_root = Path(__file__).resolve().parent.parent + toolchain_file = repo_root / "cmake" / "toolchain.cmake" + if not toolchain_file.exists(): + print(f"Error: toolchain file not found at {toolchain_file}") + sys.exit(1) + + if args.llvm_src: + project_root = Path(args.llvm_src).expanduser().resolve() + else: + project_root = Path.cwd() + os.chdir(project_root) + + if not (project_root / "llvm" / "CMakeLists.txt").exists(): + print(f"Error: Could not find 'llvm/CMakeLists.txt' in {project_root}") + print("Please run this script from the root of the llvm-project repository.") + sys.exit(1) + + lto_enabled = args.lto == "ON" + mode_for_dir = args.mode.lower() + + if args.build_dir: + build_dir = Path(args.build_dir) + if not build_dir.is_absolute(): + build_dir = project_root / build_dir + else: + build_dir = f"build-{mode_for_dir}" + if lto_enabled: + build_dir += "-lto" + build_dir = project_root / build_dir + install_prefix = build_dir.parent / f"{build_dir.name}-install" + + print("--- Configuration ---") + print(f"Mode: {args.mode}") + print(f"LTO: {args.lto}") + print(f"Root: {project_root}") + print(f"Build Dir: {build_dir}") + print(f"Install Prefix: {install_prefix}") + print(f"Toolchain: {toolchain_file}") + print("---------------------") + + llvm_distribution_components = [ + "LLVMDemangle", + "LLVMSupport", + "LLVMCore", + "LLVMOption", + "LLVMBinaryFormat", + "LLVMMC", + "LLVMMCParser", + "LLVMObject", + "LLVMProfileData", + "LLVMBitReader", + "LLVMBitstreamReader", + "LLVMRemarks", + "LLVMObjectYAML", + "LLVMAggressiveInstCombine", + "LLVMInstCombine", + "LLVMIRReader", + "LLVMTextAPI", + "LLVMSymbolize", + "LLVMDebugInfoDWARF", + "LLVMDebugInfoDWARFLowLevel", + "LLVMDebugInfoCodeView", + "LLVMDebugInfoGSYM", + "LLVMDebugInfoPDB", + "LLVMDebugInfoBTF", + "LLVMDebugInfoMSF", + "LLVMAsmParser", + "LLVMTargetParser", + "LLVMTransformUtils", + "LLVMAnalysis", + "LLVMScalarOpts", + "LLVMFrontendHLSL", + "LLVMFrontendOpenMP", + "LLVMFrontendOffloading", + "LLVMFrontendAtomic", + "LLVMFrontendDirective", + "LLVMWindowsDriver", + "clangIndex", + "clangAPINotes", + "clangAST", + "clangASTMatchers", + "clangBasic", + "clangDriver", + "clangFormat", + "clangFrontend", + "clangLex", + "clangParse", + "clangSema", + "clangSerialization", + "clangRewrite", + "clangAnalysis", + "clangEdit", + "clangSupport", + "clangStaticAnalyzerCore", + "clangStaticAnalyzerFrontend", + "clangTidy", + "clangTidyUtils", + "clangTidyAndroidModule", + "clangTidyAbseilModule", + "clangTidyAlteraModule", + "clangTidyBoostModule", + "clangTidyBugproneModule", + "clangTidyCERTModule", + "clangTidyConcurrencyModule", + "clangTidyCppCoreGuidelinesModule", + "clangTidyDarwinModule", + "clangTidyFuchsiaModule", + "clangTidyGoogleModule", + "clangTidyHICPPModule", + "clangTidyLinuxKernelModule", + "clangTidyLLVMModule", + "clangTidyLLVMLibcModule", + "clangTidyMiscModule", + "clangTidyModernizeModule", + "clangTidyObjCModule", + "clangTidyOpenMPModule", + "clangTidyPerformanceModule", + "clangTidyPortabilityModule", + "clangTidyReadabilityModule", + "clangTidyZirconModule", + "clangTooling", + "clangToolingCore", + "clangToolingInclusions", + "clangToolingInclusionsStdlib", + "clangToolingSyntax", + "clangToolingRefactoring", + "clangTransformer", + "clangCrossTU", + "clangAnalysisFlowSensitive", + "clangAnalysisFlowSensitiveModels", + "clangStaticAnalyzerCheckers", + "clangIncludeCleaner", + "llvm-headers", + "clang-headers", + "clang-tidy-headers", + "clang-resource-headers", + ] + + components_joined = ";".join(llvm_distribution_components) + cmake_args = [ + "-G", + "Ninja", + f"-DCMAKE_TOOLCHAIN_FILE={toolchain_file.as_posix()}", + f"-DCMAKE_INSTALL_PREFIX={install_prefix}", + "-DCMAKE_C_FLAGS=-w", + "-DCMAKE_CXX_FLAGS=-w", + "-DLLVM_ENABLE_ZLIB=OFF", + "-DLLVM_ENABLE_ZSTD=OFF", + "-DLLVM_ENABLE_LIBXML2=OFF", + "-DLLVM_ENABLE_BINDINGS=OFF", + "-DLLVM_ENABLE_IDE=OFF", + "-DLLVM_ENABLE_Z3_SOLVER=OFF", + "-DLLVM_ENABLE_LIBEDIT=OFF", + "-DLLVM_ENABLE_LIBPFM=OFF", + "-DLLVM_ENABLE_OCAMLDOC=OFF", + "-DLLVM_ENABLE_PLUGINS=OFF", + "-DLLVM_INCLUDE_UTILS=OFF", + "-DLLVM_INCLUDE_TESTS=OFF", + "-DLLVM_INCLUDE_EXAMPLES=OFF", + "-DLLVM_INCLUDE_BENCHMARKS=OFF", + "-DLLVM_INCLUDE_DOCS=OFF", + "-DLLVM_BUILD_UTILS=OFF", + "-DLLVM_BUILD_TOOLS=OFF", + "-DCLANG_BUILD_TOOLS=OFF", + "-DCLANG_INCLUDE_DOCS=OFF", + "-DCLANG_INCLUDE_TESTS=OFF", + "-DCLANG_TOOL_CLANG_IMPORT_TEST_BUILD=OFF", + "-DCLANG_TOOL_CLANG_LINKER_WRAPPER_BUILD=OFF", + "-DCLANG_TOOL_C_INDEX_TEST_BUILD=OFF", + "-DCLANG_TOOL_LIBCLANG_BUILD=OFF", + "-DCLANG_ENABLE_CLANGD=OFF", + "-DLLVM_BUILD_LLVM_C_DYLIB=OFF", + "-DLLVM_LINK_LLVM_DYLIB=OFF", + "-DLLVM_ENABLE_RTTI=OFF", + # Enable features + "-DLLVM_INCLUDE_TOOLS=ON", + "-DLLVM_PARALLEL_LINK_JOBS=1", + "-DCMAKE_JOB_POOL_LINK=console", + "-DLLVM_ENABLE_PROJECTS=clang;clang-tools-extra", + "-DLLVM_TARGETS_TO_BUILD=all", + "-DLLVM_USE_LINKER=lld", + "-DLLVM_DISABLE_ASSEMBLY_FILES=ON", + # Distribution + f"-DLLVM_DISTRIBUTION_COMPONENTS={components_joined}", + ] + + ccache_env = os.environ.get("CCACHE_PROGRAM") or os.environ.get("CCACHE") + ccache_program = shutil.which(ccache_env) if ccache_env else shutil.which("ccache") + if not ccache_program and ccache_env: + # Fall back to the env value as-is if it points to a real path. + candidate = Path(ccache_env) + if candidate.exists(): + ccache_program = candidate.as_posix() + + if ccache_program: + ccache_path = Path(ccache_program).as_posix() + print(f"Using ccache: {ccache_path}") + cmake_args.append("-DLLVM_CCACHE_BUILD=ON") + cmake_args.append(f"-DCCACHE_PROGRAM={ccache_path}") + else: + print("ccache not found; proceeding without it.") + + is_shared = "OFF" + if args.mode == "Debug": + cmake_args.append("-DCMAKE_BUILD_TYPE=Debug") + cmake_args.append("-DLLVM_USE_SANITIZER=Address") + is_shared = "ON" + elif args.mode == "Release": + cmake_args.append("-DCMAKE_BUILD_TYPE=Release") + elif args.mode == "RelWithDebInfo": + cmake_args.append("-DCMAKE_BUILD_TYPE=RelWithDebInfo") + + if sys.platform == "win32": + is_shared = "OFF" + cmake_args.append(f"-DBUILD_SHARED_LIBS={is_shared}") + + if lto_enabled: + cmake_args.append("-DLLVM_ENABLE_LTO=Thin") + else: + cmake_args.append("-DLLVM_ENABLE_LTO=OFF") + + build_dir.mkdir(exist_ok=True) + + print(f"\nConfiguring in {build_dir}...") + try: + source_dir = project_root / "llvm" + subprocess.check_call( + ["cmake", "-S", str(source_dir), "-B", str(build_dir)] + cmake_args + ) + except subprocess.CalledProcessError: + print("CMake configuration failed!") + sys.exit(1) + + print("\nBuilding 'install-distribution' target...") + try: + subprocess.check_call( + ["cmake", "--build", str(build_dir), "--target", "install-distribution"] + ) + except subprocess.CalledProcessError: + print("Build failed!") + sys.exit(1) + + print("\nCopying internal Sema headers...") + clang_sema_dir = project_root / "clang/lib/Sema" + install_sema_dir = install_prefix / "include/clang/Sema" + install_sema_dir.mkdir(parents=True, exist_ok=True) + + headers_to_copy = ["CoroutineStmtBuilder.h", "TypeLocBuilder.h", "TreeTransform.h"] + + for header in headers_to_copy: + src = clang_sema_dir / header + dst = install_sema_dir / header + if src.exists(): + shutil.copy(src, dst) + print(f" Copied {header}") + else: + print(f" Warning: {header} not found in source.") + + def human_readable(num: int) -> str: + for unit in ["B", "KB", "MB", "GB"]: + if num < 1024.0: + return f"{num:,.1f}{unit}" + num /= 1024.0 + return f"{num:.1f}TB" + + lib_dir = install_prefix / "lib" + sizes = [] + if lib_dir.exists(): + for p in lib_dir.rglob("*"): + if p.is_file(): + sizes.append((p, p.stat().st_size)) + sizes.sort(key=lambda x: x[1], reverse=True) + + total_size = sum(sz for _, sz in sizes) + print(f"\nLibrary size summary under {lib_dir}:") + print(f" Total: {human_readable(total_size)} across {len(sizes)} files") + for path, sz in sizes: + rel = path.relative_to(install_prefix) + print(f" {human_readable(sz):>8} {rel}") + if not sizes: + print(" (no files found)") + + print(f"\nSuccess! Artifacts installed to: {install_prefix}") + + +if __name__ == "__main__": + main() diff --git a/scripts/delete-artifacts.bash b/scripts/delete-artifacts.bash new file mode 100755 index 000000000..d34a9b5b5 --- /dev/null +++ b/scripts/delete-artifacts.bash @@ -0,0 +1,37 @@ +#!/bin/bash + +# Configuration: workflow file name can be provided as the first argument, defaults to llvm.yml +WORKFLOW_FILE_NAME="${1:-llvm.yml}" +RUN_LIMIT=1000 + +echo "Searching for all runs of workflow ${WORKFLOW_FILE_NAME}..." + +# Retrieve all workflow run IDs +RUN_IDS=$(gh run list --workflow "${WORKFLOW_FILE_NAME}" --json databaseId --jq '.[].databaseId' --limit $RUN_LIMIT) + +if [ -z "$RUN_IDS" ]; then + echo "No runs found for workflow ${WORKFLOW_FILE_NAME}." + exit 0 +fi + +echo "Found the following Run IDs:" +echo "$RUN_IDS" +echo "---" + +# Loop and delete each workflow run (and its Artifacts) +echo "Starting deletion of runs and their Artifacts..." + +for RUN_ID in $RUN_IDS; do + echo "Deleting Run ID: ${RUN_ID}..." + # Older gh releases may not support --confirm; pipe "y" to avoid interactive prompt. + if yes | gh run delete "${RUN_ID}"; then + echo "Successfully deleted Run ${RUN_ID}." + else + echo "Failed to delete Run ${RUN_ID}!" + fi + sleep 0.5 +done + +echo "" +echo "---" +echo "All workflow runs and associated Artifacts have been processed." diff --git a/scripts/download-llvm.sh b/scripts/download-llvm.sh new file mode 100755 index 000000000..3a640e031 --- /dev/null +++ b/scripts/download-llvm.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +set -euo pipefail + +if [[ $# -ne 1 ]]; then + echo "Usage: $0 " >&2 + exit 1 +fi + +WORKFLOW_ID="$1" + +mkdir -p artifacts +gh run download "${WORKFLOW_ID}" --dir artifacts + +echo "Downloaded artifacts:" +find artifacts -maxdepth 4 -type f -print diff --git a/scripts/monitor-resources.ps1 b/scripts/monitor-resources.ps1 new file mode 100644 index 000000000..f044c2377 --- /dev/null +++ b/scripts/monitor-resources.ps1 @@ -0,0 +1,39 @@ +param( + [string]$LogFile = "ci-resource-usage.log", + [int]$IntervalSeconds = 30 +) + +function Write-Log { + param( + [Parameter(ValueFromPipeline = $true)] + [string]$Message + ) + process { + Add-Content -Path $LogFile -Value $Message + } +} + +"Resource monitor started for Windows, interval ${IntervalSeconds}s, writing to ${LogFile}" | Write-Log + +while ($true) { + $timestamp = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") + + "[$timestamp] ===== Disk =====" | Write-Log + try { + $disk = Get-Volume | Select-Object DriveLetter, FileSystem, @{Name="FreeGB";Expression={[math]::Round($_.SizeRemaining/1GB,2)}}, @{Name="SizeGB";Expression={[math]::Round($_.Size/1GB,2)}} | Format-Table -AutoSize | Out-String + $disk | Write-Log + } catch { + "Disk query failed: $($_.Exception.Message)" | Write-Log + } + + "[$timestamp] ===== Memory =====" | Write-Log + try { + $mem = Get-CimInstance Win32_OperatingSystem | Select-Object @{Name="TotalGB";Expression={[math]::Round($_.TotalVisibleMemorySize/1MB,2)}}, @{Name="FreeGB";Expression={[math]::Round($_.FreePhysicalMemory/1MB,2)}} | Format-Table -AutoSize | Out-String + $mem | Write-Log + } catch { + "Memory query failed: $($_.Exception.Message)" | Write-Log + } + + "" | Write-Log + Start-Sleep -Seconds $IntervalSeconds +} diff --git a/scripts/monitor-resources.sh b/scripts/monitor-resources.sh new file mode 100644 index 000000000..895687a62 --- /dev/null +++ b/scripts/monitor-resources.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +# Periodically logs disk and memory usage to a file. +# Usage: monitor-resources.sh [log-file] + +set -uo pipefail + +LOG_FILE="${1:-ci-resource-usage.log}" +INTERVAL="${CLICE_MONITOR_INTERVAL:-30}" +OS="$(uname -s)" + +echo "Resource monitor started for ${OS}, interval ${INTERVAL}s, writing to ${LOG_FILE}" >> "${LOG_FILE}" + +log_disk() { + echo "[$(date -u +"%Y-%m-%dT%H:%M:%SZ")] ===== Disk =====" >> "${LOG_FILE}" + df -h >> "${LOG_FILE}" 2>&1 +} + +log_mem() { + echo "[$(date -u +"%Y-%m-%dT%H:%M:%SZ")] ===== Memory =====" >> "${LOG_FILE}" + case "${OS}" in + Linux) + if command -v free >/dev/null 2>&1; then + free -h >> "${LOG_FILE}" 2>&1 + else + cat /proc/meminfo >> "${LOG_FILE}" 2>&1 + fi + ;; + Darwin) + if command -v vm_stat >/dev/null 2>&1; then + PAGESIZE="$(sysctl -n hw.pagesize 2>/dev/null || echo 4096)" + TOTAL_MEM="$(sysctl -n hw.memsize 2>/dev/null || echo 0)" + echo "Total Memory: ${TOTAL_MEM} bytes" >> "${LOG_FILE}" + vm_stat >> "${LOG_FILE}" 2>&1 + # Derive an approximate free/used breakdown to make the log easier to read. + FREE_PAGES="$(vm_stat | awk '/(Pages free|Pages speculative)/ {gsub(/\\./,\"\",$3); total+=$3} END {print total+0}')" + if [[ -n "${FREE_PAGES}" ]]; then + FREE_BYTES=$((FREE_PAGES * PAGESIZE)) + echo "Approx Free: ${FREE_BYTES} bytes" >> "${LOG_FILE}" + fi + else + echo "vm_stat unavailable" >> "${LOG_FILE}" + fi + ;; + *) + echo "Unsupported OS for memory logging: ${OS}" >> "${LOG_FILE}" + ;; + esac +} + +while true; do + log_disk + log_mem + echo "" >> "${LOG_FILE}" + sleep "${INTERVAL}" +done diff --git a/scripts/prune-llvm-bin.py b/scripts/prune-llvm-bin.py new file mode 100644 index 000000000..9a392156f --- /dev/null +++ b/scripts/prune-llvm-bin.py @@ -0,0 +1,261 @@ +#!/usr/bin/env python3 +""" +Prune unused LLVM binaries/libraries from the install tree. + +Two modes: + - discover: iteratively delete candidates and rebuild to confirm they are unused, + then write the deletion list to a manifest JSON file. + - apply: read the manifest and delete the listed files without rebuilding + (useful for LTO builds that trust the non-LTO pruning result). +""" + +import argparse +import json +import shutil +import subprocess +import time +from datetime import datetime, timezone +from pathlib import Path +from typing import Iterable, List, Optional + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Prune unused LLVM artifacts.") + parser.add_argument( + "--action", + choices=["discover", "apply"], + default="discover", + help="discover: probe deletable files and record them; apply: delete using manifest", + ) + parser.add_argument( + "--install-dir", + type=Path, + default=Path(".llvm/build-install/lib"), + help="Path to the LLVM install lib directory (default: .llvm/build-install/lib)", + ) + parser.add_argument( + "--build-dir", + type=Path, + default=Path("build"), + help="CMake build directory used for validation builds (default: build)", + ) + parser.add_argument( + "--manifest", + type=Path, + default=Path("pruned-libs.json"), + help="Path to manifest JSON for recording or applying deletions", + ) + parser.add_argument( + "--gh-run-id", + type=str, + help="GitHub run ID to download manifest from when applying", + ) + parser.add_argument( + "--gh-artifact", + type=str, + default="llvm-pruned-libs", + help="Artifact name/pattern that contains the manifest", + ) + parser.add_argument( + "--gh-download-dir", + type=Path, + default=Path("artifacts"), + help="Directory to place downloaded artifacts", + ) + parser.add_argument( + "--max-attempts", + type=int, + default=30, + help="Maximum attempts when waiting for manifest download", + ) + parser.add_argument( + "--sleep-seconds", + type=int, + default=60, + help="Seconds to sleep between manifest download attempts", + ) + return parser.parse_args() + + +def _print_failure_output( + result: subprocess.CalledProcessError, max_lines: int = 50 +) -> None: + stdout = getattr(result, "stdout", "") or "" + stderr = getattr(result, "stderr", "") or "" + combined = stdout + stderr + if not combined: + return + print("Build output (last lines):") + lines = combined.splitlines() + for line in lines[-max_lines:]: + print(line) + + +def run_build(build_dir: Path) -> bool: + cmd = ["cmake", "--build", str(build_dir)] + print(f"Running: {' '.join(cmd)}") + try: + subprocess.run(cmd, check=True, capture_output=True, text=True) + return True + except subprocess.CalledProcessError as exc: + _print_failure_output(exc) + return False + + +def candidate_files(install_dir: Path) -> Iterable[Path]: + if not install_dir.is_dir(): + raise FileNotFoundError(f"lib dir not found: {install_dir}") + for path in sorted(install_dir.iterdir()): + if not path.is_file(): + continue + if path.suffix.lower() in {".a", ".lib"}: + yield path + else: + print(f"Skipping non-static file: {path.name}") + + +def try_delete(path: Path, build_dir: Path) -> bool: + backup = path.with_suffix(path.suffix + ".bak") + print(f"Testing deletion: {path}") + shutil.move(path, backup) + success = run_build(build_dir) + if success: + backup.unlink(missing_ok=True) + print(f"Safe to delete: {path.name}") + return True + shutil.move(backup, path) + print(f"Required; restored: {path.name}") + return False + + +def discover(install_dir: Path, build_dir: Path) -> List[str]: + deletable: List[str] = [] + for path in candidate_files(install_dir): + if try_delete(path, build_dir): + deletable.append(path.name) + return deletable + + +def write_manifest( + manifest: Path, removed: List[str], install_dir: Path, build_dir: Path +) -> None: + data = { + "generated_at": datetime.now(timezone.utc).isoformat(), + "install_dir": str(install_dir), + "build_dir": str(build_dir), + "removed": removed, + } + manifest.write_text(json.dumps(data, indent=2)) + print(f"Wrote manifest with {len(removed)} entries to {manifest}") + + +def apply_manifest(manifest: Path, install_dir: Path) -> None: + if not manifest.is_file(): + raise FileNotFoundError(f"Manifest not found: {manifest}") + data = json.loads(manifest.read_text()) + removed = data.get("removed", []) + if not isinstance(removed, list): + raise ValueError("Manifest missing 'removed' list") + for name in removed: + target = install_dir / name + if target.exists(): + print(f"Deleting {target}") + target.unlink() + else: + print(f"Already absent: {target}") + + +def find_manifest(download_dir: Path, manifest_name: str) -> Optional[Path]: + for path in download_dir.rglob(manifest_name): + if path.is_file(): + return path + return None + + +def wait_and_download_manifest( + run_id: str, + artifact: str, + download_dir: Path, + manifest_name: str, + max_attempts: int, + sleep_seconds: int, +) -> Path: + download_dir.mkdir(parents=True, exist_ok=True) + for attempt in range(1, max_attempts + 1): + print( + f"[{attempt}/{max_attempts}] Downloading manifest via gh run download " + f"(run={run_id}, artifact={artifact})" + ) + cmd = [ + "gh", + "run", + "download", + str(run_id), + "--pattern", + artifact, + "--dir", + str(download_dir), + ] + result = subprocess.run(cmd, capture_output=True, text=True) + if result.returncode == 0: + found = find_manifest(download_dir, manifest_name) + if found: + print(f"Found manifest at {found}") + return found + print("Download succeeded but manifest not found; retrying...") + else: + print("gh run download failed; stderr follows:") + print(result.stderr) + if attempt < max_attempts: + time.sleep(sleep_seconds) + raise RuntimeError("Manifest could not be downloaded within the allotted attempts") + + +def ensure_manifest( + manifest: Path, + run_id: Optional[str], + artifact: str, + download_dir: Path, + max_attempts: int, + sleep_seconds: int, +) -> Path: + if manifest.exists(): + return manifest + if not run_id: + raise FileNotFoundError( + f"Manifest {manifest} missing and no gh run ID provided for download" + ) + downloaded = wait_and_download_manifest( + run_id=run_id, + artifact=artifact, + download_dir=download_dir, + manifest_name=manifest.name, + max_attempts=max_attempts, + sleep_seconds=sleep_seconds, + ) + if downloaded != manifest: + shutil.copy(downloaded, manifest) + return manifest + + +def main() -> None: + args = parse_args() + install_dir = args.install_dir + build_dir = args.build_dir + if args.action == "discover": + deletable = discover(install_dir, build_dir) + write_manifest(args.manifest, deletable, install_dir, build_dir) + else: + manifest = ensure_manifest( + manifest=args.manifest, + run_id=args.gh_run_id, + artifact=args.gh_artifact, + download_dir=args.gh_download_dir, + max_attempts=args.max_attempts, + sleep_seconds=args.sleep_seconds, + ) + apply_manifest(manifest, install_dir) + + +if __name__ == "__main__": + main() diff --git a/scripts/setup-llvm.py b/scripts/setup-llvm.py new file mode 100644 index 000000000..e62697fe8 --- /dev/null +++ b/scripts/setup-llvm.py @@ -0,0 +1,355 @@ +#!/usr/bin/env python3 + +import argparse +import hashlib +import json +import os +import shutil +import subprocess +import sys +import tarfile +from pathlib import Path +from urllib.error import HTTPError, URLError +from urllib.request import Request, urlopen + + +PRIVATE_CLANG_FILES = [ + "Sema/CoroutineStmtBuilder.h", + "Sema/TypeLocBuilder.h", + "Sema/TreeTransform.h", +] + + +def log(message: str) -> None: + print(f"[setup-llvm] {message}", flush=True) + + +def read_manifest(path: Path) -> list[dict]: + with path.open("r", encoding="utf-8") as handle: + return json.load(handle) + + +def detect_platform() -> str: + plat = sys.platform + if plat.startswith("win"): + return "Windows" + if plat == "darwin": + return "macosx" + if plat.startswith("linux"): + return "Linux" + raise RuntimeError(f"Unsupported platform: {plat}") + + +def pick_artifact( + manifest: list[dict], version: str, build_type: str, is_lto: bool, platform: str +) -> dict: + base_version = version.split("+", 1)[0] + for entry in manifest: + if entry.get("version") != version: + continue + if entry.get("platform") != platform.lower(): + continue + if entry.get("build_type") != build_type: + continue + if bool(entry.get("lto")) != is_lto: + continue + return entry + raise RuntimeError( + f"No matching LLVM artifact in manifest for version={base_version}, platform={platform}, " + f"build_type={build_type}, lto={is_lto}" + ) + + +def sha256sum(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + for chunk in iter(lambda: handle.read(1024 * 1024), b""): + digest.update(chunk) + return digest.hexdigest() + + +def download(url: str, dest: Path, token: str | None) -> None: + log(f"Start download: {url} -> {dest}") + dest.parent.mkdir(parents=True, exist_ok=True) + headers = {"User-Agent": "clice-setup-llvm"} + if token: + headers["Authorization"] = f"Bearer {token}" + request = Request(url, headers=headers) + try: + with urlopen(request) as response, dest.open("wb") as handle: + total_bytes = response.length + if total_bytes is None: + header_len = response.getheader("Content-Length") + if header_len and header_len.isdigit(): + total_bytes = int(header_len) + downloaded = 0 + next_percent = 10 + next_unknown_mark = 10 * 1024 * 1024 # 10MB steps when size is unknown + while True: + chunk = response.read(1024 * 512) + if not chunk: + break + handle.write(chunk) + downloaded += len(chunk) + if total_bytes: + percent = int(downloaded * 100 / total_bytes) + while percent >= next_percent and next_percent <= 100: + log( + f"Download progress: {next_percent}% " + f"({downloaded / 1024 / 1024:.1f}MB/" + f"{total_bytes / 1024 / 1024:.1f}MB)" + ) + next_percent += 10 + else: + if downloaded >= next_unknown_mark: + log( + f"Downloaded {downloaded / 1024 / 1024:.1f}MB (size unknown)" + ) + next_unknown_mark += 10 * 1024 * 1024 + if total_bytes and next_percent <= 100: + log("Download progress: 100% (size verified by server)") + log(f"Finished download: {dest} ({downloaded / 1024 / 1024:.1f}MB)") + except HTTPError as err: + raise RuntimeError(f"HTTP error {err.code} while downloading {url}") from err + except URLError as err: + raise RuntimeError(f"Failed to download {url}: {err.reason}") from err + + +def ensure_download( + url: str, dest: Path, expected_sha256: str, token: str | None +) -> None: + if dest.exists(): + current = sha256sum(dest) + if current == expected_sha256: + return + dest.unlink() + download(url, dest, token) + current = sha256sum(dest) + if current != expected_sha256: + dest.unlink(missing_ok=True) + raise RuntimeError( + f"SHA256 mismatch for {dest.name}: expected {expected_sha256}, got {current}" + ) + + +def extract_archive(archive: Path, dest_dir: Path) -> None: + log(f"Extracting {archive.name} to {dest_dir}") + dest_dir.mkdir(parents=True, exist_ok=True) + name = archive.name.lower() + if name.endswith(".tar.xz") or name.endswith(".tar.gz") or name.endswith(".tar"): + with tarfile.open(archive, "r:*") as tar: + tar.extractall(path=dest_dir) + log("Extraction complete") + return + raise RuntimeError(f"Unsupported archive format: {archive}") + + +def flatten_install_dir(dest_dir: Path) -> None: + # Some archives add an extra root directory (llvm-install, build-install, etc.). + for name in ("llvm-install", "build-install"): + nested = dest_dir / name + if not nested.is_dir(): + continue + log(f"Flattening nested install directory: {nested}") + for entry in nested.iterdir(): + target = dest_dir / entry.name + if target.exists(): + raise RuntimeError( + f"Cannot flatten {nested}: target already exists: {target}" + ) + shutil.move(str(entry), str(target)) + nested.rmdir() + break + + +def parse_version_tuple(text: str) -> tuple[int, ...]: + digits = [] + current = "" + for ch in text: + if ch.isdigit(): + current += ch + else: + if current: + digits.append(int(current)) + current = "" + if ch in {".", "-"}: + continue + if current: + digits.append(int(current)) + return tuple(digits) + + +def system_llvm_ok(required_version: str, build_type: str) -> Path | None: + if build_type.lower().startswith("debug"): + return None + llvm_config = shutil.which("llvm-config") + if not llvm_config: + return None + try: + version = subprocess.check_output([llvm_config, "--version"], text=True).strip() + prefix = subprocess.check_output([llvm_config, "--prefix"], text=True).strip() + except (subprocess.CalledProcessError, OSError): + return None + required = parse_version_tuple(required_version.split("+", 1)[0]) + found = parse_version_tuple(version) + if not found or found < required: + return None + return Path(prefix) + + +def github_api(url: str, token: str | None) -> dict: + headers = { + "Accept": "application/vnd.github+json", + "User-Agent": "clice-setup-llvm", + } + if token: + headers["Authorization"] = f"Bearer {token}" + request = Request(url, headers=headers) + with urlopen(request) as response: + return json.load(response) + + +def lookup_llvm_commit(version: str, token: str | None) -> str | None: + tag_version = version.split("+", 1)[0] + tag = f"llvmorg-{tag_version}" + ref_url = f"https://api.github.com/repos/llvm/llvm-project/git/ref/tags/{tag}" + try: + ref = github_api(ref_url, token) + except Exception: + return None + obj = ref.get("object") or {} + obj_type = obj.get("type") + obj_sha = obj.get("sha") + if obj_type == "commit": + return obj_sha + if obj_type == "tag" and obj_sha: + tag_url = f"https://api.github.com/repos/llvm/llvm-project/git/tags/{obj_sha}" + try: + tag_info = github_api(tag_url, token) + except Exception: + return None + return tag_info.get("object", {}).get("sha") or tag_info.get("sha") + return None + + +def ensure_private_headers( + install_path: Path, work_dir: Path, version: str, token: str | None, offline: bool +) -> None: + missing = [] + for rel in PRIVATE_CLANG_FILES: + if (install_path / "include" / "clang" / rel).exists(): + continue + if (work_dir / "include" / "clang" / rel).exists(): + continue + missing.append(rel) + if not missing or offline: + return + commit = lookup_llvm_commit(version, token) + if not commit: + return + for rel in missing: + dest = work_dir / "include" / "clang" / rel + dest.parent.mkdir(parents=True, exist_ok=True) + url = f"https://raw.githubusercontent.com/llvm/llvm-project/{commit}/clang/lib/{rel}" + log(f"Fetching private header: {url}") + download(url, dest, token) + + +def main() -> None: + parser = argparse.ArgumentParser(description="Setup LLVM dependencies for CMake") + parser.add_argument("--version", required=True) + parser.add_argument("--build-type", required=True) + parser.add_argument("--binary-dir", required=True) + parser.add_argument("--manifest", required=True) + parser.add_argument("--install-path") + parser.add_argument("--enable-lto", action="store_true") + parser.add_argument("--offline", action="store_true") + parser.add_argument("--output", required=True) + args = parser.parse_args() + + log( + "Args: " + f"version={args.version}, build_type={args.build_type}, " + f"binary_dir={args.binary_dir}, install_path={args.install_path or '(auto)'}, " + f"enable_lto={args.enable_lto}, offline={args.offline}" + ) + token = os.environ.get("GH_TOKEN") or os.environ.get("GITHUB_TOKEN") + build_type = args.build_type + platform_name = detect_platform() + log(f"Platform detected: {platform_name}, normalized build type: {build_type}") + manifest = read_manifest(Path(args.manifest)) + + binary_dir = Path(args.binary_dir).resolve() + install_root = binary_dir / ".llvm" + + install_path: Path | None = None + needs_install = False + if args.install_path: + candidate = Path(args.install_path) + if candidate.exists(): + log(f"Using provided LLVM install at {candidate}") + else: + log( + f"Provided LLVM install path does not exist; will install to {candidate}" + ) + needs_install = True + install_path = candidate + else: + detected = system_llvm_ok(args.version, build_type) + if detected: + log(f"Found suitable system LLVM at {detected}") + install_path = detected + + artifact = None + if install_path is None: + needs_install = True + artifact = pick_artifact( + manifest, args.version, build_type, args.enable_lto, platform_name + ) + log(f"Selected artifact: {artifact.get('filename')} for download") + filename = artifact["filename"] + url_version = args.version.replace("+", "%2B") + url = f"https://github.com/clice-io/clice-llvm/releases/download/{url_version}/{filename}" + download_path = binary_dir / filename + ensure_download(url, download_path, artifact["sha256"], token) + extract_archive(download_path, install_root) + flatten_install_dir(install_root) + install_path = install_root + elif needs_install: + artifact = pick_artifact( + manifest, args.version, build_type, args.enable_lto, platform_name + ) + log(f"Selected artifact: {artifact.get('filename')} for download") + filename = artifact["filename"] + url_version = args.version.replace("+", "%2B") + url = f"https://github.com/clice-io/clice-llvm/releases/download/{url_version}/{filename}" + download_path = binary_dir / filename + ensure_download(url, download_path, artifact["sha256"], token) + target_dir = install_path.resolve() + extract_archive(download_path, target_dir) + flatten_install_dir(target_dir) + install_path = target_dir + else: + install_path = install_path.resolve() + log(f"Using existing LLVM install at {install_path}") + + cmake_dir = install_path / "lib" / "cmake" / "llvm" + ensure_private_headers(install_path, binary_dir, args.version, token, args.offline) + + output = Path(args.output) + output.parent.mkdir(parents=True, exist_ok=True) + with output.open("w", encoding="utf-8") as handle: + json.dump( + { + "install_path": str(install_path), + "cmake_dir": str(cmake_dir), + "artifact": artifact or {}, + }, + handle, + indent=2, + ) + handle.write("\n") + + +if __name__ == "__main__": + main() diff --git a/scripts/upload-llvm.py b/scripts/upload-llvm.py new file mode 100644 index 000000000..6d9db0f40 --- /dev/null +++ b/scripts/upload-llvm.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 + +import hashlib +import json +import os +import subprocess +import sys +from pathlib import Path + + +def sha256sum(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + for chunk in iter(lambda: handle.read(1024 * 1024), b""): + digest.update(chunk) + return digest.hexdigest() + + +def parse_platform(name: str) -> str: + lowered = name.lower() + if "windows" in lowered: + return "windows" + if "linux" in lowered: + return "linux" + if "macos" in lowered: + return "macosx" + raise ValueError(f"Unable to determine platform from filename: {name}") + + +def parse_build_type(name: str) -> str: + lowered = name.lower() + if "debug" in lowered: + return "Debug" + return "RelWithDebInfo" + + +def build_metadata_entry(path: Path, version: str) -> dict: + filename = path.name + return { + "version": version, + "filename": filename, + "sha256": sha256sum(path), + "lto": "-lto" in filename.lower(), + "asan": "-asan" in filename.lower(), + "platform": parse_platform(filename), + "build_type": parse_build_type(filename), + } + + +def main() -> None: + if len(sys.argv) != 4: + print( + "Usage: upload-llvm.py ", file=sys.stderr + ) + sys.exit(1) + + tag, target_repo, workflow_id = sys.argv[1:] + artifacts_dir = Path("artifacts") + + if not artifacts_dir.is_dir(): + print(f"Artifacts directory not found: {artifacts_dir}", file=sys.stderr) + sys.exit(1) + + artifact_files = sorted( + p + for p in artifacts_dir.rglob("*") + if p.is_file() and p.suffix.lower() != ".json" + ) + + if not artifact_files: + print("No artifacts found to upload.", file=sys.stderr) + sys.exit(1) + + version_without_prefix = tag.lstrip("vV") + metadata = [ + build_metadata_entry(path, version_without_prefix) for path in artifact_files + ] + + json_path = artifacts_dir / "llvm-manifest.json" + with json_path.open("w", encoding="utf-8") as handle: + json.dump(metadata, handle, indent=2) + handle.write("\n") + + assets = [str(path) for path in artifact_files] + assets.append(str(json_path)) + + env = os.environ.copy() + + print(f"Checking for existing release {tag} in {target_repo}...") + view_result = subprocess.run( + ["gh", "release", "view", tag, "--repo", target_repo], + env=env, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + + if view_result.returncode == 0: + print(f"Deleting existing release {tag} in {target_repo}...") + subprocess.run( + ["gh", "release", "delete", tag, "--repo", target_repo, "-y"], + env=env, + check=True, + ) + + print(f"Creating release {tag} in {target_repo} with {len(assets)} assets...") + # fmt: off + args = [ + "gh", "release", "create", tag, *assets, + "--repo", target_repo, + "--title", tag, + "--notes", f"Artifacts build from workflow run https://github.com/clice-io/clice/actions/runs/{workflow_id}", + "--latest", + ] + # fmt: on + subprocess.run(args, env=env, check=True) + + +if __name__ == "__main__": + main()