├── .cargo └── config ├── .github ├── dependabot.yml └── workflows │ ├── r10e-cross-rs-build.yml │ └── r10e-rust-overlay-build.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── Makefile ├── README.md ├── nix-cross-rs ├── Cargo.lock ├── Cargo.toml ├── Cross.toml ├── Dockerfile ├── Makefile ├── README.md ├── nixbuild.sh ├── run.sh ├── rust-toolchain ├── shell.nix └── src │ └── main.rs ├── nix-rust-overlay ├── Dockerfile ├── Makefile ├── README.md ├── musl-1.1.24.patch ├── run.sh ├── shell-aarch64.nix ├── shell-armv6.nix ├── shell-armv7.nix ├── shell-i686.nix ├── shell-x86_64-win.nix └── shell-x86_64.nix ├── nix.conf └── src └── main.rs /.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "x86_64-unknown-linux-musl" 3 | 4 | [target.x86_64-unknown-linux-musl] 5 | rustflags = [ "-C", "target-feature=+crt-static", 6 | "-C", "link-arg=-lgcc" ] -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "cargo" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | # Cf. https://en.wikipedia.org/wiki/List_of_tz_database_time_zones 8 | timezone: "Etc/GMT" 9 | time: "11:42" 10 | # Disable version updates for cargo dependencies 11 | open-pull-requests-limit: 0 -------------------------------------------------------------------------------- /.github/workflows/r10e-cross-rs-build.yml: -------------------------------------------------------------------------------- 1 | # Possibly reproducible build with cross-rs and Nix 2 | name: "Reproducible build with cross-rs" 3 | 4 | on: 5 | push: 6 | paths-ignore: 7 | - 'nix-rust-overlay/**' 8 | branches: 9 | - 'main' 10 | pull_request: 11 | paths-ignore: 12 | - 'nix-rust-overlay/**' 13 | branches: 14 | - 'main' 15 | 16 | jobs: 17 | nix-cross-rs-build: 18 | name: "r10e cross-rs build" 19 | strategy: 20 | fail-fast: false 21 | matrix: 22 | os: [ubuntu-latest] 23 | runs-on: ${{ matrix.os }} 24 | steps: 25 | - name: Checkout repository 26 | uses: actions/checkout@v4.1.1 27 | - name: Cross build artifacts 28 | run: | 29 | cd ${{ github.workspace }} 30 | make cross-rs 31 | -------------------------------------------------------------------------------- /.github/workflows/r10e-rust-overlay-build.yml: -------------------------------------------------------------------------------- 1 | # Possibly reproducible build with Nix rust-overlay 2 | name: "Reproducible build with rust-overlay" 3 | 4 | on: 5 | push: 6 | paths-ignore: 7 | - 'nix-cross-rs/**' 8 | branches: 9 | - 'main' 10 | pull_request: 11 | paths-ignore: 12 | - 'nix-cross-rs/**' 13 | branches: 14 | - 'main' 15 | 16 | jobs: 17 | nix-cross-rs-build: 18 | name: "r10e rust-overlay build" 19 | strategy: 20 | fail-fast: false 21 | matrix: 22 | os: [ubuntu-latest] 23 | runs-on: ${{ matrix.os }} 24 | steps: 25 | - name: Checkout repository 26 | uses: actions/checkout@v4.1.1 27 | - name: Cross build artifacts 28 | run: | 29 | cd ${{ github.workspace }} 30 | make rust-overlay 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "bitflags" 7 | version = "2.9.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" 10 | 11 | [[package]] 12 | name = "cc" 13 | version = "1.2.16" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" 16 | dependencies = [ 17 | "jobserver", 18 | "libc", 19 | "shlex", 20 | ] 21 | 22 | [[package]] 23 | name = "cfg-if" 24 | version = "1.0.0" 25 | source = "registry+https://github.com/rust-lang/crates.io-index" 26 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 27 | 28 | [[package]] 29 | name = "foreign-types" 30 | version = "0.3.2" 31 | source = "registry+https://github.com/rust-lang/crates.io-index" 32 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 33 | dependencies = [ 34 | "foreign-types-shared", 35 | ] 36 | 37 | [[package]] 38 | name = "foreign-types-shared" 39 | version = "0.1.1" 40 | source = "registry+https://github.com/rust-lang/crates.io-index" 41 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 42 | 43 | [[package]] 44 | name = "fuchsia-cprng" 45 | version = "0.1.1" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 48 | 49 | [[package]] 50 | name = "hello-random" 51 | version = "0.1.0" 52 | dependencies = [ 53 | "openssl", 54 | "rand 0.3.23", 55 | "zstd", 56 | ] 57 | 58 | [[package]] 59 | name = "jobserver" 60 | version = "0.1.32" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" 63 | dependencies = [ 64 | "libc", 65 | ] 66 | 67 | [[package]] 68 | name = "libc" 69 | version = "0.2.171" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" 72 | 73 | [[package]] 74 | name = "once_cell" 75 | version = "1.21.1" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" 78 | 79 | [[package]] 80 | name = "openssl" 81 | version = "0.10.72" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" 84 | dependencies = [ 85 | "bitflags", 86 | "cfg-if", 87 | "foreign-types", 88 | "libc", 89 | "once_cell", 90 | "openssl-macros", 91 | "openssl-sys", 92 | ] 93 | 94 | [[package]] 95 | name = "openssl-macros" 96 | version = "0.1.1" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 99 | dependencies = [ 100 | "proc-macro2", 101 | "quote", 102 | "syn", 103 | ] 104 | 105 | [[package]] 106 | name = "openssl-sys" 107 | version = "0.9.108" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | checksum = "e145e1651e858e820e4860f7b9c5e169bc1d8ce1c86043be79fa7b7634821847" 110 | dependencies = [ 111 | "cc", 112 | "libc", 113 | "pkg-config", 114 | "vcpkg", 115 | ] 116 | 117 | [[package]] 118 | name = "pkg-config" 119 | version = "0.3.32" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" 122 | 123 | [[package]] 124 | name = "proc-macro2" 125 | version = "1.0.94" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" 128 | dependencies = [ 129 | "unicode-ident", 130 | ] 131 | 132 | [[package]] 133 | name = "quote" 134 | version = "1.0.40" 135 | source = "registry+https://github.com/rust-lang/crates.io-index" 136 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 137 | dependencies = [ 138 | "proc-macro2", 139 | ] 140 | 141 | [[package]] 142 | name = "rand" 143 | version = "0.3.23" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" 146 | dependencies = [ 147 | "libc", 148 | "rand 0.4.6", 149 | ] 150 | 151 | [[package]] 152 | name = "rand" 153 | version = "0.4.6" 154 | source = "registry+https://github.com/rust-lang/crates.io-index" 155 | checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" 156 | dependencies = [ 157 | "fuchsia-cprng", 158 | "libc", 159 | "rand_core 0.3.1", 160 | "rdrand", 161 | "winapi", 162 | ] 163 | 164 | [[package]] 165 | name = "rand_core" 166 | version = "0.3.1" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 169 | dependencies = [ 170 | "rand_core 0.4.2", 171 | ] 172 | 173 | [[package]] 174 | name = "rand_core" 175 | version = "0.4.2" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" 178 | 179 | [[package]] 180 | name = "rdrand" 181 | version = "0.4.0" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 184 | dependencies = [ 185 | "rand_core 0.3.1", 186 | ] 187 | 188 | [[package]] 189 | name = "shlex" 190 | version = "1.3.0" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 193 | 194 | [[package]] 195 | name = "syn" 196 | version = "2.0.100" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" 199 | dependencies = [ 200 | "proc-macro2", 201 | "quote", 202 | "unicode-ident", 203 | ] 204 | 205 | [[package]] 206 | name = "unicode-ident" 207 | version = "1.0.18" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 210 | 211 | [[package]] 212 | name = "vcpkg" 213 | version = "0.2.15" 214 | source = "registry+https://github.com/rust-lang/crates.io-index" 215 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 216 | 217 | [[package]] 218 | name = "winapi" 219 | version = "0.3.9" 220 | source = "registry+https://github.com/rust-lang/crates.io-index" 221 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 222 | dependencies = [ 223 | "winapi-i686-pc-windows-gnu", 224 | "winapi-x86_64-pc-windows-gnu", 225 | ] 226 | 227 | [[package]] 228 | name = "winapi-i686-pc-windows-gnu" 229 | version = "0.4.0" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 232 | 233 | [[package]] 234 | name = "winapi-x86_64-pc-windows-gnu" 235 | version = "0.4.0" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 238 | 239 | [[package]] 240 | name = "zstd" 241 | version = "0.11.2+zstd.1.5.2" 242 | source = "git+https://github.com/syncom/zstd-rs?rev=abbc3b6a21c9825243933cbb6778781608db56dc#abbc3b6a21c9825243933cbb6778781608db56dc" 243 | dependencies = [ 244 | "zstd-safe", 245 | ] 246 | 247 | [[package]] 248 | name = "zstd-safe" 249 | version = "5.0.2+zstd.1.5.2" 250 | source = "git+https://github.com/syncom/zstd-rs?rev=abbc3b6a21c9825243933cbb6778781608db56dc#abbc3b6a21c9825243933cbb6778781608db56dc" 251 | dependencies = [ 252 | "libc", 253 | "zstd-sys", 254 | ] 255 | 256 | [[package]] 257 | name = "zstd-sys" 258 | version = "2.0.1+zstd.1.5.2" 259 | source = "git+https://github.com/syncom/zstd-rs?rev=abbc3b6a21c9825243933cbb6778781608db56dc#abbc3b6a21c9825243933cbb6778781608db56dc" 260 | dependencies = [ 261 | "cc", 262 | "libc", 263 | ] 264 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello-random" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | [dependencies] 8 | rand = "0.3.14" 9 | # The following commit breaks cross builds 10 | #zstd = { git = "https://github.com/gyscos/zstd-rs", rev ="f0d8a12f0f520095cf26a0dac35b8d0939277add" } 11 | # The following commit results in a successful build, which reverts the above commit 12 | zstd = { git = "https://github.com/syncom/zstd-rs", rev ="abbc3b6a21c9825243933cbb6778781608db56dc" } 13 | [target.'cfg(unix)'.dependencies] 14 | openssl = "0.10.72" 15 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) 2 | mkfile_dir := $(dir $(mkfile_path)) 3 | 4 | .PHONY: cross-rs rust-overlay cr-clean ro-clean clean 5 | 6 | all: cross-rs rust-overlay 7 | 8 | cross-rs: 9 | make -C $(mkfile_dir)/nix-cross-rs 10 | 11 | cr-clean: 12 | make -C $(mkfile_dir)/nix-cross-rs clean 13 | 14 | rust-overlay: 15 | make -C $(mkfile_dir)/nix-rust-overlay r10e-build 16 | 17 | ro-clean: 18 | make -C $(mkfile_dir)/nix-rust-overlay clean 19 | 20 | clean: cr-clean ro-clean 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Reproducible, Statically Linked Rust Cross Builds in Nix 2 | 3 | [![cross-rs builds](https://github.com/syncom/rust-cross-build-nix/actions/workflows/r10e-cross-rs-build.yml/badge.svg)](https://github.com/syncom/rust-cross-build-nix/actions/workflows/r10e-cross-rs-build.yml) 4 | [![rusto-overlay builds](https://github.com/syncom/rust-cross-build-nix/actions/workflows/r10e-rust-overlay-build.yml/badge.svg)](https://github.com/syncom/rust-cross-build-nix/actions/workflows/r10e-rust-overlay-build.yml) 5 | 6 | This repository demonstrates "one-click" ways of cross building Rust 7 | code, deterministically. We use Nix to do the builds, and the artifacts 8 | are bit-for-bit reproducible. The examples also statically link against 9 | `musl` libc, because static linking is trickier to do, and because we 10 | can. 11 | 12 | You need Docker for building the examples. 13 | 14 | ## Approach 1 15 | 16 | [nix-cross-rs](./nix-cross-rs/) 17 | 18 | - This approach uses [cross-rs/cross](https://github.com/cross-rs/cross), 19 | managed by Nix, for the cross builds. It requires running a container engine 20 | (`podman`) inside a Docker container, and privileged access permissions. 21 | Compared to the second approach, this one is less "pure" and conceptually more 22 | complex. Hence this approach is less preferred. 23 | 24 | ## Approach 2 25 | 26 | [nix-rust-overlay](./nix-rust-overlay/) 27 | 28 | - This approach is "pure", in that it uses Nix to manage dependencies entirely. 29 | - It demonstrates how to statically link to `openssl` for the `unix` target family. 30 | - It demonstrates cross builds on a `windows` target (without `openssl` static 31 | linking, for simplicity). 32 | 33 | ## How to Build Using Both Approaches 34 | 35 | In the directory root of the repository 36 | 37 | ```bash 38 | make 39 | ``` 40 | 41 | Or for either approach 42 | 43 | ```bash 44 | # Approach 1 45 | make cross-rs 46 | # Approach 2 47 | make rust-overlay 48 | ``` 49 | 50 | Clean up with command 51 | 52 | ```bash 53 | make clean 54 | ``` 55 | 56 | Or for either approach 57 | 58 | ```bash 59 | # Approach 1 60 | make cr-clean 61 | # Approach 2 62 | make ro-clean 63 | ``` 64 | -------------------------------------------------------------------------------- /nix-cross-rs/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "cc" 7 | version = "1.0.73" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 10 | dependencies = [ 11 | "jobserver", 12 | ] 13 | 14 | [[package]] 15 | name = "fuchsia-cprng" 16 | version = "0.1.1" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 19 | 20 | [[package]] 21 | name = "hello-random" 22 | version = "0.1.0" 23 | dependencies = [ 24 | "rand 0.3.23", 25 | "zstd", 26 | ] 27 | 28 | [[package]] 29 | name = "jobserver" 30 | version = "0.1.24" 31 | source = "registry+https://github.com/rust-lang/crates.io-index" 32 | checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" 33 | dependencies = [ 34 | "libc", 35 | ] 36 | 37 | [[package]] 38 | name = "libc" 39 | version = "0.2.132" 40 | source = "registry+https://github.com/rust-lang/crates.io-index" 41 | checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" 42 | 43 | [[package]] 44 | name = "rand" 45 | version = "0.3.23" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" 48 | dependencies = [ 49 | "libc", 50 | "rand 0.4.6", 51 | ] 52 | 53 | [[package]] 54 | name = "rand" 55 | version = "0.4.6" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" 58 | dependencies = [ 59 | "fuchsia-cprng", 60 | "libc", 61 | "rand_core 0.3.1", 62 | "rdrand", 63 | "winapi", 64 | ] 65 | 66 | [[package]] 67 | name = "rand_core" 68 | version = "0.3.1" 69 | source = "registry+https://github.com/rust-lang/crates.io-index" 70 | checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 71 | dependencies = [ 72 | "rand_core 0.4.2", 73 | ] 74 | 75 | [[package]] 76 | name = "rand_core" 77 | version = "0.4.2" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" 80 | 81 | [[package]] 82 | name = "rdrand" 83 | version = "0.4.0" 84 | source = "registry+https://github.com/rust-lang/crates.io-index" 85 | checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 86 | dependencies = [ 87 | "rand_core 0.3.1", 88 | ] 89 | 90 | [[package]] 91 | name = "winapi" 92 | version = "0.3.9" 93 | source = "registry+https://github.com/rust-lang/crates.io-index" 94 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 95 | dependencies = [ 96 | "winapi-i686-pc-windows-gnu", 97 | "winapi-x86_64-pc-windows-gnu", 98 | ] 99 | 100 | [[package]] 101 | name = "winapi-i686-pc-windows-gnu" 102 | version = "0.4.0" 103 | source = "registry+https://github.com/rust-lang/crates.io-index" 104 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 105 | 106 | [[package]] 107 | name = "winapi-x86_64-pc-windows-gnu" 108 | version = "0.4.0" 109 | source = "registry+https://github.com/rust-lang/crates.io-index" 110 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 111 | 112 | [[package]] 113 | name = "zstd" 114 | version = "0.11.2+zstd.1.5.2" 115 | source = "git+https://github.com/syncom/zstd-rs?rev=abbc3b6a21c9825243933cbb6778781608db56dc#abbc3b6a21c9825243933cbb6778781608db56dc" 116 | dependencies = [ 117 | "zstd-safe", 118 | ] 119 | 120 | [[package]] 121 | name = "zstd-safe" 122 | version = "5.0.2+zstd.1.5.2" 123 | source = "git+https://github.com/syncom/zstd-rs?rev=abbc3b6a21c9825243933cbb6778781608db56dc#abbc3b6a21c9825243933cbb6778781608db56dc" 124 | dependencies = [ 125 | "libc", 126 | "zstd-sys", 127 | ] 128 | 129 | [[package]] 130 | name = "zstd-sys" 131 | version = "2.0.1+zstd.1.5.2" 132 | source = "git+https://github.com/syncom/zstd-rs?rev=abbc3b6a21c9825243933cbb6778781608db56dc#abbc3b6a21c9825243933cbb6778781608db56dc" 133 | dependencies = [ 134 | "cc", 135 | "libc", 136 | ] 137 | -------------------------------------------------------------------------------- /nix-cross-rs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello-random" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | [dependencies] 8 | rand = "0.7.0" 9 | # The following commit breaks cross builds 10 | #zstd = { git = "https://github.com/gyscos/zstd-rs", rev ="f0d8a12f0f520095cf26a0dac35b8d0939277add" } 11 | # The following commit results in a successful build, which reverts the above commit 12 | zstd = { git = "https://github.com/syncom/zstd-rs", rev ="abbc3b6a21c9825243933cbb6778781608db56dc" } 13 | openssl = { version = "0.10.72", features = ["vendored"] } -------------------------------------------------------------------------------- /nix-cross-rs/Cross.toml: -------------------------------------------------------------------------------- 1 | [build.env] 2 | passthrough = [ 3 | "RUSTFLAGS", 4 | ] 5 | 6 | [target.x86_64-unknown-linux-musl] 7 | # v0.2.4 8 | image = "ghcr.io/cross-rs/x86_64-unknown-linux-musl@sha256:79e3cf3994f70c6a318f003a94313d1b13a4de564e37998f9b0f7b1943153cf7" 9 | 10 | [target.armv7-unknown-linux-musleabihf] 11 | # v0.2.4 12 | image = "ghcr.io/cross-rs/armv7-unknown-linux-musleabihf@sha256:dd17a0ad95a3fce9c15230f60f8ed3bf6e60d81de260fbb9e457e4a49de8a43a" 13 | 14 | [target.arm-unknown-linux-musleabihf] 15 | # 0.2.4 16 | image = "ghcr.io/cross-rs/arm-unknown-linux-musleabihf@sha256:35209e76c3fa59a8330c4241c2c9ffb91ae29a211890b050923a82e0739f3ed1" 17 | 18 | [target.aarch64-unknown-linux-musl] 19 | # 0.2.4 20 | image = "ghcr.io/cross-rs/aarch64-unknown-linux-musl@sha256:bc51668f05f063030234df49145267791963a6c36d1e858b61c86654859c369c" -------------------------------------------------------------------------------- /nix-cross-rs/Dockerfile: -------------------------------------------------------------------------------- 1 | # The following information is from https://hub.docker.com/r/nixos/nix/tags 2 | FROM nixos/nix:2.9.0@sha256:13b257cd42db29dc851f9818ea1bc2f9c7128c51fdf000971fa6058c66fbe4b6 as cross-rs_builder 3 | 4 | ############################################################ 5 | # Step 1: Prepare nixpkgs and cross for deterministic builds 6 | ############################################################ 7 | WORKDIR /build 8 | # Custom project name 9 | ENV RUST_PROJECT_NAME="rust-cross-build-nix" 10 | 11 | # 22.05 12 | #ENV NIXPKGS_COMMIT_SHA="ce6aa13369b667ac2542593170993504932eb836" 13 | # This version has podman 4.2.0, which contains bugfix 14 | # https://github.com/containers/podman/pull/14787 15 | ENV NIXPKGS_COMMIT_SHA="692574660e1f1e397b6e48065c931e8758c5ad16" 16 | # 0.2.4 17 | ENV CROSS_COMMIT_SHA="4645d937bdae6952d9df38eff3ecb91fd719c3bd" 18 | 19 | # Apple M1 workaround 20 | COPY nix.conf /build/nix.conf 21 | ENV NIX_USER_CONF_FILES=/build/nix.conf 22 | 23 | RUN nix-env --option filter-syscalls false -i git gnused && \ 24 | mkdir -p /build/nixpkgs && \ 25 | cd nixpkgs && \ 26 | git init && \ 27 | git remote add origin https://github.com/NixOS/nixpkgs.git && \ 28 | git fetch --depth 1 origin ${NIXPKGS_COMMIT_SHA} && \ 29 | git checkout FETCH_HEAD && \ 30 | cd .. && \ 31 | mkdir -p /build/cross && \ 32 | git clone https://github.com/cross-rs/cross.git && \ 33 | cd cross && \ 34 | git checkout ${CROSS_COMMIT_SHA} && \ 35 | cd .. && \ 36 | mkdir -p /build/.cargo && \ 37 | mkdir -p /build/.rustup && \ 38 | mkdir -p /build/${RUST_PROJECT_NAME} 39 | 40 | ENV NIX_PATH=nixpkgs=/build/nixpkgs 41 | ENV RUSTC_VERSION=1.63.0 42 | ENV CARGO_HOME="/build/.cargo" 43 | ENV RUSTUP_HOME="/build/.rustup" 44 | ENV PATH="${CARGO_HOME}/bin:${RUSTUP_HOME}/toolchains/${RUSTC_VERSION}-x86_64-unknown-linux-gnu/bin:${PATH}" 45 | 46 | ######################################################### 47 | # Step 2: Prepare Rust project 48 | ######################################################### 49 | COPY nix-cross-rs/src /build/${RUST_PROJECT_NAME}/src 50 | COPY nix-cross-rs/Cargo.toml /build/${RUST_PROJECT_NAME}/Cargo.toml 51 | COPY nix-cross-rs/Cross.toml /build/${RUST_PROJECT_NAME}/Cross.toml 52 | COPY nix-cross-rs/Cargo.lock /build/${RUST_PROJECT_NAME}/Cargo.lock 53 | COPY nix-cross-rs/rust-toolchain /build/${RUST_PROJECT_NAME}/rust-toolchain 54 | COPY nix-cross-rs/nixbuild.sh /build/${RUST_PROJECT_NAME}/nixbuild.sh 55 | COPY nix-cross-rs/shell.nix /build/${RUST_PROJECT_NAME}/shell.nix 56 | 57 | # String substitution 58 | RUN sed -i "s/RUST_PROJECT_NAME/${RUST_PROJECT_NAME}/g" /build/${RUST_PROJECT_NAME}/nixbuild.sh 59 | 60 | ENTRYPOINT [ "/bin/sh", "-c", "exec /build/${RUST_PROJECT_NAME}/nixbuild.sh" ] 61 | -------------------------------------------------------------------------------- /nix-cross-rs/Makefile: -------------------------------------------------------------------------------- 1 | mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) 2 | mkfile_dir := $(dir $(mkfile_path)) 3 | 4 | all: cross-build 5 | 6 | cross-build: 7 | $(mkfile_dir)/run.sh 8 | 9 | clean: 10 | rm -rf $(mkfile_dir)/out 11 | -------------------------------------------------------------------------------- /nix-cross-rs/README.md: -------------------------------------------------------------------------------- 1 | # Reproducible Rust Cross Builds with cross-rs 2 | 3 | This approach to deterministically building statically linked Rust binaries is 4 | based on [cross](https://github.com/cross-rs/cross) and 5 | [Nix](https://github.com/NixOS/nixpkgs), where the former does the heavy-lifting 6 | for cross-building, and the latter makes the builds reproducible. 7 | 8 | ## How to build 9 | 10 | In the directory root of the repository 11 | 12 | ```bash 13 | make cross-rs 14 | # `make cr-clean` to clean up 15 | ``` 16 | -------------------------------------------------------------------------------- /nix-cross-rs/nixbuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This script is to be invoked inside the container 3 | 4 | cd /build/RUST_PROJECT_NAME && \ 5 | nix-shell shell.nix \ 6 | --run "cd /build/RUST_PROJECT_NAME && \ 7 | rustup toolchain install $(cat rust-toolchain) && \ 8 | cargo install cross --git file:///build/cross && \ 9 | mkdir -p out && \ 10 | CROSS_CONTAINER_ENGINE=podman cross build --release --target aarch64-unknown-linux-musl && \ 11 | cp target/aarch64-unknown-linux-musl/release/hello-random out/hello-random-aarch64-linux && \ 12 | CROSS_CONTAINER_ENGINE=podman cross build --release --target armv7-unknown-linux-musleabihf && \ 13 | cp target/armv7-unknown-linux-musleabihf/release/hello-random out/hello-random-armv7-linux && \ 14 | CROSS_CONTAINER_ENGINE=podman cross build --release --target x86_64-unknown-linux-musl && \ 15 | cp target/x86_64-unknown-linux-musl/release/hello-random out/hello-random-x86_64-linux && \ 16 | CROSS_CONTAINER_ENGINE=podman cross build --release --target arm-unknown-linux-musleabihf && \ 17 | cp target/arm-unknown-linux-musleabihf/release/hello-random out/hello-random-arm-linux" 18 | -------------------------------------------------------------------------------- /nix-cross-rs/run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euxo pipefail 4 | 5 | SCRIPT_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 6 | OUT_DIR="${SCRIPT_DIR}/out" 7 | REVISION=$(git --work-tree="${SCRIPT_DIR}"/../ --git-dir="${SCRIPT_DIR}"/../.git \ 8 | rev-parse HEAD) 9 | BUILDER_TAG_NAME="cross-rs_builder:$REVISION" 10 | 11 | ######################################### 12 | # Self test 13 | ######################################### 14 | err() { 15 | echo -e "$*" 16 | exit 1 17 | } 18 | 19 | self_test() { 20 | # Check sha256sum 21 | command -v sha256sum &>/dev/null || \ 22 | err "sha256sum not found. Please install coreutils first" 23 | 24 | # Check docker 25 | docker info &>/dev/null || \ 26 | err "Make sure docker daemon is running" 27 | } 28 | 29 | # Let's go 30 | self_test 31 | 32 | echo "Creating builder container image..." 33 | # Need to run docker build in script's parent directory 34 | cd "${SCRIPT_DIR}/.." 35 | docker build --platform linux/amd64 -f "${SCRIPT_DIR}/Dockerfile" -t "${BUILDER_TAG_NAME}" . 36 | docker images "${BUILDER_TAG_NAME}" 37 | rm -rf "${OUT_DIR}" 38 | mkdir -p "${OUT_DIR}" 39 | 40 | echo "Cross building started..." 41 | docker run --platform linux/amd64 --privileged -v /var/lib/containers/storage -v "${OUT_DIR}":/build/rust-cross-build-nix/out --rm -i "${BUILDER_TAG_NAME}" 42 | 43 | echo 44 | echo "============ HELLO-RANDOM ARTIFACTS INFO ============" 45 | echo "Artifacts created in ${OUT_DIR}/" 46 | echo "sha256sums:" 47 | sha256sum "${OUT_DIR}"/hello-random* | sort -k2 48 | echo 49 | -------------------------------------------------------------------------------- /nix-cross-rs/rust-toolchain: -------------------------------------------------------------------------------- 1 | 1.85.0 2 | -------------------------------------------------------------------------------- /nix-cross-rs/shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import {} }: 2 | 3 | let 4 | 5 | # To use this shell.nix on NixOS your user needs to be configured as such: 6 | users.extraUsers.root = { 7 | subUidRanges = [{ startUid = 100000; count = 65536; }]; 8 | subGidRanges = [{ startGid = 100000; count = 65536; }]; 9 | }; 10 | 11 | # Provides a script that copies required files to ~/ 12 | podmanSetupScript = let 13 | registriesConf = pkgs.writeText "registries.conf" '' 14 | [registries.search] 15 | registries = ['docker.io'] 16 | 17 | [registries.block] 18 | registries = [] 19 | ''; 20 | in pkgs.writeScript "podman-setup" '' 21 | #!${pkgs.runtimeShell} 22 | 23 | # Dont overwrite customised configuration 24 | if ! test -f ~/.config/containers/policy.json; then 25 | install -Dm555 ${pkgs.skopeo.src}/default-policy.json ~/.config/containers/policy.json 26 | fi 27 | 28 | if ! test -f ~/.config/containers/registries.conf; then 29 | install -Dm555 ${registriesConf} ~/.config/containers/registries.conf 30 | fi 31 | ''; 32 | 33 | in pkgs.mkShell { 34 | 35 | buildInputs = [ 36 | pkgs.rustup 37 | pkgs.gcc 38 | pkgs.podman # Docker compat 39 | pkgs.runc # Container runtime 40 | pkgs.conmon # Container runtime monitor 41 | pkgs.skopeo # Interact with container registry 42 | pkgs.slirp4netns # User-mode networking for unprivileged namespaces 43 | pkgs.fuse-overlayfs # CoW for images, much faster than default vfs 44 | ]; 45 | 46 | shellHook = '' 47 | # Install required configuration 48 | ${podmanSetupScript} 49 | mkdir -p /opt/cni 50 | ln -s ${pkgs.cni-plugins}/bin /opt/cni/bin 51 | ''; 52 | 53 | } -------------------------------------------------------------------------------- /nix-cross-rs/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate rand; 2 | extern crate zstd; 3 | use std::io::Write; 4 | 5 | use rand::Rng; 6 | 7 | fn main() -> std::io::Result<()> { 8 | let rn = rand::thread_rng().gen_range(38, 45); 9 | println!("Hello, random: {}", rn); 10 | println!("ZSTD default compression level: {}", zstd::DEFAULT_COMPRESSION_LEVEL); 11 | 12 | let mut infile = std::fs::File::create("infile")?; 13 | let mut outfile = std::fs::OpenOptions::new().write(true).create(true).open("outfile")?; 14 | infile.write_all(b"Hello, random")?; 15 | let infile1 = std::fs::File::open("infile")?; 16 | zstd::stream::copy_encode(&infile1, &mut outfile, 0)?; 17 | 18 | Ok(()) 19 | } 20 | -------------------------------------------------------------------------------- /nix-rust-overlay/Dockerfile: -------------------------------------------------------------------------------- 1 | # The following information is from https://hub.docker.com/r/nixos/nix/tags 2 | FROM nixos/nix:2.9.0@sha256:13b257cd42db29dc851f9818ea1bc2f9c7128c51fdf000971fa6058c66fbe4b6 as rust-overlay_builder 3 | 4 | ################################################################### 5 | # Step 1: Prepare nixpkgs and rust-overlay for deterministic builds 6 | ################################################################### 7 | WORKDIR /build 8 | # Custom project name 9 | ENV RUST_PROJECT_NAME="rust-cross-build-nix" 10 | 11 | # nixpkgs 22.05 12 | ENV NIXPKGS_COMMIT_SHA="ce6aa13369b667ac2542593170993504932eb836" 13 | # rust-overlay version 20240502 with latest rust-bin.stable 1.78.0 14 | # Note that this is the previous commit of the problematic commit 15 | # 0bf05d8534406776a0fbc9ed8d4ef5bd925b056a that seemed to have introduced a 16 | # breaking change 17 | ENV RUST_OVERLAY_COMMIT_SHA="2e7ccf572ce0f0547d4cf4426de4482936882d0e" 18 | 19 | # Apple M1 workaround 20 | COPY nix.conf /build/nix.conf 21 | ENV NIX_USER_CONF_FILES=/build/nix.conf 22 | 23 | RUN nix-env -i git && \ 24 | mkdir -p /build/nixpkgs && \ 25 | cd nixpkgs && \ 26 | git init && \ 27 | git remote add origin https://github.com/NixOS/nixpkgs.git && \ 28 | git fetch --depth 1 origin ${NIXPKGS_COMMIT_SHA} && \ 29 | git checkout FETCH_HEAD && \ 30 | cd .. && \ 31 | git clone https://github.com/oxalica/rust-overlay.git && \ 32 | cd rust-overlay && \ 33 | git checkout ${RUST_OVERLAY_COMMIT_SHA} && \ 34 | cd .. && \ 35 | mkdir -p /build/${RUST_PROJECT_NAME}/out 36 | 37 | ENV NIX_PATH=nixpkgs=/build/nixpkgs:rust-overlay=/build/rust-overlay 38 | 39 | ######################################################### 40 | # Step 2: Prepare Nix Shells for Caching 41 | ######################################################### 42 | COPY nix-rust-overlay/shell-x86_64-win.nix /build/${RUST_PROJECT_NAME}/shell-x86_64-win.nix 43 | COPY nix-rust-overlay/shell-x86_64.nix /build/${RUST_PROJECT_NAME}/shell-x86_64.nix 44 | COPY nix-rust-overlay/shell-i686.nix /build/${RUST_PROJECT_NAME}/shell-i686.nix 45 | COPY nix-rust-overlay/shell-aarch64.nix /build/${RUST_PROJECT_NAME}/shell-aarch64.nix 46 | COPY nix-rust-overlay/shell-armv7.nix /build/${RUST_PROJECT_NAME}/shell-armv7.nix 47 | COPY nix-rust-overlay/shell-armv6.nix /build/${RUST_PROJECT_NAME}/shell-armv6.nix 48 | # Copy patch for musl-1.1.24 49 | COPY nix-rust-overlay/musl-1.1.24.patch /build/musl-1.1.24.patch 50 | 51 | # Warm up the cache layers 52 | RUN cd /build/${RUST_PROJECT_NAME} && \ 53 | nix-shell shell-x86_64-win.nix 54 | RUN cd /build/${RUST_PROJECT_NAME} && \ 55 | nix-shell shell-x86_64.nix 56 | RUN cd /build/${RUST_PROJECT_NAME} && \ 57 | nix-shell shell-aarch64.nix 58 | # Use musl-1.1.24 for 32-bit platforms, to work around a cross building issue 59 | # similar to the one discussed in 60 | # https://stackoverflow.com/questions/61934997/undefined-reference-to-stat-time64-when-cross-compiling-rust-project-on-mu 61 | RUN cd /build/nixpkgs && git apply /build/musl-1.1.24.patch 62 | RUN cd /build/${RUST_PROJECT_NAME} && \ 63 | nix-shell shell-armv6.nix 64 | RUN cd /build/${RUST_PROJECT_NAME} && \ 65 | nix-shell shell-armv7.nix 66 | RUN cd /build/${RUST_PROJECT_NAME} && \ 67 | nix-shell shell-i686.nix 68 | 69 | ######################################################### 70 | # Step 3: Cross builds for various targets 71 | ######################################################### 72 | COPY src /build/${RUST_PROJECT_NAME}/src 73 | COPY Cargo.toml /build/${RUST_PROJECT_NAME}/Cargo.toml 74 | COPY Cargo.lock /build/${RUST_PROJECT_NAME}/Cargo.lock 75 | COPY nix-rust-overlay/Makefile /build/${RUST_PROJECT_NAME}/Makefile 76 | 77 | # Revert the musl-1.1.24 patch because we don't need it for 64-bit platforms 78 | RUN cd /build/nixpkgs && git apply -R /build/musl-1.1.24.patch 79 | RUN cd /build/${RUST_PROJECT_NAME} && \ 80 | nix-shell shell-x86_64-win.nix --show-trace \ 81 | --run "TARGET=x86_64-pc-windows-gnu make && \ 82 | TARGET=x86_64-pc-windows-gnu make run" && \ 83 | # echo to NOP qemu commands to get around issue on Apple M1 84 | nix-shell shell-x86_64.nix \ 85 | --run "TARGET=x86_64-unknown-linux-musl make && \ 86 | echo TARGET=x86_64-unknown-linux-musl make run" && \ 87 | nix-shell shell-aarch64.nix \ 88 | --run "TARGET=aarch64-unknown-linux-musl make && \ 89 | echo TARGET=aarch64-unknown-linux-musl make run" 90 | # Re-apply the musl-1.1.24 patch for 32-bit platforms 91 | RUN cd /build/nixpkgs && git apply /build/musl-1.1.24.patch 92 | RUN cd /build/${RUST_PROJECT_NAME} && \ 93 | nix-shell shell-armv6.nix \ 94 | --run "TARGET=arm-unknown-linux-musleabihf make && \ 95 | echo TARGET=arm-unknown-linux-musleabihf make run" && \ 96 | nix-shell shell-armv7.nix \ 97 | --run "TARGET=armv7-unknown-linux-musleabihf make && \ 98 | echo TARGET=armv7-unknown-linux-musleabihf make run" && \ 99 | nix-shell shell-i686.nix \ 100 | --run "TARGET=i686-unknown-linux-musl make && \ 101 | echo TARGET=i686-unknown-linux-musl make run" 102 | -------------------------------------------------------------------------------- /nix-rust-overlay/Makefile: -------------------------------------------------------------------------------- 1 | # This Makefile is expected to be run inside nix-shell. 2 | TARGET ?= x86_64-unknown-linux-musl 3 | CARGO_FLAGS := --release --target $(TARGET) 4 | 5 | mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) 6 | mkfile_dir := $(dir $(mkfile_path)) 7 | 8 | ifeq ($(TARGET),x86_64-pc-windows-gnu) 9 | SRC_BIN := $(mkfile_dir)/target/$(TARGET)/release/hello-random.exe 10 | DEST_BIN := $(mkfile_dir)/out/hello-random-$(TARGET).exe 11 | OPENSSL_STATIC_FLAG := OPENSSL_STATIC=0 12 | else 13 | SRC_BIN := $(mkfile_dir)/target/$(TARGET)/release/hello-random 14 | DEST_BIN := $(mkfile_dir)/out/hello-random-$(TARGET) 15 | OPENSSL_STATIC_FLAG := OPENSSL_STATIC=1 16 | endif 17 | 18 | .PHONY: all 19 | all: Cargo.toml Cargo.lock src/main.rs 20 | $(OPENSSL_STATIC_FLAG) cargo build -vv --locked $(CARGO_FLAGS) 21 | cp $(SRC_BIN) $(DEST_BIN) 22 | 23 | .PHONY: run 24 | run: all 25 | cargo run $(CARGO_FLAGS) 26 | 27 | # This target calls other targets to build reproducible artifacts 28 | .PHONY: r10e-build 29 | r10e-build: Dockerfile run.sh 30 | $(mkfile_dir)/run.sh 31 | 32 | .PHONY: clean 33 | clean: 34 | rm -rf $(mkfile_dir)/out 35 | -------------------------------------------------------------------------------- /nix-rust-overlay/README.md: -------------------------------------------------------------------------------- 1 | # Reproducible Rust Cross Builds with rust-overlay 2 | 3 | This approach to deterministically building statically linked Rust binaries is 4 | based on [Nix](https://github.com/NixOS/nixpkgs) and 5 | [rust-overlay](https://github.com/oxalica/rust-overlay). 6 | 7 | ## How to build 8 | 9 | In the directory root of the repository 10 | 11 | ```bash 12 | make rust-overlay 13 | # `make ro-clean` to clean up 14 | ``` 15 | -------------------------------------------------------------------------------- /nix-rust-overlay/musl-1.1.24.patch: -------------------------------------------------------------------------------- 1 | diff --git a/pkgs/os-specific/linux/musl/default.nix b/pkgs/os-specific/linux/musl/default.nix 2 | index fb0d1911..5ca8d700 100644 3 | --- a/pkgs/os-specific/linux/musl/default.nix 4 | +++ b/pkgs/os-specific/linux/musl/default.nix 5 | @@ -40,11 +40,11 @@ let 6 | in 7 | stdenv.mkDerivation rec { 8 | pname = "musl"; 9 | - version = "1.2.3"; 10 | + version = "1.1.24"; 11 | 12 | src = fetchurl { 13 | url = "https://musl.libc.org/releases/${pname}-${version}.tar.gz"; 14 | - sha256 = "sha256-fVsLYGJSHkYn4JnkydyCSNMqMChelZt+7Kp4DPjP1KQ="; 15 | + sha256 = "18r2a00k82hz0mqdvgm7crzc7305l36109c0j9yjmkxj2alcjw0k"; 16 | }; 17 | 18 | enableParallelBuilding = true; 19 | -------------------------------------------------------------------------------- /nix-rust-overlay/run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euxo pipefail 4 | 5 | SCRIPT_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 6 | OUT_DIR="${SCRIPT_DIR}/out" 7 | REVISION=$(git --work-tree="${SCRIPT_DIR}"/../ --git-dir="${SCRIPT_DIR}"/../.git \ 8 | rev-parse HEAD) 9 | BUILDER_TAG_NAME="rust-overlay_builder:$REVISION" 10 | 11 | ######################################### 12 | # Self test 13 | ######################################### 14 | err() { 15 | echo -e "$*" 16 | exit 1 17 | } 18 | 19 | self_test() { 20 | # Check sha256sum 21 | command -v sha256sum &>/dev/null || \ 22 | err "sha256sum not found. Please install coreutils first" 23 | 24 | # Check docker 25 | docker info &>/dev/null || \ 26 | err "Make sure docker daemon is running" 27 | } 28 | 29 | # Let's go 30 | self_test 31 | echo "Creating builder container image..." 32 | # Need to run docker build in script's parent directory 33 | cd "${SCRIPT_DIR}/.." 34 | docker build --platform linux/amd64 -f "${SCRIPT_DIR}/Dockerfile" -t "${BUILDER_TAG_NAME}" . 35 | docker images "${BUILDER_TAG_NAME}" 36 | rm -rf "${OUT_DIR}" 37 | mkdir -p "${OUT_DIR}" 38 | 39 | echo "Cross building started..." 40 | docker run --platform linux/amd64 -v "${OUT_DIR}":/tmp/out_rust-overlay --rm -i "${BUILDER_TAG_NAME}" << CMD 41 | mkdir -p /tmp/out_rust-overlay && \ 42 | cp -r /build/rust-cross-build-nix/out/* /tmp/out_rust-overlay/ 43 | CMD 44 | 45 | echo 46 | echo "============ HELLO-RANDOM ARTIFACTS INFO ============" 47 | echo "Artifacts created in ${OUT_DIR}/" 48 | echo "sha256sums:" 49 | sha256sum "${OUT_DIR}"/hello-random* | sort -k2 50 | echo 51 | -------------------------------------------------------------------------------- /nix-rust-overlay/shell-aarch64.nix: -------------------------------------------------------------------------------- 1 | # h/t https://github.com/oxalica/rust-overlay/tree/master/examples/cross-aarch64 2 | # When invoking with `nix-shell`, add "rust-overlay=/path/to/rust-overlay/dir" 3 | # to $NIX_PATH 4 | (import { 5 | crossSystem = "aarch64-linux"; 6 | overlays = [ (import ) ]; 7 | }).pkgsMusl.pkgsStatic.callPackage ( 8 | { mkShell, stdenv, rust-bin, pkg-config, openssl, qemu }: 9 | mkShell { 10 | nativeBuildInputs = [ 11 | rust-bin.stable."1.78.0".minimal 12 | pkg-config 13 | ]; 14 | 15 | depsBuildBuild = [ qemu ]; 16 | 17 | buildInputs = [ openssl ]; 18 | 19 | CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER = "${stdenv.cc.targetPrefix}cc"; 20 | CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUNNER = "qemu-aarch64"; 21 | }) {} 22 | -------------------------------------------------------------------------------- /nix-rust-overlay/shell-armv6.nix: -------------------------------------------------------------------------------- 1 | # h/t https://github.com/oxalica/rust-overlay/tree/master/examples/cross-aarch64 2 | # When invoking with `nix-shell`, add "rust-overlay=/path/to/rust-overlay/dir" 3 | # to $NIX_PATH 4 | (import { 5 | crossSystem = "armv6l-linux"; 6 | overlays = [ (import ) ]; 7 | }).pkgsMusl.pkgsStatic.callPackage ( 8 | { mkShell, stdenv, rust-bin, pkg-config, openssl, qemu }: 9 | mkShell { 10 | nativeBuildInputs = [ 11 | rust-bin.stable."1.78.0".minimal 12 | pkg-config 13 | ]; 14 | 15 | depsBuildBuild = [ qemu ]; 16 | 17 | buildInputs = [ openssl ]; 18 | 19 | CARGO_TARGET_ARM_UNKNOWN_LINUX_MUSLEABIHF_LINKER = "${stdenv.cc.targetPrefix}cc"; 20 | CARGO_TARGET_ARM_UNKNOWN_LINUX_MUSLEABIHF_RUNNER = "qemu-arm"; 21 | }) {} 22 | -------------------------------------------------------------------------------- /nix-rust-overlay/shell-armv7.nix: -------------------------------------------------------------------------------- 1 | # h/t https://github.com/oxalica/rust-overlay/tree/master/examples/cross-aarch64 2 | # When invoking with `nix-shell`, add "rust-overlay=/path/to/rust-overlay/dir" 3 | # to $NIX_PATH 4 | (import { 5 | crossSystem = "armv7l-linux"; 6 | overlays = [ (import ) ]; 7 | }).pkgsMusl.pkgsStatic.callPackage ( 8 | { mkShell, stdenv, rust-bin, pkg-config, openssl, qemu }: 9 | mkShell { 10 | nativeBuildInputs = [ 11 | rust-bin.stable."1.78.0".minimal 12 | pkg-config 13 | ]; 14 | 15 | depsBuildBuild = [ qemu ]; 16 | 17 | buildInputs = [ openssl ]; 18 | 19 | CARGO_TARGET_ARMV7_UNKNOWN_LINUX_MUSLEABIHF_LINKER = "${stdenv.cc.targetPrefix}cc"; 20 | CARGO_TARGET_ARMV7_UNKNOWN_LINUX_MUSLEABIHF_RUNNER = "qemu-arm"; 21 | }) {} 22 | -------------------------------------------------------------------------------- /nix-rust-overlay/shell-i686.nix: -------------------------------------------------------------------------------- 1 | # h/t https://github.com/oxalica/rust-overlay/tree/master/examples/cross-aarch64 2 | # When invoking with `nix-shell`, add "rust-overlay=/path/to/rust-overlay/dir" 3 | # to $NIX_PATH 4 | (import { 5 | crossSystem = "i686-linux"; 6 | overlays = [ (import ) ]; 7 | }).pkgsMusl.pkgsStatic.callPackage ( 8 | { mkShell, stdenv, rust-bin, pkg-config, openssl, qemu }: 9 | mkShell { 10 | nativeBuildInputs = [ 11 | rust-bin.stable."1.78.0".minimal 12 | pkg-config 13 | ]; 14 | 15 | depsBuildBuild = [ qemu ]; 16 | 17 | buildInputs = [ openssl ]; 18 | 19 | CARGO_TARGET_I686_UNKNOWN_LINUX_MUSL_LINKER = "${stdenv.cc.targetPrefix}cc"; 20 | CARGO_TARGET_I686_UNKNOWN_LINUX_MUSL_RUNNER = "qemu-i386"; 21 | }) {} 22 | -------------------------------------------------------------------------------- /nix-rust-overlay/shell-x86_64-win.nix: -------------------------------------------------------------------------------- 1 | # h/t https://github.com/oxalica/rust-overlay/tree/master/examples/cross-aarch64 2 | # When invoking with `nix-shell`, add "rust-overlay=/path/to/rust-overlay/dir" 3 | # to $NIX_PATH 4 | (import { 5 | crossSystem = { 6 | config = "x86_64-w64-mingw32"; 7 | }; 8 | overlays = [ (import ) ]; 9 | }).callPackage ( 10 | { mkShell, stdenv, rust-bin, windows, wine64, pkg-config }: 11 | mkShell { 12 | nativeBuildInputs = [ 13 | rust-bin.stable."1.77.0".minimal 14 | pkg-config 15 | ]; 16 | 17 | depsBuildBuild = [ wine64 ]; 18 | 19 | buildInputs = [ windows.pthreads ]; 20 | 21 | CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = "${stdenv.cc.targetPrefix}cc"; 22 | CARGO_TARGET_X86_64_PC_WINDOWS_GNU_RUNNER = "wine64"; 23 | }) {} -------------------------------------------------------------------------------- /nix-rust-overlay/shell-x86_64.nix: -------------------------------------------------------------------------------- 1 | # h/t https://github.com/oxalica/rust-overlay/tree/master/examples/cross-aarch64 2 | # When invoking with `nix-shell`, add "rust-overlay=/path/to/rust-overlay/dir" 3 | # to $NIX_PATH 4 | (import { 5 | crossSystem = "x86_64-linux"; 6 | overlays = [ (import ) ]; 7 | }).pkgsMusl.pkgsStatic.callPackage ( 8 | { mkShell, stdenv, rust-bin, pkg-config, openssl, qemu }: 9 | mkShell { 10 | nativeBuildInputs = [ 11 | rust-bin.stable."1.78.0".minimal 12 | pkg-config 13 | ]; 14 | 15 | depsBuildBuild = [ qemu ]; 16 | 17 | buildInputs = [ openssl ]; 18 | 19 | CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER = "${stdenv.cc.targetPrefix}cc"; 20 | CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUNNER = "qemu-x86_64"; 21 | }) {} 22 | -------------------------------------------------------------------------------- /nix.conf: -------------------------------------------------------------------------------- 1 | # cf https://nixos.org/manual/nix/stable/command-ref/conf-file.html 2 | # Workaround for Apple M1 3 | filter-syscalls = false -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate rand; 2 | extern crate zstd; 3 | use std::io::Write; 4 | 5 | use rand::Rng; 6 | 7 | fn main() -> std::io::Result<()> { 8 | let rn = rand::thread_rng().gen_range(38, 45); 9 | println!("Hello, random: {}", rn); 10 | println!("ZSTD default compression level: {}", zstd::DEFAULT_COMPRESSION_LEVEL); 11 | 12 | let mut infile = std::fs::File::create("infile")?; 13 | let mut outfile = std::fs::OpenOptions::new().write(true).create(true).open("outfile")?; 14 | infile.write_all(b"Hello, random")?; 15 | let infile1 = std::fs::File::open("infile")?; 16 | zstd::stream::copy_encode(&infile1, &mut outfile, 0)?; 17 | 18 | // Test linking against OpenSSL on unix target 19 | openssl_init(); 20 | 21 | Ok(()) 22 | } 23 | 24 | #[cfg(target_family = "unix")] 25 | fn openssl_init() { 26 | openssl::init(); 27 | assert!(openssl::version::version().starts_with("OpenSSL ")); 28 | } 29 | 30 | #[cfg(not(target_family = "unix"))] 31 | fn openssl_init() { 32 | println!("openssl not linked on this target"); 33 | } --------------------------------------------------------------------------------