diff --git a/.bazelignore b/.bazelignore new file mode 100644 index 000000000..bc1620e4c --- /dev/null +++ b/.bazelignore @@ -0,0 +1,5 @@ +.cache +.venv +docs/.site +public +target diff --git a/.bazeliskrc b/.bazeliskrc new file mode 100644 index 000000000..b2fd13d58 --- /dev/null +++ b/.bazeliskrc @@ -0,0 +1,2 @@ +# Bazelisk runs `bazel/bazel` in place of the Bazel release it fetched. +BAZELISK_WRAPPER_DIRECTORY=bazel diff --git a/.bazelrc b/.bazelrc new file mode 100644 index 000000000..f000c3531 --- /dev/null +++ b/.bazelrc @@ -0,0 +1,5 @@ +# The output root is placed in `.cache` (see `bazel/shim.py`), and the repo contents cache cannot live in-tree. +common --repo_contents_cache= + +# Keeps the convenience symlinks out of the repository root. +build --symlink_prefix=.cache/bazel- diff --git a/.bazelversion b/.bazelversion new file mode 100644 index 000000000..47da986f8 --- /dev/null +++ b/.bazelversion @@ -0,0 +1 @@ +9.1.0 diff --git a/.cargo/mutants.toml b/.cargo/mutants.toml index 3cea57009..5316c05fa 100644 --- a/.cargo/mutants.toml +++ b/.cargo/mutants.toml @@ -5,7 +5,7 @@ additional_cargo_test_args = [ "fail-fast", ] build_timeout_multiplier = 5.0 -exclude_globs = ["pkgs/dev/**", "pkgs/pow/**"] +exclude_globs = ["meta/dev/**", "pkgs/pow/**"] features = ["full"] gitignore = true profile = "mutants" diff --git a/.editorconfig b/.editorconfig index 4bc07da6b..d935d28e5 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,8 +11,14 @@ trim_trailing_whitespace = true [*.Dockerfile] indent_size = 4 +[*.bat] +end_of_line = crlf + [*.md] trim_trailing_whitespace = false -[Justfile] +[{Justfile,*.just}] +indent_size = 4 + +[{*.bzl,BUILD.bazel,MODULE.bazel}] indent_size = 4 diff --git a/.gitattributes b/.gitattributes index bd37aec13..4bc64229b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,6 @@ * text=auto eol=lf -fuzz/*/corpora/** binary linguist-generated +*.bat text eol=crlf +*.lock linguist-generated +*.lock.yml linguist-generated +*.rs diff=rust +fuzz/*/corpora/** binary linguist-generated diff --git a/.github/workflows/build_bazel.yml b/.github/workflows/build_bazel.yml new file mode 100644 index 000000000..af6ba0260 --- /dev/null +++ b/.github/workflows/build_bazel.yml @@ -0,0 +1,55 @@ +name: Build with Bazel + +on: + push: + branches: [develop] + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + bazel: + strategy: + fail-fast: false + matrix: + os: + - ubuntu-24.04 + - ubuntu-24.04-arm + - macos-latest + - macos-15-intel + - windows-latest + + name: ${{ matrix.os }} (bazel) + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 1 + + - name: Install just + uses: taiki-e/install-action@v2 + with: + tool: just + + # Windows images ship Bazel beside Bazelisk, and either may come first. + - name: Uninstall Bazel + if: runner.os == 'Windows' + shell: pwsh + run: | + if (choco list bazel --exact --limit-output) { + choco uninstall bazel --yes --no-progress + } + + - name: Build every target + run: just zbuild + + - name: Check the output root + shell: bash + run: test -d .cache/bazel/install diff --git a/.github/workflows/build_cross.yml b/.github/workflows/build_cross.yml index da0de8475..22975fac6 100644 --- a/.github/workflows/build_cross.yml +++ b/.github/workflows/build_cross.yml @@ -41,7 +41,7 @@ jobs: run: nix develop ./contrib/nix#dev --command true - name: Validate toolchains - run: nix develop ./contrib/nix#dev --command ./contrib/nix/smoke_test.sh + run: nix develop ./contrib/nix#dev --command ./contrib/smoke_test.py build: name: ${{ matrix.target }} diff --git a/Cargo.lock b/Cargo.lock index 49c4205bc..4e75755fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -424,6 +424,10 @@ dependencies = [ "xxhash-rust", ] +[[package]] +name = "dash-meta-bazel" +version = "0.0.0" + [[package]] name = "dash-num" version = "0.2.0-beta" diff --git a/Cargo.toml b/Cargo.toml index 971dcab8c..bef3fdf20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] members = [ - "pkgs/dev", + "meta/bazel", + "meta/dev", "pkgs/num", "pkgs/params", "pkgs/p2p_core", diff --git a/Justfile b/Justfile index 686da55b1..4112afd5f 100644 --- a/Justfile +++ b/Justfile @@ -8,6 +8,8 @@ export RUSTDOCFLAGS := "-D warnings" mod fuzz "fuzz/mod.just" +import "bazel/mod.just" + each := "cargo hack --workspace --exclude-features default --each-feature" powerset := "cargo hack --workspace --exclude-features default --feature-powerset" @@ -51,3 +53,6 @@ test: {{ each }} test --doc cargo doc --workspace --no-deps --features full {{ each }} test --benches + +zbuild *flags: + bazel build {{ flags }} //... diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 000000000..7df18876a --- /dev/null +++ b/MODULE.bazel @@ -0,0 +1,4 @@ +module( + name = "dash_base_sdk", + version = "0.0.0", +) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock new file mode 100644 index 000000000..23f8dcfbd --- /dev/null +++ b/MODULE.bazel.lock @@ -0,0 +1,192 @@ +{ + "lockFileVersion": 26, + "registryFileHashes": { + "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", + "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", + "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", + "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1", + "https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/MODULE.bazel": "51f2312901470cdab0dbdf3b88c40cd21c62a7ed58a3de45b365ddc5b11bcab2", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/source.json": "cea3901d7e299da7320700abbaafe57a65d039f10d0d7ea601c4a66938ea4b0c", + "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896", + "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", + "https://bcr.bazel.build/modules/apple_support/1.21.0/MODULE.bazel": "ac1824ed5edf17dee2fdd4927ada30c9f8c3b520be1b5fd02a5da15bc10bff3e", + "https://bcr.bazel.build/modules/apple_support/1.21.1/MODULE.bazel": "5809fa3efab15d1f3c3c635af6974044bac8a4919c62238cce06acee8a8c11f1", + "https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4", + "https://bcr.bazel.build/modules/apple_support/1.24.2/source.json": "2c22c9827093250406c5568da6c54e6fdf0ef06238def3d99c71b12feb057a8d", + "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", + "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", + "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", + "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", + "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", + "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", + "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", + "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.23.0/MODULE.bazel": "fd1ac84bc4e97a5a0816b7fd7d4d4f6d837b0047cf4cbd81652d616af3a6591a", + "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", + "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", + "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", + "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", + "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6", + "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.42.1/MODULE.bazel": "275a59b5406ff18c01739860aa70ad7ccb3cfb474579411decca11c93b951080", + "https://bcr.bazel.build/modules/bazel_features/1.42.1/source.json": "fcd4396b2df85f64f2b3bb436ad870793ecf39180f1d796f913cc9276d355309", + "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", + "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", + "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", + "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", + "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", + "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb", + "https://bcr.bazel.build/modules/buildozer/8.5.1/MODULE.bazel": "a35d9561b3fc5b18797c330793e99e3b834a473d5fbd3d7d7634aafc9bdb6f8f", + "https://bcr.bazel.build/modules/buildozer/8.5.1/source.json": "e3386e6ff4529f2442800dee47ad28d3e6487f36a1f75ae39ae56c70f0cd2fbd", + "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", + "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", + "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", + "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", + "https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46", + "https://bcr.bazel.build/modules/googletest/1.17.0/source.json": "38e4454b25fc30f15439c0378e57909ab1fd0a443158aa35aec685da727cd713", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000", + "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/source.json": "f448c6e8963fdfa7eb831457df83ad63d3d6355018f6574fb017e8169deb43a9", + "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", + "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", + "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", + "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", + "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", + "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", + "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", + "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580", + "https://bcr.bazel.build/modules/platforms/1.0.0/source.json": "f4ff1fd412e0246fd38c82328eb209130ead81d62dcd5a9e40910f867f733d96", + "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", + "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", + "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", + "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", + "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d", + "https://bcr.bazel.build/modules/protobuf/33.4/MODULE.bazel": "114775b816b38b6d0ca620450d6b02550c60ceedfdc8d9a229833b34a223dc42", + "https://bcr.bazel.build/modules/protobuf/33.4/source.json": "555f8686b4c7d6b5ba731fbea13bf656b4bfd9a7ff629c1d9d3f6e1d6155de79", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680", + "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/source.json": "2ff292be6ef3340325ce8a045ecc326e92cbfab47c7cbab4bd85d28971b97ac4", + "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", + "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", + "https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e", + "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/MODULE.bazel": "76e10fd4a48038d3fc7c5dc6e63b7063bbf5304a2e3bd42edda6ec660eebea68", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/source.json": "8ee81e1708756f81b343a5eb2b2f0b953f1d25c4ab3d4a68dc02754872e80715", + "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", + "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", + "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", + "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", + "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", + "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", + "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", + "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", + "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", + "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", + "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", + "https://bcr.bazel.build/modules/rules_cc/0.1.2/MODULE.bazel": "557ddc3a96858ec0d465a87c0a931054d7dcfd6583af2c7ed3baf494407fd8d0", + "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", + "https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c", + "https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37", + "https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84", + "https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07", + "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", + "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", + "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", + "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", + "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", + "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", + "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", + "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", + "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", + "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", + "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2", + "https://bcr.bazel.build/modules/rules_java/9.1.0/MODULE.bazel": "ee63f27e36a3fada80342869361182f120a9819c74320e8e65b1e04ba0cd7a9d", + "https://bcr.bazel.build/modules/rules_java/9.1.0/source.json": "da589573c1dee2c9ac4a568b301269a2e8191110ff0345c1a959fa7ea6c4dfd6", + "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", + "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", + "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", + "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd", + "https://bcr.bazel.build/modules/rules_jvm_external/6.7/source.json": "5426f412d0a7fc6b611643376c7e4a82dec991491b9ce5cb1cfdd25fe2e92be4", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5", + "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", + "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", + "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", + "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a", + "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", + "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", + "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", + "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e", + "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", + "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", + "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", + "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", + "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", + "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937", + "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13", + "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6", + "https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/MODULE.bazel": "d01f995ecd137abf30238ad9ce97f8fc3ac57289c8b24bd0bf53324d937a14f8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/source.json": "028a084b65dcf8f4dc4f82f8778dbe65df133f234b316828a82e060d81bdce32", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", + "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/source.json": "20ec05cd5e592055e214b2da8ccb283c7f2a421ea0dc2acbf1aa792e11c03d0c", + "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca", + "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046", + "https://bcr.bazel.build/modules/rules_swift/2.4.0/MODULE.bazel": "1639617eb1ede28d774d967a738b4a68b0accb40650beadb57c21846beab5efd", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/MODULE.bazel": "72c8f5cf9d26427cee6c76c8e3853eb46ce6b0412a081b2b6db6e8ad56267400", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/source.json": "e85761f3098a6faf40b8187695e3de6d97944e98abd0d8ce579cb2daf6319a66", + "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", + "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", + "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", + "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", + "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/MODULE.bazel": "75aab2373a4bbe2a1260b9bf2a1ebbdbf872d3bd36f80bff058dccd82e89422f", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/source.json": "5fba48bbe0ba48761f9e9f75f92876cafb5d07c0ce059cc7a8027416de94a05b", + "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", + "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806", + "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" + }, + "selectedYankedVersions": {}, + "moduleExtensions": {}, + "facts": {} +} diff --git a/bazel/bazel b/bazel/bazel new file mode 120000 index 000000000..3f3a0b1ea --- /dev/null +++ b/bazel/bazel @@ -0,0 +1 @@ +shim.py \ No newline at end of file diff --git a/bazel/bazel.bat b/bazel/bazel.bat new file mode 100644 index 000000000..f0750acf7 --- /dev/null +++ b/bazel/bazel.bat @@ -0,0 +1,3 @@ +@echo off +python "%~dp0shim.py" %* +exit /b %ERRORLEVEL% diff --git a/bazel/mod.just b/bazel/mod.just new file mode 100644 index 000000000..36e939e23 --- /dev/null +++ b/bazel/mod.just @@ -0,0 +1,4 @@ +# Bazel settings shared by the root and crate justfiles. + +# Read by bazelisk, which otherwise downloads Bazel into the user's cache. +export BAZELISK_HOME := justfile_directory() + "/.cache/bazelisk" diff --git a/bazel/shim.py b/bazel/shim.py new file mode 100755 index 000000000..8c92f9197 --- /dev/null +++ b/bazel/shim.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +# coding: latin-1 + +# +# Copyright (c) 2026-present, The Dash Core developers +# SPDX-License-Identifier: MIT +# See the accompanying file LICENSE or https://opensource.org/license/MIT +# + +"""Shim that runs Bazel with its output root in `.cache/bazel`.""" + +from __future__ import annotations + +import os +import subprocess +import sys +from pathlib import Path + +OUTPUT_ROOT = Path(__file__).resolve().parents[1] / ".cache" / "bazel" + + +def main() -> int: + real = os.environ.get("BAZEL_REAL") + if not real: + print("bazel: run bazelisk, which sets BAZEL_REAL", file=sys.stderr) + return 2 + argv = [real, f"--output_user_root={OUTPUT_ROOT}", *sys.argv[1:]] + if os.name == "nt": + return subprocess.run(argv, check=False).returncode # noqa: S603 + os.execv(real, argv) # noqa: S606 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/contrib/README.md b/contrib/README.md index 1e43c618f..33a222606 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -100,6 +100,33 @@ cargo install --locked cargo-deny sudo dnf install -y cargo-deny git just nodejs24 ``` +## Bazel + +> [!NOTE] +> Bazel isn't installed directly. Instead, [Bazelisk](https://github.com/bazelbuild/bazelisk) is installed as `bazel`, +> which uses the version pinned by [`.bazelversion`](../.bazelversion). It is accompanied by +> [buildifier](https://github.com/bazelbuild/buildtools), used to lint Starlark (the DSL used by Bazel) files. + + +### macOS (with [Homebrew](https://brew.sh/)) + +> [!WARNING] +> `bazelisk` conflicts with the `bazel` formula. If the latter has been installed, it must be uninstalled first. + +```bash +brew install bazelisk buildifier +``` + + +### Linux/WSL + +Neither Bazelisk nor buildifier are available in official Debian or Fedora repositories. Both are published to the npm +registry and can be installed with the `npm` CLI tool (a part of Node.js, an existing dependency). + +```bash +npm install -g @bazel/bazelisk @bazel/buildifier +``` + diff --git a/contrib/docker/docker-compose.yml b/contrib/docker/docker-compose.yml index 50bd9b970..544941b2e 100644 --- a/contrib/docker/docker-compose.yml +++ b/contrib/docker/docker-compose.yml @@ -34,6 +34,10 @@ services: nix_daemon: condition: "service_healthy" init: true + # `fhs-run` uses bubblewrap, which needs user namespaces and unmasked procfs generally denied by Docker by default. + security_opt: + - "seccomp=unconfined" + - "systempaths=unconfined" user: "${HOST_UID:-1000}:${HOST_GID:-1000}" environment: NIX_REMOTE: "daemon" diff --git a/contrib/docker/entrypoint b/contrib/docker/entrypoint index bba2dbcdf..ce8cd1998 100755 --- a/contrib/docker/entrypoint +++ b/contrib/docker/entrypoint @@ -26,7 +26,7 @@ if ! git rev-parse --git-dir > /dev/null 2>&1; then fi if (( $# > 0 )); then - exec nix develop ./contrib/nix#dev --command "$@" + exec nix develop ./contrib/nix#dev --command fhs-run "$@" else - exec nix develop ./contrib/nix#dev + exec nix develop ./contrib/nix#dev --command fhs-run bash fi diff --git a/contrib/nix/flake.lock b/contrib/nix/flake.lock index 13cdec4d7..fc49ffcff 100644 --- a/contrib/nix/flake.lock +++ b/contrib/nix/flake.lock @@ -16,6 +16,22 @@ "type": "github" } }, + "nixpkgs-llvm": { + "locked": { + "lastModified": 1745533402, + "narHash": "sha256-gDcMJdnBJg7ncP+eqENwH9pOW0azcCOW5y50N+jKdL8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3e2cf88148e732abc1d259286123e06a9d8c964a", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3e2cf88148e732abc1d259286123e06a9d8c964a", + "type": "github" + } + }, "nixpkgs-unstable": { "locked": { "lastModified": 1789632929, @@ -81,6 +97,7 @@ "root": { "inputs": { "nixpkgs": "nixpkgs", + "nixpkgs-llvm": "nixpkgs-llvm", "nixpkgs-unstable": "nixpkgs-unstable", "pyproject-build-systems": "pyproject-build-systems", "pyproject-nix": "pyproject-nix", diff --git a/contrib/nix/flake.nix b/contrib/nix/flake.nix index 7d3b27de3..911c1ba43 100644 --- a/contrib/nix/flake.nix +++ b/contrib/nix/flake.nix @@ -8,6 +8,8 @@ nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + nixpkgs-llvm.url = "github:NixOS/nixpkgs/3e2cf88148e732abc1d259286123e06a9d8c964a"; + pyproject-build-systems = { url = "github:pyproject-nix/build-system-pkgs"; inputs.nixpkgs.follows = "nixpkgs"; @@ -35,6 +37,7 @@ outputs = { nixpkgs, + nixpkgs-llvm, nixpkgs-unstable, rust-overlay, ... @@ -63,18 +66,24 @@ inherit system; config.allowUnfree = true; }; + llvm = (import nixpkgs-llvm { inherit system; }).llvmPackages_20; } ); in { devShells = eachSystem ( - { pkgs, unstable }: + { + pkgs, + unstable, + llvm, + }: let ctx = import ./shell/common.nix { inherit pkgs lib inputs + llvm unstable ; root = ../..; diff --git a/contrib/nix/mods/bazel.nix b/contrib/nix/mods/bazel.nix new file mode 100644 index 000000000..f6761d9db --- /dev/null +++ b/contrib/nix/mods/bazel.nix @@ -0,0 +1,23 @@ +# Bazel through bazelisk, with buildifier. + +{ pkgs }: + +let + # nixpkgs builds Bazel from source, whose lockfiles differ from those of the + # release binaries. Bazelisk fetches the release hosts without Nix run too. + bazelisk = pkgs.writeShellScriptBin "bazel" '' + exec ${pkgs.bazelisk}/bin/bazelisk "$@" + ''; +in +{ + packages = [ + bazelisk + pkgs.buildifier + ]; + + shellHook = '' + if root=$(git rev-parse --show-toplevel 2> /dev/null); then + export BAZELISK_HOME="$root/.cache/bazelisk" + fi + ''; +} diff --git a/contrib/nix/mods/compiler_rt.nix b/contrib/nix/mods/compiler_rt.nix new file mode 100644 index 000000000..69131f9cb --- /dev/null +++ b/contrib/nix/mods/compiler_rt.nix @@ -0,0 +1,54 @@ +# The clang resource directory drivers compile and link with + +{ pkgs, llvm }: + +let + macos = pkgs.stdenvNoCC.mkDerivation { + pname = "macos-compiler-rt"; + version = "20.1.3"; + + src = pkgs.fetchurl { + url = "https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-64-20.1.3-hc6f8467_0.conda"; + hash = "sha256-DNAy1cTVF7Toej8nY599YWBlvrtLhwtXbb4+LW2Lyzc="; + }; + + nativeBuildInputs = [ + pkgs.unzip + pkgs.zstd + ]; + + # A `.conda` package is a zip holding the payload as a zstd tarball. + unpackPhase = '' + runHook preUnpack + unzip -q "$src" 'pkg-*.tar.zst' + mkdir payload + tar --zstd -xf pkg-*.tar.zst -C payload + runHook postUnpack + ''; + + dontConfigure = true; + dontBuild = true; + + installPhase = '' + runHook preInstall + mkdir -p "$out" + cp -a payload/lib "$out/" + runHook postInstall + ''; + + # The fixup phase would treat target Mach-O archives as host binaries. + dontFixup = true; + + meta.license = llvm.compiler-rt.meta.license; + }; +in +pkgs.symlinkJoin { + name = "clang-resource-dir"; + paths = [ + # Supplies clang's builtin headers. + llvm.clang-unwrapped.lib + # nixpkgs builds compiler-rt for the host alone, while conda-forge's + # universal archives serve macOS targets from any host. + macos + ]; +} diff --git a/contrib/nix/mods/cxx.nix b/contrib/nix/mods/cxx.nix index 66b78482d..b65278ca3 100644 --- a/contrib/nix/mods/cxx.nix +++ b/contrib/nix/mods/cxx.nix @@ -3,15 +3,14 @@ { pkgs, lib, + llvm, xcodeSdk ? null, }: let - llvm = pkgs.llvmPackages_20; - # clang -print-resource-dir names the main output, but the builtin headers are # split into .lib, so the flag has to be passed explicitly. - resourceDir = "${llvm.clang-unwrapped.lib}/lib/clang/20"; + resourceDir = "${import ./compiler_rt.nix { inherit pkgs llvm; }}/lib/clang/20"; # --ld-path names lld directly, where -fuse-ld=lld would find the nixpkgs # bintools wrapper on PATH. Mach-O needs ld64. @@ -85,7 +84,7 @@ let darwinFlags = _: [ - "-isysroot ${xcodeSdk}" + "-isysroot ${xcodeSdk.sysroot}" "-nostdlibinc" "-iwithsysroot/usr/include" "-iframeworkwithsysroot/System/Library/Frameworks" @@ -208,7 +207,7 @@ in # Adding clang to packages would not displace the cc-wrapper the default # stdenv puts on PATH, so the shell is built against this stdenv instead. compiler = { - stdenv = llvm.stdenv; + stdenv = pkgs.overrideCC pkgs.stdenv llvm.clang; packages = [ llvm.bintools ]; }; @@ -225,8 +224,9 @@ in # both are set shell-wide rather than per target. A native macOS build # has to resolve against the same pinned SDK as a cross target. darwin = lib.optionalAttrs (lib.any (t: (defFor t).kind == "darwin") targets) { + MACOS_SDK_VERSION = xcodeSdk.sdkVersion; MACOSX_DEPLOYMENT_TARGET = xcodeSdk.minVersion; - SDKROOT = "${xcodeSdk}"; + SDKROOT = xcodeSdk.sysroot; }; in { diff --git a/contrib/nix/mods/fhs.nix b/contrib/nix/mods/fhs.nix new file mode 100644 index 000000000..edb912585 --- /dev/null +++ b/contrib/nix/mods/fhs.nix @@ -0,0 +1,33 @@ +# An FHS layout like that of standard (non-NixOS) Linux distributions + +{ pkgs, lib }: + +let + run = pkgs.buildFHSEnv { + name = "fhs-run"; + targetPkgs = p: [ + p.bash + p.bzip2 + p.coreutils + p.diffutils + p.file + p.findutils + p.gawk + p.gnugrep + p.gnused + p.gnutar + p.gzip + # The C and C++ runtimes a binary built against glibc expects. + p.stdenv.cc.cc.lib + p.unzip + p.which + p.xz + p.zlib + p.zstd + ]; + runScript = "env"; + }; +in +{ + packages = lib.optional pkgs.stdenv.hostPlatform.isLinux run; +} diff --git a/contrib/nix/mods/python.nix b/contrib/nix/mods/python.nix index 5bd5ae253..d670eb05f 100644 --- a/contrib/nix/mods/python.nix +++ b/contrib/nix/mods/python.nix @@ -25,6 +25,12 @@ let (old.nativeBuildInputs or [ ]) ++ final.resolveBuildSystem { setuptools = [ ]; }; }); + # `lief` links the C++ runtime, `autoPatchelfHook` has to find it for Linux. + lief = prev.lief.overrideAttrs (old: { + buildInputs = + (old.buildInputs or [ ]) ++ lib.optional pkgs.stdenv.hostPlatform.isLinux pkgs.stdenv.cc.cc.lib; + }); + # Narrow rebuild triggers to relevant files to avoid pulling in the whole # source tree and thrashing the cache for it. dash-base-sdk = prev.dash-base-sdk.overrideAttrs (_: { diff --git a/contrib/nix/mods/xcode_sdk.nix b/contrib/nix/mods/xcode_sdk.nix index 695e64270..db4e0f314 100644 --- a/contrib/nix/mods/xcode_sdk.nix +++ b/contrib/nix/mods/xcode_sdk.nix @@ -3,40 +3,127 @@ { pkgs }: let + inherit (pkgs) lib; + # Xcode release and build ID version = "26.1.1-17B100"; -in -pkgs.stdenvNoCC.mkDerivation { - inherit version; + sdkVersion = "26.1"; - # Archive contains stubs and headers, nothing to configure, build or fix - dontBuild = true; - dontConfigure = true; - dontFixup = true; + platform = "Platforms/MacOSX.platform"; + sdks = "${platform}/Developer/SDKs"; + sdk = "${sdks}/MacOSX${sdkVersion}.sdk"; + + # `xcrun` finds an SDK through the plists, which the archive lacks. + plist = + entries: + pkgs.writeText "Info.plist" '' + + + + ${ + lib.concatStrings ( + lib.mapAttrsToList (key: value: " ${key}${value}\n") entries + ) + } + ''; + # clang reads the SDK version from `SDKSettings.json`. Without the file, + # binaries record the deployment target as their SDK version. + sdkSettings = pkgs.writeText "SDKSettings.json" ( + builtins.toJSON { + CanonicalName = "macosx${sdkVersion}"; + DefaultDeploymentTarget = sdkVersion; + DisplayName = "macOS ${sdkVersion}"; + IsBaseSDK = "YES"; + MaximumDeploymentTarget = "${sdkVersion}.99"; + Version = sdkVersion; + SupportedTargets.macosx = { + Archs = [ + "arm64" + "arm64e" + "x86_64" + "x86_64h" + ]; + DefaultDeploymentTarget = sdkVersion; + LLVMTargetTripleSys = "macos"; + LLVMTargetTripleVendor = "apple"; + MaximumDeploymentTarget = "${sdkVersion}.99"; + MinimumDeploymentTarget = "10.13"; + }; + } + ); +in + +pkgs.stdenvNoCC.mkDerivation (finalAttrs: { pname = "xcode-sdk"; + inherit version; + + # The archive holds a bare sysroot, so `installPhase` builds the + # DEVELOPER_DIR around it. src = pkgs.fetchurl { url = "https://bitcoincore.org/depends-sources/sdks/Xcode-${version}-extracted-SDK-with-libcxx-headers.tar"; hash = "sha256-lgD6k2RN9nTukWteLIprqNrPYxmWpl3JItADuYteo7E="; }; + dontConfigure = true; + dontBuild = true; + installPhase = '' runHook preInstall - mkdir -p $out - cp -a ./* $out/ + + mkdir -p "$out/${sdk}" "$out/Toolchains/XcodeDefault.xctoolchain" + cp -a ./* "$out/${sdk}/" + ln -s "MacOSX${sdkVersion}.sdk" "$out/${sdks}/MacOSX.sdk" + + cp ${sdkSettings} "$out/${sdk}/SDKSettings.json" + cp ${ + plist { + CanonicalName = "macosx${sdkVersion}"; + DisplayName = "macOS ${sdkVersion}"; + IsBaseSDK = "YES"; + MaximumDeploymentTarget = "${sdkVersion}.99"; + Version = sdkVersion; + } + } "$out/${sdk}/SDKSettings.plist" + cp ${ + plist { + FamilyIdentifier = "macosx"; + FamilyName = "macOS"; + Identifier = "com.apple.platform.macosx"; + Name = "macosx"; + Type = "Platform"; + Version = sdkVersion; + } + } "$out/${platform}/Info.plist" + cp ${ + plist { Identifier = "com.apple.dt.toolchain.XcodeDefault"; } + } "$out/Toolchains/XcodeDefault.xctoolchain/ToolchainInfo.plist" + + # Apple's `xcrun` accepts a DEVELOPER_DIR only if it holds `usr/bin/xcrun`. + ${lib.optionalString pkgs.stdenv.hostPlatform.isDarwin '' + mkdir -p "$out/usr/bin" + ln -s ${lib.getExe' pkgs.xcbuild "xcrun"} "$out/usr/bin/xcrun" + ''} + runHook postInstall ''; + # The fixup phase would treat target Mach-O stubs as host binaries. + dontFixup = true; + passthru = { - # Target macOS version binaries are expected to support. + # `$out` is a DEVELOPER_DIR, so the sysroot is named separately. + sysroot = "${finalAttrs.finalPackage}/${sdk}"; + inherit sdkVersion; + # The target deployment version (i.e. minimum macOS version). minVersion = "14.0"; - # ld64 version clang is told to assume, as lld reports its own. + # lld is not ld64, and clang gates linker flags on its version. linkerVersion = "711"; }; meta = { description = "macOS SDK extracted from Xcode, with libc++ headers"; - license = pkgs.lib.licenses.unfree; + license = lib.licenses.unfree; }; -} +}) diff --git a/contrib/nix/shell/ci.nix b/contrib/nix/shell/ci.nix index a881895ab..ff1219072 100644 --- a/contrib/nix/shell/ci.nix +++ b/contrib/nix/shell/ci.nix @@ -12,8 +12,10 @@ compose [ (cxx.forTargets crossTargets) (cxx.forWasm commonTargets) + mods.bazel mods.codeql mods.cxx + mods.fhs mods.nixpkgs mods.python mods.rust diff --git a/contrib/nix/shell/common.nix b/contrib/nix/shell/common.nix index d9fb98ef3..5fdc32716 100644 --- a/contrib/nix/shell/common.nix +++ b/contrib/nix/shell/common.nix @@ -4,6 +4,7 @@ pkgs, lib, inputs, + llvm, root, unstable, }: @@ -13,7 +14,7 @@ let commonTargets = [ "wasm32-unknown-unknown" ]; cxx = import ../mods/cxx.nix { - inherit pkgs lib; + inherit pkgs lib llvm; xcodeSdk = import ../mods/xcode_sdk.nix { inherit pkgs; }; }; @@ -88,8 +89,10 @@ in ; mods = lib.mapAttrs (name: m: m // { _name = name; }) { + bazel = import ../mods/bazel.nix { inherit pkgs; }; codeql = import ../mods/codeql.nix { inherit pkgs unstable; }; cxx = cxx.compiler; + fhs = import ../mods/fhs.nix { inherit pkgs lib; }; nixpkgs = import ../mods/nixpkgs.nix { inherit pkgs; }; python = import ../mods/python.nix { inherit pkgs lib; diff --git a/contrib/nix/smoke_test.sh b/contrib/nix/smoke_test.sh deleted file mode 100755 index 82173a82b..000000000 --- a/contrib/nix/smoke_test.sh +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env bash - -set -uo pipefail - -out="${1:-$(mktemp -d)}" -mkdir -p "${out}" -printf '#include \nint main(void) { puts("Hello, world!"); return 0; }\n' > "${out}/hello.c" -printf '#include \nint main() { std::cout << "Hello, world!\\n"; }\n' > "${out}/hello.cpp" -printf 'fn main() { println!("Hello, world!"); }\n' > "${out}/hello.rs" -printf 'int add(int a, int b) { return a + b; }\n' > "${out}/free.c" - -status=0 - -# `--macho` is a `llvm-objdump` flag, the GNU equivalent is unsupported. -objdump=$(command -v llvm-objdump || command -v objdump || true) - -say() { - printf ' %-26s %-4s %s\n' "$1" "$2" "$3" -} - -produced() { - local found=("${1}"*) - [[ -e "${found[0]}" ]] -} - -try() { - local name="$1" lang="$2" bin="${out}/${1}.${2}" src="${out}/${SRC:-hello}.${2}" - local want="${MACOSX_DEPLOYMENT_TARGET:-}" got kind - shift 2 - if [[ -z "$1" ]]; then - say "${name}" "${lang}" skipped - return - fi - rm -f -- "${bin}"* - if ! "$@" "${src}" -o "${bin}" || ! produced "${bin}"; then - say "${name}" "${lang}" FAILED - status=1 - return - fi - # An unreadable load command is a failure, not a reason to skip the check. - if [[ "${name}" == *-apple-darwin ]]; then - got=$("${objdump:-false}" --macho --private-headers "${bin}"* 2> /dev/null | - awk '$1 == "minos" { print $2; exit }') - if [[ -z "${want}" || "${got}" != "${want}" ]]; then - say "${name}" "${lang}" "FAILED, minos ${got:-unknown}, wanted ${want:-}" - status=1 - return - fi - fi - kind=$(file -b "${bin}"* 2> /dev/null | head -1) - say "${name}" "${lang}" "${kind:-built}" -} - -try host c "${CC:-cc}" -try host cpp "${CXX:-c++}" -try host rs rustc - -for target in \ - aarch64-apple-darwin \ - x86_64-apple-darwin \ - aarch64-unknown-linux-gnu \ - x86_64-unknown-linux-gnu \ - x86_64-pc-windows-gnu \ - wasm32-unknown-unknown; -do - cc="CC_${target//-/_}" - cxx="CXX_${target//-/_}" - driver="${!cc:-}" - rust="${driver:+rustc}" - linker="${driver}" - if [[ "${target}" == wasm32-* ]]; then - # rustc links wasm32 with its own rust-lld. - rust=rustc - linker= - SRC=free try "${target}" c "${driver}" -c - else - try "${target}" c "${driver}" - fi - try "${target}" cpp "${!cxx:-}" - try "${target}" rs "${rust}" "--target=${target}" ${linker:+"-Clinker=${linker}"} -done - -exit "${status}" diff --git a/contrib/probes/free.c b/contrib/probes/free.c new file mode 100644 index 000000000..2bca74961 --- /dev/null +++ b/contrib/probes/free.c @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: CC0-1.0 + +int add(int a, int b) +{ + return a + b; +} diff --git a/contrib/probes/hello.c b/contrib/probes/hello.c new file mode 100644 index 000000000..386fd7d41 --- /dev/null +++ b/contrib/probes/hello.c @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: CC0-1.0 + +#if defined(_WIN32) +#include +#elif defined(__APPLE__) +#include +#include +#include +#elif defined(__linux__) +#include +#include +#include +#else +#error "no system interface is known for this target" +#endif + +static const char greeting[] = "Hello, world!\n"; + +#if defined(_WIN32) +static int say(const char* text, DWORD length) +{ + HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD written = 0; + return out != INVALID_HANDLE_VALUE && WriteFile(out, text, length, &written, NULL) && written == length; +} +#elif defined(__APPLE__) +static int say(const char* text, size_t length) +{ + // Any Mach call proves the kernel headers and libSystem resolved. + if (mach_task_self() == MACH_PORT_NULL) { + return 0; + } + // Checking for a release past the deployment target calls into + // compiler-rt, which the SDK does not ship. + qos_class_t qos = QOS_CLASS_DEFAULT; + if (__builtin_available(macOS 15.0, *)) { + qos = QOS_CLASS_USER_INITIATED; + } + dispatch_queue_t queue = dispatch_get_global_queue(qos, 0); + dispatch_semaphore_t done = dispatch_semaphore_create(0); + dispatch_data_t data = dispatch_data_create(text, length, queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT); + __block int failed = 1; + dispatch_write(STDOUT_FILENO, data, queue, ^(dispatch_data_t rest, int error) { + failed = rest != NULL || error != 0; + dispatch_semaphore_signal(done); + }); + dispatch_semaphore_wait(done, DISPATCH_TIME_FOREVER); + return !failed; +} +#elif defined(__linux__) +_Static_assert(LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0), "the UAPI headers predate Linux 5.10"); + +static int say(const char* text, size_t length) +{ + return syscall(SYS_write, STDOUT_FILENO, text, length) == (long)length; +} +#endif + +int main(void) +{ + return say(greeting, sizeof(greeting) - 1) ? 0 : 1; +} diff --git a/contrib/probes/hello.cpp b/contrib/probes/hello.cpp new file mode 100644 index 000000000..e5de6c701 --- /dev/null +++ b/contrib/probes/hello.cpp @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: CC0-1.0 + +#if defined(_WIN32) +#include +#elif defined(__APPLE__) +#include +#include +#include +#elif defined(__linux__) +#include +#include +#include +#else +#error "no system interface is known for this target" +#endif + +#include + +namespace { + +#if defined(_WIN32) +bool say(const std::string& text) +{ + HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD written = 0; + const auto length = static_cast(text.size()); + return out != INVALID_HANDLE_VALUE && WriteFile(out, text.data(), length, &written, nullptr) && written == length; +} +#elif defined(__APPLE__) +bool say(const std::string& text) +{ + // Any Mach call proves the kernel headers and libSystem resolved. + if (mach_task_self() == MACH_PORT_NULL) { + return false; + } + // Checking for a release past the deployment target calls into + // compiler-rt, which the SDK does not ship. + qos_class_t qos = QOS_CLASS_DEFAULT; + if (__builtin_available(macOS 15.0, *)) { + qos = QOS_CLASS_USER_INITIATED; + } + dispatch_queue_t queue = dispatch_get_global_queue(qos, 0); + dispatch_semaphore_t done = dispatch_semaphore_create(0); + dispatch_data_t data = dispatch_data_create(text.data(), text.size(), queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT); + __block bool failed = true; + dispatch_write(STDOUT_FILENO, data, queue, ^(dispatch_data_t rest, int error) { + failed = rest != nullptr || error != 0; + dispatch_semaphore_signal(done); + }); + dispatch_semaphore_wait(done, DISPATCH_TIME_FOREVER); + return !failed; +} +#elif defined(__linux__) +static_assert(LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0), "the UAPI headers predate Linux 5.10"); + +bool say(const std::string& text) +{ + return syscall(SYS_write, STDOUT_FILENO, text.data(), text.size()) == static_cast(text.size()); +} +#endif + +} // namespace + +int main() +{ + const std::string greeting = std::string("Hello") + ", world!\n"; + return say(greeting) ? 0 : 1; +} diff --git a/contrib/smoke_test.py b/contrib/smoke_test.py new file mode 100755 index 000000000..1fc0d075c --- /dev/null +++ b/contrib/smoke_test.py @@ -0,0 +1,313 @@ +#!/usr/bin/env python3 +# coding: latin-1 + +# +# Copyright (c) 2026-present, The Dash Core developers +# SPDX-License-Identifier: MIT +# See the accompanying file LICENSE or https://opensource.org/license/MIT +# + +"""Build and test a probe for every supported target. + +Usage: + + nix develop ./contrib/nix#dev --command ./contrib/smoke_test.py + ./contrib/smoke_test.py --keep /tmp/smoke +""" + +from __future__ import annotations + +import argparse +import contextlib +import dataclasses +import os +import platform +import subprocess +import sys +import tempfile +from dataclasses import dataclass +from pathlib import Path + +import lief +from common import ( + RETCODE_ERR, + RETCODE_PASS, + format_table, +) + +# What every host binary prints. +GREETING = "Hello, world!" + +# Programs every toolchain builds, beside this script. +PROBES = Path(__file__).resolve().parent / "probes" + +# Rust needs nothing beyond its own standard library to greet. +HELLO_RS = 'fn main() { println!("Hello, world!"); }\n' + +# LIEF reads no WebAssembly, which is told apart by its magic and version. +WASM_PREAMBLE = b"\0asm\x01\0\0\0" + +# Seconds a build or a probe may run before it counts as hung. +TIMEOUT = 120 + +# Each target the devshell may carry drivers for, with the format and +# architecture its binaries must have. Mach-O versions come from the +# environment. +TARGETS = [ + ("aarch64-apple-darwin", "Mach-O", "arm64"), + ("x86_64-apple-darwin", "Mach-O", "x86_64"), + ("aarch64-unknown-linux-gnu", "ELF", "arm64"), + ("x86_64-unknown-linux-gnu", "ELF", "x86_64"), + ("x86_64-pc-windows-gnu", "PE", "x86_64"), + ("wasm32-unknown-unknown", "wasm", "wasm32"), +] + + +@dataclass(frozen=True) +class Kind: + """The format, architecture and Mach-O versions of a binary.""" + + fmt: str + arch: str + minos: str | None = None + sdk: str | None = None + + def __str__(self) -> str: + minos = f", minos {self.minos}" if self.minos else "" + sdk = f", sdk {self.sdk}" if self.sdk else "" + return f"{self.fmt} {self.arch}{minos}{sdk}" + + def satisfies(self, want: Kind) -> bool: + """Return whether this binary is what *want* asks for.""" + same = (self.fmt, self.arch) == (want.fmt, want.arch) + minos = want.minos in (None, self.minos) + return same and minos and want.sdk in (None, self.sdk) + + @staticmethod + def of(path: Path) -> Kind | None: + """Return the format and architecture *path* carries, or None.""" + try: + with path.open("rb") as f: + if f.read(len(WASM_PREAMBLE)) == WASM_PREAMBLE: + return Kind("wasm", "wasm32") + except OSError: + return None + + binary = lief.parse(str(path)) + if binary is None: + return None + fmt = binary.format.name.replace("MACHO", "Mach-O") + arch = binary.abstract.header.architecture.name.lower() + minos = sdk = None + if isinstance(binary, lief.MachO.Binary) and binary.has_build_version: + minos = _version(binary.build_version.minos) + sdk = _version(binary.build_version.sdk) + return Kind(fmt, arch, minos, sdk) + + +def _version(parts: list[int]) -> str: + """Return a Mach-O `major.minor.patch` version, dropping a zero patch.""" + major, minor, patch = parts + return f"{major}.{minor}" + (f".{patch}" if patch else "") + + +def _canonical(version: str | None) -> str | None: + """Return *version* as `_version` spells it, so `14` matches `14.0`.""" + if not version: + return None + try: + parts = [int(part) for part in version.split(".")] + except ValueError: + return version + return _version([*parts, 0, 0][:3]) + + +class Report: + """Collects one row per binary and whether every row passed.""" + + def __init__(self) -> None: + self.rows: list[tuple[str, str, str]] = [] + self.failed = False + + def add(self, name: str, lang: str, result: str, *, ok: bool = True) -> None: + self.rows.append((name, lang, result if ok else f"FAILED, {result}")) + self.failed |= not ok + + def held( + self, name: str, lang: str, path: Path, want: Kind, *, note: str = "" + ) -> bool: + """Record whether the binary at *path*, or with a suffix, is *want*.""" + found = next(iter(_outputs(path)), None) + got = Kind.of(found) if found is not None else None + if got is None: + self.add(name, lang, "nothing recognisable was built", ok=False) + elif not got.satisfies(want): + self.add(name, lang, f"{got}, wanted {want}", ok=False) + else: + self.add(name, lang, f"{got}{note}") + return True + return False + + def greets(self, name: str, lang: str, path: Path, want: Kind) -> None: + """Record whether the host binary at *path* is *want* and greets.""" + try: + result = _run([str(path)]) + except (OSError, subprocess.TimeoutExpired) as exc: + self.add(name, lang, _unfinished(exc), ok=False) + return + if result.returncode != 0: + self.add(name, lang, f"exited with {result.returncode}", ok=False) + return + if result.stdout.strip() != GREETING: + self.add(name, lang, "no greeting", ok=False) + return + self.held(name, lang, path, want, note=", ran") + + +class Builder: + """Builds the probes into one directory and records each result.""" + + def __init__(self, report: Report, out: Path) -> None: + self.report = report + self.out = out + self.src = { + "c": PROBES / "hello.c", + "cpp": PROBES / "hello.cpp", + "rs": out / "hello.rs", + "free": PROBES / "free.c", + } + self.src["rs"].write_text(HELLO_RS, encoding="utf-8") + + def build(self, name: str, lang: str, argv: list[str]) -> Path | None: + """Return the binary *argv* built, or None after recording why not.""" + binary = self.out / f"{name}.{lang}" + for stale in _outputs(binary): + stale.unlink() + try: + result = _run([*argv, "-o", str(binary)]) + except (OSError, subprocess.TimeoutExpired) as exc: + self.report.add(name, lang, _unfinished(exc), ok=False) + return None + if result.returncode != 0: + # The first error names the cause; the drivers' last line rarely does. + lines = result.stderr.strip().splitlines() + cause = next((ln for ln in lines if "error" in ln), None) + cause = cause or (lines[-1] if lines else "no output") + self.report.add(name, lang, cause, ok=False) + return None + return binary + + def host(self) -> None: + """Build with the host compilers, then run what they built.""" + want = host_kind() + for lang, compiler in ( + ("c", os.environ.get("CC", "cc")), + ("cpp", os.environ.get("CXX", "c++")), + ("rs", "rustc"), + ): + binary = self.build("host", lang, [compiler, str(self.src[lang])]) + if binary is not None: + self.report.greets("host", lang, binary, want) + + def target(self, triple: str, want: Kind) -> None: + """Build with the drivers the devshell carries for *triple*.""" + key = triple.replace("-", "_") + cc = os.environ.get(f"CC_{key}") + cxx = os.environ.get(f"CXX_{key}") + if want.fmt == "Mach-O": + minos = _canonical(os.environ.get("MACOSX_DEPLOYMENT_TARGET")) + # Set only when clang reads the version from `SDKSettings.json`. + sdk = _canonical(os.environ.get("MACOS_SDK_VERSION")) + if (cc or cxx) and not (minos and sdk): + unset = "MACOSX_DEPLOYMENT_TARGET" if not minos else "MACOS_SDK_VERSION" + self.report.add(triple, "all", f"no {unset}", ok=False) + return + want = dataclasses.replace(want, minos=minos, sdk=sdk) + + rs = str(self.src["rs"]) + # wasm32 has no libc to greet through, so it builds a bare object. + if want.fmt == "wasm": + free = str(self.src["free"]) + langs = [("c", [cc, "-c", free] if cc else None), ("cpp", None)] + # rustc links wasm32 with its own rust-lld, so it needs no driver. + rust = ["rustc", f"--target={triple}", rs] + else: + langs = [ + ("c", [cc, str(self.src["c"])] if cc else None), + ("cpp", [cxx, str(self.src["cpp"])] if cxx else None), + ] + rust = None + if cc: + rust = ["rustc", f"--target={triple}", f"-Clinker={cc}", rs] + + for lang, argv in [*langs, ("rs", rust)]: + if argv is None: + self.report.add(triple, lang, "skipped") + continue + binary = self.build(triple, lang, argv) + if binary is not None: + self.report.held(triple, lang, binary, want) + + +def _run(argv: list[str]) -> subprocess.CompletedProcess[str]: + return subprocess.run( # noqa: S603 + argv, capture_output=True, check=False, text=True, timeout=TIMEOUT + ) + + +def _unfinished(exc: OSError | subprocess.TimeoutExpired) -> str: + """Return why a command never finished, for its report row.""" + if isinstance(exc, subprocess.TimeoutExpired): + return f"timed out after {TIMEOUT}s" + return f"could not run, {(exc.strerror or str(exc)).lower()}" + + +def _outputs(binary: Path) -> list[Path]: + """Return *binary* and any file a driver named after it plus a suffix.""" + return sorted( + p + for p in binary.parent.glob(binary.name + "*") + if p.name == binary.name or p.name.startswith(binary.name + ".") + ) + + +def host_kind() -> Kind: + """Return what a binary built for the host is.""" + machine = platform.machine().lower() + machine = {"aarch64": "arm64", "amd64": "x86_64"}.get(machine, machine) + fmt = "Mach-O" if platform.system() == "Darwin" else "ELF" + return Kind(fmt, machine) + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__.splitlines()[0]) + parser.add_argument( + "--keep", + type=Path, + metavar="DIR", + help="build into DIR and keep it, instead of a temporary directory", + ) + args = parser.parse_args() + lief.logging.disable() + + report = Report() + scratch = ( + contextlib.nullcontext(str(args.keep)) + if args.keep + else tempfile.TemporaryDirectory(prefix="smoke-") + ) + with scratch as where: + # Absolute, so running a host binary never searches PATH. + out = Path(where).resolve() + out.mkdir(parents=True, exist_ok=True) + builder = Builder(report, out) + builder.host() + for triple, fmt, arch in TARGETS: + builder.target(triple, Kind(fmt, arch)) + print(format_table(("target", "lang", "result"), report.rows)) + + return RETCODE_ERR if report.failed else RETCODE_PASS + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/docs/dev/devshells.md b/docs/dev/devshells.md index 097d6297a..dfe75b74b 100644 --- a/docs/dev/devshells.md +++ b/docs/dev/devshells.md @@ -22,6 +22,12 @@ then generate an updated lockfile by running `uv lock` in the shell. Then re-enter a fresh devshell, it should take on the new definitions. +* **Linux devshells expect a standard layout** + + Binaries built for standard Linux systems look for dynamic loaders and libraries at paths NixOS leaves empty. + `fhs-run ` runs a command in an [FHS](https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html) layout + typical of Linux distributions, and `fhs-run bash` opens a shell in it. The Docker container enters it by default. + * **Pinned versions of tools don't match against manual setup** Manual setup installs PyPI-sourced dependencies with `.dev`. Not every PyPI package is written in Python nor does it diff --git a/maint/README.md b/maint/README.md index e2ae40bcf..278fc9140 100644 --- a/maint/README.md +++ b/maint/README.md @@ -15,6 +15,7 @@ use [`lint_all.py`](./lint_all.py). | Name | Purpose | Verbs | Depends on | | ---- | ------- | ---------- | ---------- | | [`lint_commit.py`](./lint/lint_commit.py) | Lint commit names against [`commit.toml`](./commit.toml) | `run` | `git` | +| [`lint_bazel.py`](./lint/lint_bazel.py) | Lint Starlark files with `buildifier` | `check`, `apply`, `apply-all` | `buildifier` | | [`lint_cargo.py`](./lint/lint_cargo.py) | Deny dependencies per [`deny.toml`](../.cargo/deny.toml), check/format TOML files against [`taplo.toml`](./taplo.toml) | `check` , `apply`, `apply-all` | `cargo-deny` (deny dependencies), `taplo` (TOML formatting) | | [`lint_codeql.py`](./lint/lint_codeql.py) | Query Rust sources against [`maint/codeql/rust/*.ql`](./codeql/rust) | `check`, `apply`, `apply-all`, `run`, `run-all` | `codeql`, `rustc` | | [`lint_javascript.py`](./lint/lint_javascript.py) | Lint Javascript sources against [`eslint.config.mjs`](js/eslint.config.mjs) | *None* | `npx` (part of Node.js), `eslint` (auto-retrieved by script) | diff --git a/maint/codeql/rust/codeql-config.yml b/maint/codeql/rust/codeql-config.yml index da2c0c08a..033dc18df 100644 --- a/maint/codeql/rust/codeql-config.yml +++ b/maint/codeql/rust/codeql-config.yml @@ -1,5 +1,6 @@ disable-default-queries: true paths-ignore: + - .cache - public - target queries: diff --git a/maint/codeql/rust/lib/crates.qll b/maint/codeql/rust/lib/crates.qll index 79ce18387..7b2473888 100644 --- a/maint/codeql/rust/lib/crates.qll +++ b/maint/codeql/rust/lib/crates.qll @@ -24,9 +24,9 @@ private string packageName(string segments) { /** Holds if a crate directory named `crate` holds `f`. */ private predicate encloses(string crate, File f) { exists(string path | path = f.getAbsolutePath() | - crate = packageName(path.regexpCapture(".*/pkgs/([^/]+)/.*", 1)) + crate = packageName(path.regexpCapture(".*/(?:meta|pkgs)/([^/]+)/.*", 1)) or - crate = packageName(path.regexpCapture(".*/pkgs/([^/]+/[^/]+)/.*", 1)) + crate = packageName(path.regexpCapture(".*/(?:meta|pkgs)/([^/]+/[^/]+)/.*", 1)) or crate = packageName(path.regexpCapture(".*/fuzz/([^/]+)/.*", 1)) + "-fuzz" ) diff --git a/maint/codeql/rust/lib/files.qll b/maint/codeql/rust/lib/files.qll index 904597cd6..684b0decb 100644 --- a/maint/codeql/rust/lib/files.qll +++ b/maint/codeql/rust/lib/files.qll @@ -33,7 +33,7 @@ File fileOf(Locatable n) { result = n.getLocation().getFile() } /** Materialises the repo-root-relative path for source files. */ pragma[nomagic] predicate fileRelPath(File f, string relPath) { - relPath = f.getAbsolutePath().regexpCapture(".*/(pkgs/.*)", 1) + relPath = f.getAbsolutePath().regexpCapture(".*/((?:meta|pkgs)/.*)", 1) } /** Holds if `f` belongs to a crate in this workspace. */ diff --git a/maint/codeql/rust/lib/filters.qll b/maint/codeql/rust/lib/filters.qll index 5e37777b1..5b1714ed9 100644 --- a/maint/codeql/rust/lib/filters.qll +++ b/maint/codeql/rust/lib/filters.qll @@ -86,7 +86,7 @@ predicate hasLifetime(TypeItem t) { string cratePrefix(TypeItem t) { exists(string path | path = fileOf(t).getAbsolutePath() and - result = path.regexpCapture("(.*/pkgs/[^/]+/).*", 1) + result = path.regexpCapture("(.*/(?:meta|pkgs)/[^/]+/).*", 1) ) } diff --git a/maint/common.py b/maint/common.py index 0a469d43b..4c0e2a3d0 100644 --- a/maint/common.py +++ b/maint/common.py @@ -36,7 +36,7 @@ CARGO_WORKSPACES: tuple[str, ...] = (".", "docs/samples", "fuzz") # Rust source roots the analysers scan, relative to the repository root. -SOURCE_DIRS: tuple[str, ...] = ("pkgs", "docs/samples", "fuzz") +SOURCE_DIRS: tuple[str, ...] = ("meta", "pkgs", "docs/samples", "fuzz") # Assumed base branch for codebase. DEFAULT_BASE = "develop" diff --git a/maint/lint/lint_bazel.py b/maint/lint/lint_bazel.py new file mode 100755 index 000000000..e05eb2166 --- /dev/null +++ b/maint/lint/lint_bazel.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +# coding: latin-1 + +# +# Copyright (c) 2026-present, The Dash Core developers +# SPDX-License-Identifier: MIT +# See the accompanying file LICENSE or https://opensource.org/license/MIT +# + +"""Validate Bazel's build definitions (in Starlark) with buildifier.""" + +from __future__ import annotations + +import sys +from pathlib import Path + +from common import ( + DEFAULT_BASE, + RETCODE_ERR, + RETCODE_SKIP, + declare_verbs, + formatted, + relay, + repo_files, + require_bin, + root_dir, + touched, +) + +# Base name of this script (equivalent to argv[0]). +SCRIPT = Path(__file__).stem + +# Spellings of a Starlark file buildifier understands. +STARLARK_SUFFIXES: tuple[str, ...] = (".bazel", ".bzl") + + +def _check_format( + repo_root: Path, + *, + fix: bool, + only: list[str] | None = None, +) -> int | None: + """Format and lint Starlark, or None when buildifier is absent.""" + try: + buildifier = require_bin("buildifier") + except FileNotFoundError as e: + print(f"{e}, skipping the Starlark check", file=sys.stderr) + return None + + sources = ( + repo_files(repo_root, *(f"*{s}" for s in STARLARK_SUFFIXES)) + if only is None + else [Path(n) for n in only] + ) + mode = "fix" if fix else "check" + return formatted( + SCRIPT, + "Starlark file", + sources, + lambda paths: [ + buildifier, + f"--mode={mode}", + f"--lint={'fix' if fix else 'warn'}", + *[str(p) for p in paths], + ], + fix=fix, + scoped=only is not None, + cwd=repo_root, + output=lambda out, err: ( + relay(out, repo_root), + relay(err, repo_root, stream=sys.stderr), + ), + ) + + +def main() -> int: + args = declare_verbs( + "Validate Starlark.", + { + "check": "report every Starlark fault, changing nothing", + "apply": f"also rewrite Starlark this branch changed vs {DEFAULT_BASE}", + "apply-all": "also rewrite every Starlark file in the tree", + }, + ).parse_args(sys.argv[1:]) + repo_root = root_dir() + + fix = args.verb.startswith("apply") + only = touched(repo_root, STARLARK_SUFFIXES) if args.verb == "apply" else None + verdict = _check_format(repo_root, fix=fix, only=only) + + return RETCODE_SKIP if verdict is None else verdict + + +if __name__ == "__main__": + try: + sys.exit(main()) + except Exception as exc: # noqa: BLE001 + print(exc, file=sys.stderr) + sys.exit(RETCODE_ERR) diff --git a/maint/lint/lint_cargo.py b/maint/lint/lint_cargo.py index 9f5b2b98c..df415f181 100755 --- a/maint/lint/lint_cargo.py +++ b/maint/lint/lint_cargo.py @@ -9,8 +9,7 @@ """Validate and enforce constraints across Rust's build system, cargo. -Includes a TOML formatter using taplo that affects all TOML files regardless of -provenance or origin, exclusions must be defined in 'maint/taplo.toml' +taplo formats tracked TOML files except those excluded by 'maint/taplo.toml'. """ from __future__ import annotations @@ -27,6 +26,7 @@ declare_verbs, formatted, relay, + repo_files, require_bin, root_dir, touched, @@ -60,12 +60,15 @@ def shorten(out: str, err: str) -> None: drop=lambda line: line.lstrip().startswith("INFO"), ) - # None, not an empty list: with no paths taplo finds its own through - # 'maint/taplo.toml', so there is no count to report for the whole tree. + sources = ( + repo_files(repo_root, "*.toml") + if only is None + else [Path(name) for name in only] + ) return formatted( SCRIPT, "TOML file", - None if only is None else [Path(name) for name in only], + sources, lambda paths: [ taplo, "fmt", "--config", str(repo_root / "maint" / "taplo.toml"), diff --git a/maint/lint/lint_symlinks.py b/maint/lint/lint_symlinks.py index 799623062..78dddb621 100755 --- a/maint/lint/lint_symlinks.py +++ b/maint/lint/lint_symlinks.py @@ -15,7 +15,7 @@ - They must not dangle (i.e. point to non-existent resources) - They must not have a depth >1 (i.e. cannot point to another symlink) - They must not point to resources outside the repository (to prevent escapes) -- They must not appear inside a crate directory (`pkgs/`) +- They must not appear inside a publishable crate directory (`pkgs/`) """ from __future__ import annotations @@ -109,7 +109,8 @@ def main() -> int: faults.append(f"{path} -> {target}: {fault}") elif path.startswith("pkgs/"): faults.append( - f"{path} -> {target}: symlink inside a crate directory is prohibited", + f"{path} -> {target}: symlink inside a publishable crate directory " + "is prohibited", ) elif mode in _MODE_FILE: fault = _hard_link_fault(repo_root, path) diff --git a/maint/semgrep/rust/cargo.yml b/maint/semgrep/rust/cargo.yml index 74f03eb5d..18c0721ec 100644 --- a/maint/semgrep/rust/cargo.yml +++ b/maint/semgrep/rust/cargo.yml @@ -4,6 +4,6 @@ rules: severity: ERROR languages: [generic] paths: - include: [/pkgs/**/Cargo.toml] - exclude: [/pkgs/dev/Cargo.toml] + include: [/meta/**/Cargo.toml, /pkgs/**/Cargo.toml] + exclude: [/meta/dev/Cargo.toml] pattern-regex: \b(serde[-_]json|json5)\b diff --git a/maint/semgrep/rust/workspace.yml b/maint/semgrep/rust/workspace.yml index 50e660b8f..0dee6a683 100644 --- a/maint/semgrep/rust/workspace.yml +++ b/maint/semgrep/rust/workspace.yml @@ -4,7 +4,7 @@ rules: severity: ERROR languages: [rust] paths: - include: [/pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] + include: [/meta/**/*.rs, /pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] pattern-regex: |- (?xm) ^[ \t]* # line start, optional indent @@ -19,13 +19,15 @@ rules: severity: ERROR languages: [rust] paths: - include: [/pkgs/**/*.rs] + include: [/meta/**/*.rs, /pkgs/**/*.rs] exclude: - "**/lib.rs" - "**/main.rs" - "**/mod.rs" - "**/build.rs" + - /meta/**/tests/** - /pkgs/**/tests/** + - /meta/**/bench/** - /pkgs/**/bench/** pattern-regex: '(?m)^\s*#!\[' @@ -34,7 +36,7 @@ rules: severity: ERROR languages: [generic] paths: - include: [/pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] + include: [/meta/**/*.rs, /pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] exclude: ["**/lib.rs", "**/main.rs", "**/mod.rs"] options: generic_multiline: true @@ -50,7 +52,7 @@ rules: severity: ERROR languages: [rust] paths: - include: [/pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] + include: [/meta/**/*.rs, /pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] patterns: - pattern-regex: |- (?xm) @@ -81,7 +83,7 @@ rules: severity: ERROR languages: [rust] paths: - include: [/pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] + include: [/meta/**/*.rs, /pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] pattern-regex: 'derive\([^)]*(?\s+for\b' - id: macro-export-no-serde-cfg @@ -106,6 +108,7 @@ rules: languages: [rust] paths: include: + - /meta/**/*.rs - /pkgs/**/*.rs exclude: - /pkgs/types/marker/** @@ -125,6 +128,7 @@ rules: languages: [rust] paths: include: + - /meta/**/*.rs - /pkgs/**/*.rs exclude: - /pkgs/types/marker/** @@ -139,6 +143,7 @@ rules: languages: [rust] paths: include: + - /meta/**/*.rs - /pkgs/**/*.rs exclude: - /pkgs/types/marker/** @@ -153,9 +158,11 @@ rules: severity: ERROR languages: [rust] paths: - include: [/pkgs/**/*.rs] + include: [/meta/**/*.rs, /pkgs/**/*.rs] exclude: + - /meta/**/prelude.rs - /pkgs/**/prelude.rs + - /meta/**/prelude/mod.rs - /pkgs/**/prelude/mod.rs - /docs/samples/** pattern-regex: '\buse\s+(::)?alloc(::|\s)' @@ -165,9 +172,11 @@ rules: severity: ERROR languages: [rust] paths: - include: [/pkgs/**/*.rs] + include: [/meta/**/*.rs, /pkgs/**/*.rs] exclude: + - /meta/**/prelude.rs - /pkgs/**/prelude.rs + - /meta/**/prelude/mod.rs - /pkgs/**/prelude/mod.rs - /docs/samples/** pattern-regex: '\buse\s+crate::prelude::[^*]' @@ -177,7 +186,7 @@ rules: severity: ERROR languages: [rust] paths: - include: [/pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] + include: [/meta/**/*.rs, /pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] patterns: - pattern-either: - pattern: | @@ -193,8 +202,8 @@ rules: severity: ERROR languages: [rust] paths: - include: [/pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] - exclude: [/pkgs/**/tests/**, /pkgs/**/bench/**] + include: [/meta/**/*.rs, /pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] + exclude: [/meta/**/tests/**, /meta/**/bench/**, /pkgs/**/tests/**, /pkgs/**/bench/**] patterns: - pattern-either: - pattern: | @@ -222,7 +231,7 @@ rules: severity: ERROR languages: [rust] paths: - include: [/pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] + include: [/meta/**/*.rs, /pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] pattern-regex: '^\s*//[/!]?\s*[-=]{4,}|^\s*//\s+--\s' - id: style-latin1-source @@ -230,7 +239,7 @@ rules: severity: ERROR languages: [rust] paths: - include: [/pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] + include: [/meta/**/*.rs, /pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] pattern-regex: '[^\x00-\xFF]' - id: typeid-no-manual-impl @@ -239,6 +248,7 @@ rules: languages: [rust] paths: include: + - /meta/**/*.rs - /pkgs/**/*.rs - /docs/samples/**/*.rs - /fuzz/**/*.rs @@ -251,7 +261,7 @@ rules: severity: ERROR languages: [rust] paths: - include: [/pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] + include: [/meta/**/*.rs, /pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] exclude: ["**/lib.rs", "**/mod.rs"] pattern-regex: '^\s*pub\s+use\s' @@ -260,7 +270,7 @@ rules: severity: ERROR languages: [rust] paths: - include: [/pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] + include: [/meta/**/*.rs, /pkgs/**/*.rs, /docs/samples/**/*.rs, /fuzz/**/*.rs] exclude: - /pkgs/types/src/entity.rs # declares the generator - /pkgs/types/src/secret.rs # declares its secret sibling diff --git a/meta/bazel/BUILD.bazel b/meta/bazel/BUILD.bazel new file mode 100644 index 000000000..c0e902eab --- /dev/null +++ b/meta/bazel/BUILD.bazel @@ -0,0 +1,5 @@ +# Exported for crate_universe, which resolves the crate graph from it. +exports_files( + ["Cargo.toml"], + visibility = ["//visibility:public"], +) diff --git a/meta/bazel/Cargo.toml b/meta/bazel/Cargo.toml new file mode 100644 index 000000000..9b50637c7 --- /dev/null +++ b/meta/bazel/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "dash-meta-bazel" +version = "0.0.0" +description = "Crate used for dependency graph resolution by Bazel" +publish = false +authors.workspace = true +edition.workspace = true +homepage.workspace = true +license.workspace = true +repository.workspace = true +rust-version.workspace = true + +[lib] +bench = false + +[features] +default = [] +std = [] +full = ["std"] + +[lints] +workspace = true diff --git a/meta/bazel/src/lib.rs b/meta/bazel/src/lib.rs new file mode 100644 index 000000000..b5b29cbd4 --- /dev/null +++ b/meta/bazel/src/lib.rs @@ -0,0 +1,13 @@ +// +// Copyright (c) 2026-present, The Dash Core developers +// SPDX-License-Identifier: MIT +// See the accompanying file LICENSE or https://opensource.org/license/MIT +// + +//! Anchor for the crate graph Bazel resolves. + +#![no_std] + +extern crate alloc; +#[cfg(feature = "std")] +extern crate std; diff --git a/pkgs/dev/Cargo.toml b/meta/dev/Cargo.toml similarity index 77% rename from pkgs/dev/Cargo.toml rename to meta/dev/Cargo.toml index a526d6c9e..fe7b25e08 100644 --- a/pkgs/dev/Cargo.toml +++ b/meta/dev/Cargo.toml @@ -50,7 +50,7 @@ bin = [ [build-dependencies] built = { version = "0.7", features = ["dependency-tree", "git2"] } -dash-types = { version = "0.2.0-beta", path = "../types", default-features = false, features = [ +dash-types = { version = "0.2.0-beta", path = "../../pkgs/types", default-features = false, features = [ "codec", ] } proc-macro2 = "1" @@ -60,13 +60,13 @@ xxhash-rust = { version = "0.8", features = ["xxh32"] } [dependencies] bitcoin-consensus-encoding = { workspace = true, features = ["alloc"] } cfg-if = "1" -dash-num = { version = "0.2.0-beta", path = "../num", optional = true, features = [ +dash-num = { version = "0.2.0-beta", path = "../../pkgs/num", optional = true, features = [ "codec", ] } -dash-params = { version = "0.0.0", path = "../params", optional = true } -dash-pow = { version = "0.1.0-beta", path = "../pow", default-features = false, optional = true } -dash-primitives = { version = "0.0.0", path = "../primitives" } -dash-types = { version = "0.2.0-beta", path = "../types", default-features = false, features = [ +dash-params = { version = "0.0.0", path = "../../pkgs/params", optional = true } +dash-pow = { version = "0.1.0-beta", path = "../../pkgs/pow", default-features = false, optional = true } +dash-primitives = { version = "0.0.0", path = "../../pkgs/primitives" } +dash-types = { version = "0.2.0-beta", path = "../../pkgs/types", default-features = false, features = [ "codec", ] } hex-conservative = { workspace = true, features = [ diff --git a/pkgs/dev/build.rs b/meta/dev/build.rs similarity index 100% rename from pkgs/dev/build.rs rename to meta/dev/build.rs diff --git a/pkgs/dev/src/bin/bsdk_util/bspcheck.rs b/meta/dev/src/bin/bsdk_util/bspcheck.rs similarity index 100% rename from pkgs/dev/src/bin/bsdk_util/bspcheck.rs rename to meta/dev/src/bin/bsdk_util/bspcheck.rs diff --git a/pkgs/dev/src/bin/bsdk_util/logging.rs b/meta/dev/src/bin/bsdk_util/logging.rs similarity index 100% rename from pkgs/dev/src/bin/bsdk_util/logging.rs rename to meta/dev/src/bin/bsdk_util/logging.rs diff --git a/pkgs/dev/src/bin/bsdk_util/main.rs b/meta/dev/src/bin/bsdk_util/main.rs similarity index 100% rename from pkgs/dev/src/bin/bsdk_util/main.rs rename to meta/dev/src/bin/bsdk_util/main.rs diff --git a/pkgs/dev/src/bin/bsdk_util/platform.rs b/meta/dev/src/bin/bsdk_util/platform.rs similarity index 100% rename from pkgs/dev/src/bin/bsdk_util/platform.rs rename to meta/dev/src/bin/bsdk_util/platform.rs diff --git a/pkgs/dev/src/bin/bsdk_util/policy.rs b/meta/dev/src/bin/bsdk_util/policy.rs similarity index 100% rename from pkgs/dev/src/bin/bsdk_util/policy.rs rename to meta/dev/src/bin/bsdk_util/policy.rs diff --git a/pkgs/dev/src/corpus.rs b/meta/dev/src/corpus.rs similarity index 100% rename from pkgs/dev/src/corpus.rs rename to meta/dev/src/corpus.rs diff --git a/pkgs/dev/src/encode.rs b/meta/dev/src/encode.rs similarity index 100% rename from pkgs/dev/src/encode.rs rename to meta/dev/src/encode.rs diff --git a/pkgs/dev/src/json.rs b/meta/dev/src/json.rs similarity index 100% rename from pkgs/dev/src/json.rs rename to meta/dev/src/json.rs diff --git a/pkgs/dev/src/lambda.rs b/meta/dev/src/lambda.rs similarity index 100% rename from pkgs/dev/src/lambda.rs rename to meta/dev/src/lambda.rs diff --git a/pkgs/dev/src/lib.rs b/meta/dev/src/lib.rs similarity index 100% rename from pkgs/dev/src/lib.rs rename to meta/dev/src/lib.rs diff --git a/pkgs/dev/src/prelude.rs b/meta/dev/src/prelude.rs similarity index 100% rename from pkgs/dev/src/prelude.rs rename to meta/dev/src/prelude.rs diff --git a/pkgs/num/Cargo.toml b/pkgs/num/Cargo.toml index 8d6117513..3d9f8b978 100644 --- a/pkgs/num/Cargo.toml +++ b/pkgs/num/Cargo.toml @@ -61,7 +61,7 @@ serde = { workspace = true, features = [ ], optional = true } [dev-dependencies] -dash-dev = { path = "../dev", features = ["full"] } +dash-dev = { path = "../../meta/dev", features = ["full"] } divan = { workspace = true } rstest = { workspace = true } serde = { workspace = true, features = ["derive", "std"] } diff --git a/pkgs/p2p_core/Cargo.toml b/pkgs/p2p_core/Cargo.toml index c4d231b5e..73f3870bc 100644 --- a/pkgs/p2p_core/Cargo.toml +++ b/pkgs/p2p_core/Cargo.toml @@ -54,7 +54,7 @@ serde = { workspace = true, features = [ thiserror = { workspace = true } [dev-dependencies] -dash-dev = { version = "0.0.0", path = "../dev", features = ["full"] } +dash-dev = { version = "0.0.0", path = "../../meta/dev", features = ["full"] } hex-conservative = { workspace = true, features = ["std"] } rstest = { workspace = true } serde = { workspace = true, features = ["derive", "std"] } diff --git a/pkgs/pkc/Cargo.toml b/pkgs/pkc/Cargo.toml index e10c6faab..aa67fe0db 100644 --- a/pkgs/pkc/Cargo.toml +++ b/pkgs/pkc/Cargo.toml @@ -62,7 +62,7 @@ zeroize = { workspace = true, features = ["alloc", "derive"] } [dev-dependencies] bitcoin-consensus-encoding = { workspace = true, features = ["alloc"] } -dash-dev = { path = "../dev", features = ["full"] } +dash-dev = { path = "../../meta/dev", features = ["full"] } divan = { workspace = true } getrandom = { version = "0.4", features = ["sys_rng"] } hex-conservative = { workspace = true, features = ["std"] } diff --git a/pkgs/pow/Cargo.toml b/pkgs/pow/Cargo.toml index 8faca25d9..9d35d06be 100644 --- a/pkgs/pow/Cargo.toml +++ b/pkgs/pow/Cargo.toml @@ -41,7 +41,7 @@ digest = { workspace = true } wide = { workspace = true } [dev-dependencies] -dash-dev = { path = "../dev", features = ["full"] } +dash-dev = { path = "../../meta/dev", features = ["full"] } divan = { workspace = true } hex-conservative = { workspace = true } rstest = { workspace = true } diff --git a/pkgs/primitives/Cargo.toml b/pkgs/primitives/Cargo.toml index 9da00480c..a85d06b47 100644 --- a/pkgs/primitives/Cargo.toml +++ b/pkgs/primitives/Cargo.toml @@ -66,7 +66,7 @@ serde = { workspace = true, features = [ thiserror = { workspace = true } [dev-dependencies] -dash-dev = { version = "0.0.0", path = "../dev", features = ["full"] } +dash-dev = { version = "0.0.0", path = "../../meta/dev", features = ["full"] } rstest = { workspace = true } serde = { workspace = true, features = ["derive", "std"] } diff --git a/pyproject.toml b/pyproject.toml index b6afca52c..8576dcee0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,6 +6,7 @@ requires-python = ">=3.11" [project.optional-dependencies] dev = ["dash-base-sdk[tools,lib]"] lib = [ + "lief>=1.0", "Markdown>=3.7", "pygments-styles>=0.3.0", "pymarkdownlnt>=0.9.37", diff --git a/uv.lock b/uv.lock index b6cc0a4a7..7e9ba213d 100644 --- a/uv.lock +++ b/uv.lock @@ -448,6 +448,7 @@ source = { editable = "." } [package.optional-dependencies] dev = [ + { name = "lief" }, { name = "markdown" }, { name = "pygments-styles" }, { name = "pymarkdownlnt" }, @@ -459,6 +460,7 @@ dev = [ { name = "zensical" }, ] lib = [ + { name = "lief" }, { name = "markdown" }, { name = "pygments-styles" }, { name = "pymarkdownlnt" }, @@ -475,6 +477,7 @@ tools = [ [package.metadata] requires-dist = [ { name = "dash-base-sdk", extras = ["tools", "lib"], marker = "extra == 'dev'" }, + { name = "lief", marker = "extra == 'lib'", specifier = ">=1.0" }, { name = "markdown", marker = "extra == 'lib'", specifier = ">=3.7" }, { name = "pygments-styles", marker = "extra == 'lib'", specifier = ">=0.3.0" }, { name = "pymarkdownlnt", marker = "extra == 'lib'", specifier = ">=0.9.37" }, @@ -658,6 +661,66 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, ] +[[package]] +name = "lief" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0e/05/30df8a9af4f9b183b5e89373626cf019bd98f46fe52728ab74cacd31d76a/lief-1.0.0.tar.gz", hash = "sha256:811b2354f48fa08c49b106eafc9c1b26006371dc24d3d04bfdd9939863df6e6a", size = 7774, upload-time = "2026-07-12T14:12:09.152Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/21/64/300f5789ea54d4dcd6385132aee6b0bb6b135518b345bd2bc56949061e2d/lief-1.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e9037bda164285b2a59ee3910dfb70e775b2e3ba793edc565725e0bf926b09e9", size = 3286965, upload-time = "2026-07-12T14:10:22.129Z" }, + { url = "https://files.pythonhosted.org/packages/1f/7d/6b814a223c9e2a1a10bb476359488fb247921b38468251325b3e83f06bed/lief-1.0.0-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:2edb6c75944a90e1f9b6fb0e086844b7d00311344149f4007dd4f029476f8fe2", size = 3375351, upload-time = "2026-07-12T14:10:23.759Z" }, + { url = "https://files.pythonhosted.org/packages/6f/21/097f7f28157870491d648c65befd3a66163eb42f23bd12d1bbda59e94c5e/lief-1.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:95fb7dc84960068ab881bc681e646cab55f3d736c07bb07e91d5cbc8738885a7", size = 3610243, upload-time = "2026-07-12T14:10:25.303Z" }, + { url = "https://files.pythonhosted.org/packages/92/2d/48a2713e5750cfd3ccd0e59662050b91273b1fbf09b4cad88a216335f947/lief-1.0.0-cp311-cp311-manylinux_2_28_i686.whl", hash = "sha256:ea1220b0b68a9b2cd6d1b3f05276c877d136f5b39e3a01d3433df70a92803071", size = 3753319, upload-time = "2026-07-12T14:10:27.022Z" }, + { url = "https://files.pythonhosted.org/packages/0d/61/ca1a9d8ec16bc0075849cb4be47e7d5e5dae8d354d2ef32eb619ad204f8c/lief-1.0.0-cp311-cp311-manylinux_2_28_riscv64.whl", hash = "sha256:5aa92fa9501d60c0dbc8fe88d40fa9f19708fad958674eaea1b52cf4217e734d", size = 3693124, upload-time = "2026-07-12T14:10:28.497Z" }, + { url = "https://files.pythonhosted.org/packages/09/b5/36e2ce60fcd60d2cc20f743ad50d437380c3f9f51d9b2942b230f0c05b72/lief-1.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:96277e45d58de45a33249079dac43e50db1c96da162fbe1ad02fbaa82e3bd06f", size = 3670339, upload-time = "2026-07-12T14:10:30.354Z" }, + { url = "https://files.pythonhosted.org/packages/7a/bf/bf9690141bb137bc99e94c38722a69ae2da428ad8c9e972136b28e5a56eb/lief-1.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:514ba1c9c94f0cd09986bfb1db71fd678acd19f826058fe9cefbba0e7b9a5d86", size = 3918692, upload-time = "2026-07-12T14:10:32.005Z" }, + { url = "https://files.pythonhosted.org/packages/b1/cb/54a449fa7590348c21022f6aba3544d4b576474a1a13d5187482eb0b6867/lief-1.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7ed5d9511cd7313bb56c95c4f580e8e332615ae0bd45e05b43990f1b563ceef3", size = 4196769, upload-time = "2026-07-12T14:10:34.106Z" }, + { url = "https://files.pythonhosted.org/packages/e9/58/5d09f19505daf08faf557a92f0af36ee5f1866bbdcc43977fd690c80f599/lief-1.0.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:37810cadad1fd796b6a681fe7eac084489103a7b2fed306776f9932b38c8d4ac", size = 3971579, upload-time = "2026-07-12T14:10:35.873Z" }, + { url = "https://files.pythonhosted.org/packages/3e/60/5440b2604553f95240b214549c73e29e9e7786f9b173a21fe5cc1fa833b2/lief-1.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:34d12d846529e5d5157a7feaf54d1bd8b6c2905cb6c46cc1f7c94fa9e9bd1f6a", size = 3963306, upload-time = "2026-07-12T14:10:37.592Z" }, + { url = "https://files.pythonhosted.org/packages/e5/07/0341a4de77c3a1b1223a7a996514b5995cb3b6ec7499d28ffadc5998fb59/lief-1.0.0-cp311-cp311-win32.whl", hash = "sha256:1a20cd029b539eb5888882b377617544da012e1bbb2ce575a524c87aaec1102b", size = 3722521, upload-time = "2026-07-12T14:22:41.152Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b0/74f50ca24b9a70ba75e4eed3d1a5f3dbf0608965b7adaf98f3afd14db0e2/lief-1.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:fbaf64c338086da0a5d67b0e440b7010f2fd4b1d6edc68db303693759320ebfb", size = 4011319, upload-time = "2026-07-12T14:10:39.338Z" }, + { url = "https://files.pythonhosted.org/packages/7b/36/01f6b6ba1efce59b538e86b4c5abbc3cfc11b18ae88e974f0aace834737a/lief-1.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:a9b7bae94a3a160af9b52f15265e55a59a1f3bb305ae9280cfe9ce84cf2c5d0e", size = 3766358, upload-time = "2026-07-12T14:10:40.917Z" }, + { url = "https://files.pythonhosted.org/packages/da/b0/9f231000f0b1d0d227fa4b3a6a66aff4d5168dcc642c697605e0df739b4f/lief-1.0.0-cp312-abi3-macosx_11_0_arm64.whl", hash = "sha256:92bf3b06c19a1ebd9e7978de47cc61040752ec452f7906bc3aac8d57abb23a8b", size = 3285262, upload-time = "2026-07-12T14:10:42.576Z" }, + { url = "https://files.pythonhosted.org/packages/03/68/4eaec5e731fa53d764d60767037fccb4ca55d1f2cf1679edaa8ae0f3a07f/lief-1.0.0-cp312-abi3-macosx_11_0_x86_64.whl", hash = "sha256:48e360eea660d019312e377954f327e4fe0918781ee45e9056cd641f50bb6355", size = 3376474, upload-time = "2026-07-12T14:10:44.265Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f8/3aba2989bd9f48e796de5260a19acb2af1e6562b147e32a2a26e418a9b58/lief-1.0.0-cp312-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:a9e4b9e165bde0163624e159c8c7a096e3d6f671371c70d008baac7ac1f04f0d", size = 3604777, upload-time = "2026-07-12T14:10:46.006Z" }, + { url = "https://files.pythonhosted.org/packages/e8/f4/73adc62ede9d8159d7b3bde312270f9ce33886647caa183db24c4e804d7e/lief-1.0.0-cp312-abi3-manylinux_2_28_i686.whl", hash = "sha256:6b5d975f45e8830bc12da346d3dd317803d8852f1b61838e655741178e46d300", size = 3753256, upload-time = "2026-07-12T14:10:47.739Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c1/b7093423a74b60f48a74c59c5cb84c20723a02484264c8b2d43662ef5761/lief-1.0.0-cp312-abi3-manylinux_2_28_riscv64.whl", hash = "sha256:5ab0c89879066a36467fb8b85485710e40ea982c90f46de3486d6633b1d43e2f", size = 3692596, upload-time = "2026-07-12T14:10:49.725Z" }, + { url = "https://files.pythonhosted.org/packages/cd/d7/6e8135da80a63d8ee413f169eda8c331817bf6f1496fc5647722b105aa19/lief-1.0.0-cp312-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:41ff868f5328fc8e5237a9e1f4718590e0ee9180c1422b3e4948b7116ba4517c", size = 3674893, upload-time = "2026-07-12T14:10:51.489Z" }, + { url = "https://files.pythonhosted.org/packages/fa/06/3b7f72f9fad8d36631aa6ba4a92edab9241806502b4d5d01f345aeb435f8/lief-1.0.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:30c48bb32afdcea98df04cd456e7199e84a629396faf475ca9c8880a4b4c1ce3", size = 3913123, upload-time = "2026-07-12T14:10:53.055Z" }, + { url = "https://files.pythonhosted.org/packages/6a/67/ec0046772e0c40a1274c42034382e93c26e33157ea917aa2ff4ba9b8be2b/lief-1.0.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:f58e26e2e4d110cd6a42d86ab497cd4bedc47d72690fae557023ac536d85edcc", size = 4197779, upload-time = "2026-07-12T14:10:54.789Z" }, + { url = "https://files.pythonhosted.org/packages/2f/50/554f682a5feb40ccf0663679bcbb479d7d4f6381d516d42859a9ead39f41/lief-1.0.0-cp312-abi3-musllinux_1_2_riscv64.whl", hash = "sha256:f6c2007bf96704cedc5cee8ae303ba7008840b9a2214ca9f4f43a6faa703834f", size = 3972848, upload-time = "2026-07-12T14:10:56.402Z" }, + { url = "https://files.pythonhosted.org/packages/da/ca/b113461f25a01a9165713de7f4ac7518ea21fb6e3939971d16d56a469c10/lief-1.0.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:714c96894048f15c8fcecbe6ef4a95416a0f256a20cc6130f8f2398ee717ca06", size = 3969432, upload-time = "2026-07-12T14:10:58.093Z" }, + { url = "https://files.pythonhosted.org/packages/87/e5/b7bcab0256eb2f15d71652d5578f338b4cac1629a35b5bef2607f41d0be9/lief-1.0.0-cp312-abi3-win32.whl", hash = "sha256:d552235f6c7b999b1837946b61cc64537501fac4fda1663c2cb76482b27b609f", size = 3720709, upload-time = "2026-07-12T14:22:43.058Z" }, + { url = "https://files.pythonhosted.org/packages/83/16/950c16d246c52a32b47aca19ade2919dfc9192cc4c45c92635c36d3a8b6b/lief-1.0.0-cp312-abi3-win_amd64.whl", hash = "sha256:ca7774b0d88f4528a1c153d7a9d2798800d6389847b966861fad9f2edb17a593", size = 4018974, upload-time = "2026-07-12T14:10:59.857Z" }, + { url = "https://files.pythonhosted.org/packages/91/2a/cc514b5ec9ec187335f2e8ab545d7b110a5f931d430a0bd2917563aefae4/lief-1.0.0-cp312-abi3-win_arm64.whl", hash = "sha256:956ee963e2a2ed318d08fd9fe4ff948906c483db1b88f7a62dac24db76ffa4b0", size = 3771788, upload-time = "2026-07-12T14:11:01.607Z" }, + { url = "https://files.pythonhosted.org/packages/e3/0e/e8fb688a7f282bc8fca82448c0e590fbba67ae754b29b4746d1aaa51ce46/lief-1.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:23253bbc154ff0dc5253a8929a2a407d11d459694c409d053b93308e623125ff", size = 3349507, upload-time = "2026-07-12T14:11:03.309Z" }, + { url = "https://files.pythonhosted.org/packages/63/96/c7d4ea1e4f43f53be57d979244bd6426aa94b059d1f3cebd8bcc46bf6222/lief-1.0.0-cp314-cp314t-macosx_11_0_x86_64.whl", hash = "sha256:ecd440475e677c6834af996d34a2babbad1af6a3addaaa3822fd021972c41311", size = 3432213, upload-time = "2026-07-12T14:11:05.041Z" }, + { url = "https://files.pythonhosted.org/packages/13/4d/58f8947e7459c2089abb03d6f63b9c12a5a9e103fed571ac43869ef8313d/lief-1.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:0e4c0934c27bea29752bdac494c2611c676d27d54139c96098f57b22d065deeb", size = 3664092, upload-time = "2026-07-12T14:11:06.62Z" }, + { url = "https://files.pythonhosted.org/packages/3c/1e/679f32b5ffee1d370358d5e94c030d047b409873489d2049365c15356d04/lief-1.0.0-cp314-cp314t-manylinux_2_28_i686.whl", hash = "sha256:4d2f1565110abc06070c0f6dcababab64606721fd1401477857558d9575ad663", size = 3805718, upload-time = "2026-07-12T14:11:08.336Z" }, + { url = "https://files.pythonhosted.org/packages/c7/05/f65b1ab1eb0e345dbbad62407ba9f8d82acf19268b8c1aff9e5355f5e7ca/lief-1.0.0-cp314-cp314t-manylinux_2_28_riscv64.whl", hash = "sha256:25ea4a80545eb4d1ffe75f49fceca526ce85130bd263bcd81a0fa66178ab1e7f", size = 3750775, upload-time = "2026-07-12T14:11:10.312Z" }, + { url = "https://files.pythonhosted.org/packages/8c/85/02e39735843ed44572126575deda5c9ebcb614412132afeeba5b8a2a3ed4/lief-1.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:18b05ce0244be151c58fedbd8b08687ed69713533cab9af23060a73f4441e847", size = 3731535, upload-time = "2026-07-12T14:11:12.064Z" }, + { url = "https://files.pythonhosted.org/packages/64/45/0664acd97c955380cf40f1ae00f33cc6f4e01373cde4782986d54d17aac7/lief-1.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:26777c1ec1ac55d3b981cad0fdb61d38de21da4b83810d637a5f4d0190470bf6", size = 3975553, upload-time = "2026-07-12T14:11:13.868Z" }, + { url = "https://files.pythonhosted.org/packages/be/ee/4a3ee9db6cba043a5579f939ffacda1c7825f49907221eae911358982aae/lief-1.0.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:5881e7698fb9b7ea6398dc86db78c6ae65331d7473c713d5a24318e264048334", size = 4250798, upload-time = "2026-07-12T14:11:15.617Z" }, + { url = "https://files.pythonhosted.org/packages/fb/80/86ecc653817067d945ef92577a58d27aa359b9f2038c69e457b710b1560a/lief-1.0.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:6be55884009b1eea2314c6d918a945c8bc72584928957771956b600fdcecaa19", size = 4029644, upload-time = "2026-07-12T14:11:17.164Z" }, + { url = "https://files.pythonhosted.org/packages/c4/af/cd42f2569b35af9744d2832f0f9698a73ed5b8aebfc5056dab69b0c2732a/lief-1.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f12816bb3d4781fdc98db4df312a8da744c5a93f587fa4919124fcb9b277d510", size = 4027250, upload-time = "2026-07-12T14:11:19.333Z" }, + { url = "https://files.pythonhosted.org/packages/0b/4d/0797e4e048179c31400322a2765a30f9dd11d1c968b829578b909452566f/lief-1.0.0-cp314-cp314t-win32.whl", hash = "sha256:b5f954b86f6c99437a461ed794bbc2d5e003e6a24e462b49f4978bce228b3801", size = 3787154, upload-time = "2026-07-12T14:22:44.99Z" }, + { url = "https://files.pythonhosted.org/packages/13/51/b80054950752fd581c60f9c01fbca3f700a3fdd47307d0f6ae19714bb550/lief-1.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:4680aeaa0eb9f21540f37ab5f97820fdf8f08b9c67c42b4435e232ca8cc22a27", size = 4073853, upload-time = "2026-07-12T14:11:21.286Z" }, + { url = "https://files.pythonhosted.org/packages/03/c5/3e8dab85764e5eafa8812ef5914acde47981d01c131084bcbdda9893c449/lief-1.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:7677a7b8fffd4de096d7ca1db64d1a6c3007e02650ed256fb93b2f3f9ea74097", size = 3804579, upload-time = "2026-07-12T14:11:23.349Z" }, + { url = "https://files.pythonhosted.org/packages/08/43/760246b541ccb5e8c30195ad8a2870ba00a37fb010585d6a63a6aac8ad91/lief-1.0.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:47c60ba68c3a1f53d872bb004a4e7d2a6f2572372d79a362fa3bd3369f5b8945", size = 3349476, upload-time = "2026-07-12T14:11:25.766Z" }, + { url = "https://files.pythonhosted.org/packages/da/2d/d0800b3f0aceb65388a236628c20e58d781abe71a17448307e8746b0c11f/lief-1.0.0-cp315-cp315t-macosx_11_0_x86_64.whl", hash = "sha256:caad33b4fe1eebf8d18acac3a8e2bbfc10f89706f7555e459e6d2588eb8f80fd", size = 3432749, upload-time = "2026-07-12T14:11:27.823Z" }, + { url = "https://files.pythonhosted.org/packages/b6/16/3e10313c41726a2a72beb6b9e63d20537f18cf1b1509a31d0b4e58169272/lief-1.0.0-cp315-cp315t-manylinux_2_28_aarch64.whl", hash = "sha256:23f42c7f4ae2df5492eb3a4ed449a2ae16bec107d9baf987bd618fde1ce53564", size = 3663917, upload-time = "2026-07-12T14:11:29.574Z" }, + { url = "https://files.pythonhosted.org/packages/24/31/12545f5a978e9018d95d6f8ccc97253ddffeb5d54101cc02f3c92a9f339a/lief-1.0.0-cp315-cp315t-manylinux_2_28_i686.whl", hash = "sha256:980aeaff59734b48927b3f9a2915c7d834c16d75d9a36a581e4f0dbd082481a8", size = 3805856, upload-time = "2026-07-12T14:11:31.498Z" }, + { url = "https://files.pythonhosted.org/packages/b9/eb/6541a331c98e490381818ae461e3a02ae12f033661b9f41887b76e09d702/lief-1.0.0-cp315-cp315t-manylinux_2_28_riscv64.whl", hash = "sha256:6a02dcd93c9dba14d3f007bc3a2a84ebf2706b704a5ab32ea6bf71987d4a9f5b", size = 3750666, upload-time = "2026-07-12T14:11:33.565Z" }, + { url = "https://files.pythonhosted.org/packages/ac/98/b8c18c255e66845ae60dbec0df6fdb38a0d7f07518c7be73f1b3d38b50dd/lief-1.0.0-cp315-cp315t-manylinux_2_28_x86_64.whl", hash = "sha256:fcaf9a28f004bc5f49637dd1a5cdfb8f937feb58febb5f70ebec29c0c1c3584c", size = 3731457, upload-time = "2026-07-12T14:11:36.2Z" }, + { url = "https://files.pythonhosted.org/packages/7b/4a/d8f2eb1f1ad1541fdb0c1508f610b49e8edb7dd39b74a53e882675e36da6/lief-1.0.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:4e6ae6b3bfd4bc4b2f8a805d0dc74b00de9da173d9a4b2bd581d774bb2cdd19d", size = 3975439, upload-time = "2026-07-12T14:11:37.962Z" }, + { url = "https://files.pythonhosted.org/packages/5e/74/a33c39eace7d326641ba058edc98c4c9045ef02e43a75002663707db0613/lief-1.0.0-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:2ee72db426d304a37d7bcfe246de3ea1e524ff95104c39f132b88835e6408fa6", size = 4250339, upload-time = "2026-07-12T14:11:39.695Z" }, + { url = "https://files.pythonhosted.org/packages/76/88/997c8880adf63e116d2eddf2062fe517baed454a154a3d49b149776033d5/lief-1.0.0-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:0628dea883631d33a84498e79c96e9cffff24ed898f9204d139ab1a51e079478", size = 4029632, upload-time = "2026-07-12T14:11:42.178Z" }, + { url = "https://files.pythonhosted.org/packages/cd/5a/8592eba660355fa299919f7aef4c18dad330d1172b2303d3f0a59ac82409/lief-1.0.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:5f7f187745c81a81231d9785bed73bae90f495531c5ea40449370e37441b45a2", size = 4027501, upload-time = "2026-07-12T14:11:43.979Z" }, + { url = "https://files.pythonhosted.org/packages/46/72/2755e9afde286bef1a1501b02a1025487bcac0ad857be6e24f8ab22d5ab9/lief-1.0.0-cp315-cp315t-win32.whl", hash = "sha256:7a9c376fd607a9480777d0928ae37fd48547937b3a54bb5d130512061e5e953c", size = 3787315, upload-time = "2026-07-12T14:22:46.611Z" }, + { url = "https://files.pythonhosted.org/packages/b8/46/bd2e04e3b8afa0a7068d80218add90ebb9a4b90fbad60987312d934d7a9f/lief-1.0.0-cp315-cp315t-win_amd64.whl", hash = "sha256:4d49b2fa555163692dbecba147a55847abf641fee3c6d72315db14d084b4a160", size = 4073797, upload-time = "2026-07-12T14:11:45.671Z" }, + { url = "https://files.pythonhosted.org/packages/d1/ce/dea3c1f1a2c04b6de4a8040bd16c5a081d06db8ea18e15dc715988b8df58/lief-1.0.0-cp315-cp315t-win_arm64.whl", hash = "sha256:580e786d72fc34a0402b0af66ed755e668293946705b8193b766c501f00bc448", size = 3804488, upload-time = "2026-07-12T14:11:47.346Z" }, +] + [[package]] name = "markdown" version = "3.10.3"