├── .gitignore
├── Cargo.lock
├── Cargo.toml
├── README.md
├── build.rs
├── index.html
├── some-c-code
├── gcd.c
├── gcd.h
└── main.c
└── src
├── bindings.rs
├── lib.rs
└── main.rs
/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /bin
3 |
--------------------------------------------------------------------------------
/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 = "aho-corasick"
7 | version = "1.1.2"
8 | source = "registry+https://github.com/rust-lang/crates.io-index"
9 | checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
10 | dependencies = [
11 | "memchr",
12 | ]
13 |
14 | [[package]]
15 | name = "anstream"
16 | version = "0.6.11"
17 | source = "registry+https://github.com/rust-lang/crates.io-index"
18 | checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5"
19 | dependencies = [
20 | "anstyle",
21 | "anstyle-parse",
22 | "anstyle-query",
23 | "anstyle-wincon",
24 | "colorchoice",
25 | "utf8parse",
26 | ]
27 |
28 | [[package]]
29 | name = "anstyle"
30 | version = "1.0.6"
31 | source = "registry+https://github.com/rust-lang/crates.io-index"
32 | checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
33 |
34 | [[package]]
35 | name = "anstyle-parse"
36 | version = "0.2.3"
37 | source = "registry+https://github.com/rust-lang/crates.io-index"
38 | checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
39 | dependencies = [
40 | "utf8parse",
41 | ]
42 |
43 | [[package]]
44 | name = "anstyle-query"
45 | version = "1.0.2"
46 | source = "registry+https://github.com/rust-lang/crates.io-index"
47 | checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
48 | dependencies = [
49 | "windows-sys 0.52.0",
50 | ]
51 |
52 | [[package]]
53 | name = "anstyle-wincon"
54 | version = "3.0.2"
55 | source = "registry+https://github.com/rust-lang/crates.io-index"
56 | checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
57 | dependencies = [
58 | "anstyle",
59 | "windows-sys 0.52.0",
60 | ]
61 |
62 | [[package]]
63 | name = "anyhow"
64 | version = "1.0.79"
65 | source = "registry+https://github.com/rust-lang/crates.io-index"
66 | checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
67 |
68 | [[package]]
69 | name = "autocfg"
70 | version = "1.1.0"
71 | source = "registry+https://github.com/rust-lang/crates.io-index"
72 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
73 |
74 | [[package]]
75 | name = "bindgen"
76 | version = "0.69.4"
77 | source = "registry+https://github.com/rust-lang/crates.io-index"
78 | checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0"
79 | dependencies = [
80 | "bitflags 2.4.2",
81 | "cexpr",
82 | "clang-sys",
83 | "itertools",
84 | "lazy_static",
85 | "lazycell",
86 | "log",
87 | "prettyplease",
88 | "proc-macro2",
89 | "quote",
90 | "regex",
91 | "rustc-hash",
92 | "shlex",
93 | "syn",
94 | "which 4.4.2",
95 | ]
96 |
97 | [[package]]
98 | name = "bitflags"
99 | version = "1.3.2"
100 | source = "registry+https://github.com/rust-lang/crates.io-index"
101 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
102 |
103 | [[package]]
104 | name = "bitflags"
105 | version = "2.4.2"
106 | source = "registry+https://github.com/rust-lang/crates.io-index"
107 | checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
108 |
109 | [[package]]
110 | name = "camino"
111 | version = "1.1.6"
112 | source = "registry+https://github.com/rust-lang/crates.io-index"
113 | checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c"
114 | dependencies = [
115 | "serde",
116 | ]
117 |
118 | [[package]]
119 | name = "cargo-options"
120 | version = "0.7.2"
121 | source = "registry+https://github.com/rust-lang/crates.io-index"
122 | checksum = "cad71bf996c8e5b9d28ef3472d7ee41f277edf4e38cd597f51ad0438d05d76ea"
123 | dependencies = [
124 | "anstyle",
125 | "clap",
126 | ]
127 |
128 | [[package]]
129 | name = "cargo-platform"
130 | version = "0.1.7"
131 | source = "registry+https://github.com/rust-lang/crates.io-index"
132 | checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f"
133 | dependencies = [
134 | "serde",
135 | ]
136 |
137 | [[package]]
138 | name = "cargo-zigbuild"
139 | version = "0.18.3"
140 | source = "registry+https://github.com/rust-lang/crates.io-index"
141 | checksum = "cb76e6ab558f9138291c7e1fa954ffd58e060712eab13f97a317da712218ca24"
142 | dependencies = [
143 | "anyhow",
144 | "cargo-options",
145 | "cargo_metadata",
146 | "clap",
147 | "dirs",
148 | "fat-macho",
149 | "fs-err",
150 | "path-slash",
151 | "rustc_version",
152 | "semver",
153 | "serde",
154 | "serde_json",
155 | "shlex",
156 | "target-lexicon",
157 | "which 6.0.0",
158 | ]
159 |
160 | [[package]]
161 | name = "cargo_metadata"
162 | version = "0.18.1"
163 | source = "registry+https://github.com/rust-lang/crates.io-index"
164 | checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037"
165 | dependencies = [
166 | "camino",
167 | "cargo-platform",
168 | "semver",
169 | "serde",
170 | "serde_json",
171 | "thiserror",
172 | ]
173 |
174 | [[package]]
175 | name = "cc"
176 | version = "1.0.83"
177 | source = "registry+https://github.com/rust-lang/crates.io-index"
178 | checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
179 | dependencies = [
180 | "libc",
181 | ]
182 |
183 | [[package]]
184 | name = "cexpr"
185 | version = "0.6.0"
186 | source = "registry+https://github.com/rust-lang/crates.io-index"
187 | checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
188 | dependencies = [
189 | "nom",
190 | ]
191 |
192 | [[package]]
193 | name = "cfg-if"
194 | version = "1.0.0"
195 | source = "registry+https://github.com/rust-lang/crates.io-index"
196 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
197 |
198 | [[package]]
199 | name = "clang-sys"
200 | version = "1.7.0"
201 | source = "registry+https://github.com/rust-lang/crates.io-index"
202 | checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1"
203 | dependencies = [
204 | "glob",
205 | "libc",
206 | "libloading",
207 | ]
208 |
209 | [[package]]
210 | name = "clap"
211 | version = "4.5.1"
212 | source = "registry+https://github.com/rust-lang/crates.io-index"
213 | checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da"
214 | dependencies = [
215 | "clap_builder",
216 | "clap_derive",
217 | ]
218 |
219 | [[package]]
220 | name = "clap_builder"
221 | version = "4.5.1"
222 | source = "registry+https://github.com/rust-lang/crates.io-index"
223 | checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb"
224 | dependencies = [
225 | "anstream",
226 | "anstyle",
227 | "clap_lex",
228 | "strsim",
229 | "terminal_size",
230 | ]
231 |
232 | [[package]]
233 | name = "clap_derive"
234 | version = "4.5.0"
235 | source = "registry+https://github.com/rust-lang/crates.io-index"
236 | checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47"
237 | dependencies = [
238 | "heck",
239 | "proc-macro2",
240 | "quote",
241 | "syn",
242 | ]
243 |
244 | [[package]]
245 | name = "clap_lex"
246 | version = "0.7.0"
247 | source = "registry+https://github.com/rust-lang/crates.io-index"
248 | checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
249 |
250 | [[package]]
251 | name = "colorchoice"
252 | version = "1.0.0"
253 | source = "registry+https://github.com/rust-lang/crates.io-index"
254 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
255 |
256 | [[package]]
257 | name = "dirs"
258 | version = "5.0.1"
259 | source = "registry+https://github.com/rust-lang/crates.io-index"
260 | checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
261 | dependencies = [
262 | "dirs-sys",
263 | ]
264 |
265 | [[package]]
266 | name = "dirs-sys"
267 | version = "0.4.1"
268 | source = "registry+https://github.com/rust-lang/crates.io-index"
269 | checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
270 | dependencies = [
271 | "libc",
272 | "option-ext",
273 | "redox_users",
274 | "windows-sys 0.48.0",
275 | ]
276 |
277 | [[package]]
278 | name = "either"
279 | version = "1.10.0"
280 | source = "registry+https://github.com/rust-lang/crates.io-index"
281 | checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
282 |
283 | [[package]]
284 | name = "errno"
285 | version = "0.3.8"
286 | source = "registry+https://github.com/rust-lang/crates.io-index"
287 | checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
288 | dependencies = [
289 | "libc",
290 | "windows-sys 0.52.0",
291 | ]
292 |
293 | [[package]]
294 | name = "fat-macho"
295 | version = "0.4.8"
296 | source = "registry+https://github.com/rust-lang/crates.io-index"
297 | checksum = "0d4c93f393add03d72bc10dd3dea43a1610ecb29e0c0a6459c70b53b82931adf"
298 | dependencies = [
299 | "goblin",
300 | ]
301 |
302 | [[package]]
303 | name = "fs-err"
304 | version = "2.11.0"
305 | source = "registry+https://github.com/rust-lang/crates.io-index"
306 | checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41"
307 | dependencies = [
308 | "autocfg",
309 | ]
310 |
311 | [[package]]
312 | name = "getrandom"
313 | version = "0.2.12"
314 | source = "registry+https://github.com/rust-lang/crates.io-index"
315 | checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
316 | dependencies = [
317 | "cfg-if",
318 | "libc",
319 | "wasi",
320 | ]
321 |
322 | [[package]]
323 | name = "glob"
324 | version = "0.3.1"
325 | source = "registry+https://github.com/rust-lang/crates.io-index"
326 | checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
327 |
328 | [[package]]
329 | name = "goblin"
330 | version = "0.8.0"
331 | source = "registry+https://github.com/rust-lang/crates.io-index"
332 | checksum = "bb07a4ffed2093b118a525b1d8f5204ae274faed5604537caf7135d0f18d9887"
333 | dependencies = [
334 | "log",
335 | "plain",
336 | "scroll",
337 | ]
338 |
339 | [[package]]
340 | name = "heck"
341 | version = "0.4.1"
342 | source = "registry+https://github.com/rust-lang/crates.io-index"
343 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
344 |
345 | [[package]]
346 | name = "home"
347 | version = "0.5.9"
348 | source = "registry+https://github.com/rust-lang/crates.io-index"
349 | checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
350 | dependencies = [
351 | "windows-sys 0.52.0",
352 | ]
353 |
354 | [[package]]
355 | name = "itertools"
356 | version = "0.12.1"
357 | source = "registry+https://github.com/rust-lang/crates.io-index"
358 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
359 | dependencies = [
360 | "either",
361 | ]
362 |
363 | [[package]]
364 | name = "itoa"
365 | version = "1.0.10"
366 | source = "registry+https://github.com/rust-lang/crates.io-index"
367 | checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
368 |
369 | [[package]]
370 | name = "lazy_static"
371 | version = "1.4.0"
372 | source = "registry+https://github.com/rust-lang/crates.io-index"
373 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
374 |
375 | [[package]]
376 | name = "lazycell"
377 | version = "1.3.0"
378 | source = "registry+https://github.com/rust-lang/crates.io-index"
379 | checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
380 |
381 | [[package]]
382 | name = "libc"
383 | version = "0.2.153"
384 | source = "registry+https://github.com/rust-lang/crates.io-index"
385 | checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
386 |
387 | [[package]]
388 | name = "libloading"
389 | version = "0.8.1"
390 | source = "registry+https://github.com/rust-lang/crates.io-index"
391 | checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161"
392 | dependencies = [
393 | "cfg-if",
394 | "windows-sys 0.48.0",
395 | ]
396 |
397 | [[package]]
398 | name = "libredox"
399 | version = "0.0.1"
400 | source = "registry+https://github.com/rust-lang/crates.io-index"
401 | checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8"
402 | dependencies = [
403 | "bitflags 2.4.2",
404 | "libc",
405 | "redox_syscall",
406 | ]
407 |
408 | [[package]]
409 | name = "linux-raw-sys"
410 | version = "0.4.13"
411 | source = "registry+https://github.com/rust-lang/crates.io-index"
412 | checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
413 |
414 | [[package]]
415 | name = "log"
416 | version = "0.4.20"
417 | source = "registry+https://github.com/rust-lang/crates.io-index"
418 | checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
419 |
420 | [[package]]
421 | name = "memchr"
422 | version = "2.7.1"
423 | source = "registry+https://github.com/rust-lang/crates.io-index"
424 | checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
425 |
426 | [[package]]
427 | name = "minimal-lexical"
428 | version = "0.2.1"
429 | source = "registry+https://github.com/rust-lang/crates.io-index"
430 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
431 |
432 | [[package]]
433 | name = "nom"
434 | version = "7.1.3"
435 | source = "registry+https://github.com/rust-lang/crates.io-index"
436 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
437 | dependencies = [
438 | "memchr",
439 | "minimal-lexical",
440 | ]
441 |
442 | [[package]]
443 | name = "once_cell"
444 | version = "1.19.0"
445 | source = "registry+https://github.com/rust-lang/crates.io-index"
446 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
447 |
448 | [[package]]
449 | name = "option-ext"
450 | version = "0.2.0"
451 | source = "registry+https://github.com/rust-lang/crates.io-index"
452 | checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
453 |
454 | [[package]]
455 | name = "path-slash"
456 | version = "0.2.1"
457 | source = "registry+https://github.com/rust-lang/crates.io-index"
458 | checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42"
459 |
460 | [[package]]
461 | name = "plain"
462 | version = "0.2.3"
463 | source = "registry+https://github.com/rust-lang/crates.io-index"
464 | checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
465 |
466 | [[package]]
467 | name = "prettyplease"
468 | version = "0.2.16"
469 | source = "registry+https://github.com/rust-lang/crates.io-index"
470 | checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5"
471 | dependencies = [
472 | "proc-macro2",
473 | "syn",
474 | ]
475 |
476 | [[package]]
477 | name = "proc-macro2"
478 | version = "1.0.78"
479 | source = "registry+https://github.com/rust-lang/crates.io-index"
480 | checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
481 | dependencies = [
482 | "unicode-ident",
483 | ]
484 |
485 | [[package]]
486 | name = "quote"
487 | version = "1.0.35"
488 | source = "registry+https://github.com/rust-lang/crates.io-index"
489 | checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
490 | dependencies = [
491 | "proc-macro2",
492 | ]
493 |
494 | [[package]]
495 | name = "redox_syscall"
496 | version = "0.4.1"
497 | source = "registry+https://github.com/rust-lang/crates.io-index"
498 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
499 | dependencies = [
500 | "bitflags 1.3.2",
501 | ]
502 |
503 | [[package]]
504 | name = "redox_users"
505 | version = "0.4.4"
506 | source = "registry+https://github.com/rust-lang/crates.io-index"
507 | checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4"
508 | dependencies = [
509 | "getrandom",
510 | "libredox",
511 | "thiserror",
512 | ]
513 |
514 | [[package]]
515 | name = "regex"
516 | version = "1.10.3"
517 | source = "registry+https://github.com/rust-lang/crates.io-index"
518 | checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
519 | dependencies = [
520 | "aho-corasick",
521 | "memchr",
522 | "regex-automata",
523 | "regex-syntax",
524 | ]
525 |
526 | [[package]]
527 | name = "regex-automata"
528 | version = "0.4.5"
529 | source = "registry+https://github.com/rust-lang/crates.io-index"
530 | checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd"
531 | dependencies = [
532 | "aho-corasick",
533 | "memchr",
534 | "regex-syntax",
535 | ]
536 |
537 | [[package]]
538 | name = "regex-syntax"
539 | version = "0.8.2"
540 | source = "registry+https://github.com/rust-lang/crates.io-index"
541 | checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
542 |
543 | [[package]]
544 | name = "rust-ffi-playground"
545 | version = "0.1.0"
546 | dependencies = [
547 | "bindgen",
548 | "cargo-zigbuild",
549 | "cc",
550 | ]
551 |
552 | [[package]]
553 | name = "rustc-hash"
554 | version = "1.1.0"
555 | source = "registry+https://github.com/rust-lang/crates.io-index"
556 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
557 |
558 | [[package]]
559 | name = "rustc_version"
560 | version = "0.4.0"
561 | source = "registry+https://github.com/rust-lang/crates.io-index"
562 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
563 | dependencies = [
564 | "semver",
565 | ]
566 |
567 | [[package]]
568 | name = "rustix"
569 | version = "0.38.31"
570 | source = "registry+https://github.com/rust-lang/crates.io-index"
571 | checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
572 | dependencies = [
573 | "bitflags 2.4.2",
574 | "errno",
575 | "libc",
576 | "linux-raw-sys",
577 | "windows-sys 0.52.0",
578 | ]
579 |
580 | [[package]]
581 | name = "ryu"
582 | version = "1.0.16"
583 | source = "registry+https://github.com/rust-lang/crates.io-index"
584 | checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
585 |
586 | [[package]]
587 | name = "scroll"
588 | version = "0.12.0"
589 | source = "registry+https://github.com/rust-lang/crates.io-index"
590 | checksum = "6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6"
591 | dependencies = [
592 | "scroll_derive",
593 | ]
594 |
595 | [[package]]
596 | name = "scroll_derive"
597 | version = "0.12.0"
598 | source = "registry+https://github.com/rust-lang/crates.io-index"
599 | checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932"
600 | dependencies = [
601 | "proc-macro2",
602 | "quote",
603 | "syn",
604 | ]
605 |
606 | [[package]]
607 | name = "semver"
608 | version = "1.0.21"
609 | source = "registry+https://github.com/rust-lang/crates.io-index"
610 | checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0"
611 | dependencies = [
612 | "serde",
613 | ]
614 |
615 | [[package]]
616 | name = "serde"
617 | version = "1.0.196"
618 | source = "registry+https://github.com/rust-lang/crates.io-index"
619 | checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
620 | dependencies = [
621 | "serde_derive",
622 | ]
623 |
624 | [[package]]
625 | name = "serde_derive"
626 | version = "1.0.196"
627 | source = "registry+https://github.com/rust-lang/crates.io-index"
628 | checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
629 | dependencies = [
630 | "proc-macro2",
631 | "quote",
632 | "syn",
633 | ]
634 |
635 | [[package]]
636 | name = "serde_json"
637 | version = "1.0.113"
638 | source = "registry+https://github.com/rust-lang/crates.io-index"
639 | checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79"
640 | dependencies = [
641 | "itoa",
642 | "ryu",
643 | "serde",
644 | ]
645 |
646 | [[package]]
647 | name = "shlex"
648 | version = "1.3.0"
649 | source = "registry+https://github.com/rust-lang/crates.io-index"
650 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
651 |
652 | [[package]]
653 | name = "strsim"
654 | version = "0.11.0"
655 | source = "registry+https://github.com/rust-lang/crates.io-index"
656 | checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
657 |
658 | [[package]]
659 | name = "syn"
660 | version = "2.0.49"
661 | source = "registry+https://github.com/rust-lang/crates.io-index"
662 | checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496"
663 | dependencies = [
664 | "proc-macro2",
665 | "quote",
666 | "unicode-ident",
667 | ]
668 |
669 | [[package]]
670 | name = "target-lexicon"
671 | version = "0.12.13"
672 | source = "registry+https://github.com/rust-lang/crates.io-index"
673 | checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae"
674 |
675 | [[package]]
676 | name = "terminal_size"
677 | version = "0.3.0"
678 | source = "registry+https://github.com/rust-lang/crates.io-index"
679 | checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7"
680 | dependencies = [
681 | "rustix",
682 | "windows-sys 0.48.0",
683 | ]
684 |
685 | [[package]]
686 | name = "thiserror"
687 | version = "1.0.57"
688 | source = "registry+https://github.com/rust-lang/crates.io-index"
689 | checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b"
690 | dependencies = [
691 | "thiserror-impl",
692 | ]
693 |
694 | [[package]]
695 | name = "thiserror-impl"
696 | version = "1.0.57"
697 | source = "registry+https://github.com/rust-lang/crates.io-index"
698 | checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
699 | dependencies = [
700 | "proc-macro2",
701 | "quote",
702 | "syn",
703 | ]
704 |
705 | [[package]]
706 | name = "unicode-ident"
707 | version = "1.0.12"
708 | source = "registry+https://github.com/rust-lang/crates.io-index"
709 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
710 |
711 | [[package]]
712 | name = "utf8parse"
713 | version = "0.2.1"
714 | source = "registry+https://github.com/rust-lang/crates.io-index"
715 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
716 |
717 | [[package]]
718 | name = "wasi"
719 | version = "0.11.0+wasi-snapshot-preview1"
720 | source = "registry+https://github.com/rust-lang/crates.io-index"
721 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
722 |
723 | [[package]]
724 | name = "which"
725 | version = "4.4.2"
726 | source = "registry+https://github.com/rust-lang/crates.io-index"
727 | checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
728 | dependencies = [
729 | "either",
730 | "home",
731 | "once_cell",
732 | "rustix",
733 | ]
734 |
735 | [[package]]
736 | name = "which"
737 | version = "6.0.0"
738 | source = "registry+https://github.com/rust-lang/crates.io-index"
739 | checksum = "7fa5e0c10bf77f44aac573e498d1a82d5fbd5e91f6fc0a99e7be4b38e85e101c"
740 | dependencies = [
741 | "either",
742 | "home",
743 | "once_cell",
744 | "rustix",
745 | "windows-sys 0.52.0",
746 | ]
747 |
748 | [[package]]
749 | name = "windows-sys"
750 | version = "0.48.0"
751 | source = "registry+https://github.com/rust-lang/crates.io-index"
752 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
753 | dependencies = [
754 | "windows-targets 0.48.5",
755 | ]
756 |
757 | [[package]]
758 | name = "windows-sys"
759 | version = "0.52.0"
760 | source = "registry+https://github.com/rust-lang/crates.io-index"
761 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
762 | dependencies = [
763 | "windows-targets 0.52.0",
764 | ]
765 |
766 | [[package]]
767 | name = "windows-targets"
768 | version = "0.48.5"
769 | source = "registry+https://github.com/rust-lang/crates.io-index"
770 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
771 | dependencies = [
772 | "windows_aarch64_gnullvm 0.48.5",
773 | "windows_aarch64_msvc 0.48.5",
774 | "windows_i686_gnu 0.48.5",
775 | "windows_i686_msvc 0.48.5",
776 | "windows_x86_64_gnu 0.48.5",
777 | "windows_x86_64_gnullvm 0.48.5",
778 | "windows_x86_64_msvc 0.48.5",
779 | ]
780 |
781 | [[package]]
782 | name = "windows-targets"
783 | version = "0.52.0"
784 | source = "registry+https://github.com/rust-lang/crates.io-index"
785 | checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
786 | dependencies = [
787 | "windows_aarch64_gnullvm 0.52.0",
788 | "windows_aarch64_msvc 0.52.0",
789 | "windows_i686_gnu 0.52.0",
790 | "windows_i686_msvc 0.52.0",
791 | "windows_x86_64_gnu 0.52.0",
792 | "windows_x86_64_gnullvm 0.52.0",
793 | "windows_x86_64_msvc 0.52.0",
794 | ]
795 |
796 | [[package]]
797 | name = "windows_aarch64_gnullvm"
798 | version = "0.48.5"
799 | source = "registry+https://github.com/rust-lang/crates.io-index"
800 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
801 |
802 | [[package]]
803 | name = "windows_aarch64_gnullvm"
804 | version = "0.52.0"
805 | source = "registry+https://github.com/rust-lang/crates.io-index"
806 | checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
807 |
808 | [[package]]
809 | name = "windows_aarch64_msvc"
810 | version = "0.48.5"
811 | source = "registry+https://github.com/rust-lang/crates.io-index"
812 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
813 |
814 | [[package]]
815 | name = "windows_aarch64_msvc"
816 | version = "0.52.0"
817 | source = "registry+https://github.com/rust-lang/crates.io-index"
818 | checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
819 |
820 | [[package]]
821 | name = "windows_i686_gnu"
822 | version = "0.48.5"
823 | source = "registry+https://github.com/rust-lang/crates.io-index"
824 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
825 |
826 | [[package]]
827 | name = "windows_i686_gnu"
828 | version = "0.52.0"
829 | source = "registry+https://github.com/rust-lang/crates.io-index"
830 | checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
831 |
832 | [[package]]
833 | name = "windows_i686_msvc"
834 | version = "0.48.5"
835 | source = "registry+https://github.com/rust-lang/crates.io-index"
836 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
837 |
838 | [[package]]
839 | name = "windows_i686_msvc"
840 | version = "0.52.0"
841 | source = "registry+https://github.com/rust-lang/crates.io-index"
842 | checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
843 |
844 | [[package]]
845 | name = "windows_x86_64_gnu"
846 | version = "0.48.5"
847 | source = "registry+https://github.com/rust-lang/crates.io-index"
848 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
849 |
850 | [[package]]
851 | name = "windows_x86_64_gnu"
852 | version = "0.52.0"
853 | source = "registry+https://github.com/rust-lang/crates.io-index"
854 | checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
855 |
856 | [[package]]
857 | name = "windows_x86_64_gnullvm"
858 | version = "0.48.5"
859 | source = "registry+https://github.com/rust-lang/crates.io-index"
860 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
861 |
862 | [[package]]
863 | name = "windows_x86_64_gnullvm"
864 | version = "0.52.0"
865 | source = "registry+https://github.com/rust-lang/crates.io-index"
866 | checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
867 |
868 | [[package]]
869 | name = "windows_x86_64_msvc"
870 | version = "0.48.5"
871 | source = "registry+https://github.com/rust-lang/crates.io-index"
872 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
873 |
874 | [[package]]
875 | name = "windows_x86_64_msvc"
876 | version = "0.52.0"
877 | source = "registry+https://github.com/rust-lang/crates.io-index"
878 | checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
879 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "rust-ffi-playground"
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 |
8 | [dependencies]
9 |
10 | [build-dependencies]
11 | bindgen = "0.69.4"
12 | cargo-zigbuild = "0.18.3"
13 | cc = "1.0.83"
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Crosscompile a Rust project with C dependencies into Web Assembly (WASM and WASI) using Zig
2 |
3 | Easy way using [rust-bindgen](https://github.com/rust-lang/rust-bindgen) and [cargo-zigbuild](https://github.com/rust-cross/cargo-zigbuild) CLI tools.
4 |
5 | ### Generate Rust bindings for the C code
6 |
7 | We just need the C/C++ header files wit the definitions and [rust-bindgen](https://github.com/rust-lang/rust-bindgen) will generate the Rust FFI bindings.
8 |
9 | ```bash
10 | bindgen some-c-code/gcd.h -o src/bindings.rs # generate Rust FFI bindings for gcd.h
11 | ```
12 |
13 | ### Quick WASI try out
14 |
15 | Using [zigbuild](https://github.com/rust-cross/cargo-zigbuild) we can cross compile to WASI
16 |
17 | ```bash
18 | rustup target add wasm32-wasip1 # make sure wasm32-wasi target is installed
19 | cargo zigbuild --target=wasm32-wasip1 --release # cross compile to WASI, release flag is optional
20 | ```
21 |
22 | > [!warning]
23 | > Previously the target `wasm32-wasip1` was `wasm32-wasi` but it is now being deprecated, still you might want to use it even if you [get some warnings](https://blog.rust-lang.org/2024/04/09/updates-to-rusts-wasi-targets.html#renaming-wasm32-wasi-to-wasm32-wasip1).
24 |
25 | we can try it with [wasm3](https://github.com/wasm3/wasm3) engine
26 |
27 | ```bash
28 | wasm3 target/wasm32-wasip1/release/rust-ffi-playground.wasm # try it out, requires wasm3
29 | ```
30 |
31 | or [wasmi](https://github.com/wasmi-labs/wasmi)
32 |
33 | ```bash
34 | wasmi_cli target/wasm32-wasip1/release/rust-ffi-playground.wasm # run it with wasmi runtime
35 | ```
36 |
37 |
38 | ### Cross compile for web (WASM)
39 |
40 | Generate code for WASM with [zigbuild](https://github.com/rust-cross/cargo-zigbuild), and then use [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen) to generate the js/ts bindings to the WASM code.
41 |
42 | ```bash
43 | cargo zigbuild --target=wasm32-unknown-unknown --release # cross compile to WASM, release flag is optional
44 | wasm-bindgen target/wasm32-unknown-unknown/release/rust-ffi-playground.wasm --out-dir ./dist --target web # generate JS and TS FFI bindings into WASM code
45 | ```
46 |
47 | To try it, manually include the script tag to load and initialize the wasm module
48 |
49 | ```html
50 |
54 | ```
55 |
56 | or use a WASM plugin like [`vite-plugin-wasm`](https://www.npmjs.com/package/vite-plugin-wasm) or use [Trunk](https://trunkrs.dev/)
57 |
58 | Note: As in this [github issue](https://github.com/rustwasm/team/issues/291#issuecomment-644946504) it can be compiled to `wasm32-unknown-emscripten`.
59 |
60 | Same [example](https://github.com/rustwasm/team/issues/291#issuecomment-645492619) but using `wasm-pack`, hence `wasm-bindgen` instead
61 |
62 | ### Going further
63 |
64 | Not a trivial project, eg. building a native library, link to a system library...
65 |
66 | Replace CLI commands with a simple `Makefile` or (even better) a `builder.rs` file, eg. use `cargo_zigbuild` and `bindgen` directly in `build.rs` by replacing `cc` with `zigbuild`
67 |
68 | ```rust
69 | use cargo_zigbuild::Zig::Cc;
70 | use std::{env, error::Error};
71 |
72 | fn main() -> Result<(), Box> {
73 | cc::Build::new().file("some-c-code/def.c").compile("def");
74 |
75 | let out_dir = env::var("OUT_DIR").unwrap();
76 |
77 | let cc = Cc {
78 | args: vec![
79 | format!("some-c-code/def.c"),
80 | "-c".to_string(),
81 | "-o".to_string(),
82 | format!("{}/def.o", out_dir),
83 | ],
84 | };
85 |
86 | cc.execute().expect("Failed to compile def.c");
87 |
88 | let ar = cargo_zigbuild::Zig::Ar {
89 | args: vec![
90 | "crus".to_string(),
91 | format!("{}/libdef.a", out_dir),
92 | format!("{}/def.o", out_dir),
93 | ],
94 | };
95 |
96 | ar.execute().expect("Failed to create def.a");
97 |
98 | println!("cargo:rustc-link-search=native={}", out_dir);
99 | println!("cargo:rustc-link-lib=static=def");
100 |
101 | println!("cargo:rerun-if-changed=some-c-code");
102 | println!("cargo:rerun-if-changed=build.rs");
103 | Ok(())
104 | }
105 | ```
106 |
107 | ## References
108 |
109 | - [The `cc-rs` project](https://crates.io/crates/cc)
110 | - [Official cargo reference](https://doc.rust-lang.org/cargo/reference/build-script-examples.html)
111 | - [zig.guide's Cross-compilation](https://zig.guide/build-system/cross-compilation/)
112 | - [`zig cc`: a Powerful Drop-In Replacement for GCC/Clang](https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html)
113 | - [Bindgen tutorial](https://rust-lang.github.io/rust-bindgen/tutorial-3.html)
114 | - [The embedded Rust book](https://docs.rust-embedded.org/book/interoperability/c-with-rust.html)
115 | - [Shrinking `.wasm` code size](https://rustwasm.github.io/docs/book/reference/code-size.html)
116 |
117 | ## Issues
118 |
119 | wasm-bindgen targets `wasm32-unknown-unknown` and `wasi-unknown` do not (fully) support C-ABI, only older targets like `wasm32-unknown-emscripten`.
120 |
121 | See [comment](https://github.com/rustwasm/team/issues/291#issuecomment-645482430), [comment](https://github.com/rustwasm/team/issues/291#issuecomment-645494771) and [documentation PR](https://github.com/rustwasm/wasm-bindgen/pull/2209)
122 |
123 | There is an experimental flag `--Z wasm_c_abi=spec` that [circumvents this limitation](https://github.com/rustwasm/team/issues/291#issuecomment-2138201722)
124 |
125 | ## Other tools
126 |
127 | - [c2rust](https://github.com/immunant/c2rust) - C to Rust translator produces `unsafe` Rust code from C99-compilant C code. It does not support cross compilation, but maybe it can with the help of Zig.
128 |
129 | From their website:
130 |
131 | > C source code is parsed and typechecked using clang before being translated by our tool.
132 |
133 | would it be possible to use it with Zig as a drop-in replacement for clang?
134 |
135 | From their README:
136 |
137 | > I translated code on platform X, but it didn't work correctly on platform Y.
138 | > We run the C preprocessor before translation to Rust. This specializes the code to the host platform. For this reason, we do not support cross compiling translated code at the moment.
139 | > What platforms can C2Rust be run on?
140 | > The translator and refactoring tool support both macOS and Linux. Other features, such as cross checking the functionality between C and Rust code, are currently limited to Linux hosts.
141 |
142 | ## Utils
143 |
144 | - [source](https://github.com/GoogleChromeLabs/wasm-feature-detect)
145 |
146 | ---
147 |
148 | ## Remarks
149 |
150 | > In general, a `lib.so` or `lib.a` should be referenced in the build file by ``.
151 |
--------------------------------------------------------------------------------
/build.rs:
--------------------------------------------------------------------------------
1 | use std::error::Error;
2 |
3 | fn main() -> Result<(), Box> {
4 | cc::Build::new().file("some-c-code/gcd.c").compile("def");
5 |
6 | let bindings = bindgen::builder()
7 | .header("some-c-code/gcd.h")
8 | .allowlist_function("gcd")
9 | .generate()?;
10 |
11 | bindings.write_to_file("src/bindings.rs")?;
12 |
13 | println!("cargo:rerun-if-changed=some-c-code");
14 | println!("cargo:rerun-if-changed=build.rs");
15 | Ok(())
16 | }
17 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | From Rust + C to Web Assembly with the help of Zig
7 |
8 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/some-c-code/gcd.c:
--------------------------------------------------------------------------------
1 | #include "gcd.h"
2 |
3 | int gcd(int i, Pair* ps) {
4 | int gcd;
5 | for (; i <= ps->n && i <= ps->m; ++i) {
6 | // Checks if i is factor of both integers
7 | if (ps->n % i == 0 && ps->m % i == 0)
8 | gcd = i;
9 | }
10 |
11 | return gcd;
12 | }
13 |
--------------------------------------------------------------------------------
/some-c-code/gcd.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file def.h
3 | * @brief This is an example header file providing functionality XYZ.
4 | * @author John Doe
5 | * @date January 1, 2024
6 | */
7 |
8 | /**
9 | * @brief This structure represents a pair of integers
10 | */
11 | typedef struct Pair {
12 | int n;
13 | int m;
14 | } Pair;
15 |
16 | /**
17 | * @brief This function performs the greatest common division (gcd) of a `Pair`
18 | *
19 | * @param i Minimum gcd to search for.
20 | * @param ps Pair of integers to find the gcd.
21 | * @return Greatest common divisor of `ps` that is larger or equal to `i`.
22 | */
23 | int gcd(int i, Pair* ps);
--------------------------------------------------------------------------------
/some-c-code/main.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "gcd.h"
4 |
5 | int main() {
6 | Pair ps;
7 | printf("Enter two integers: ");
8 | scanf("%d %d", &ps.n, &ps.m);
9 | printf("G.C.D of %d and %d is %d.", ps.n, ps.m, gcd(0, &ps));
10 | }
--------------------------------------------------------------------------------
/src/bindings.rs:
--------------------------------------------------------------------------------
1 | /* automatically generated by rust-bindgen 0.69.4 */
2 |
3 | #[doc = " @brief This structure represents a pair of integers"]
4 | #[repr(C)]
5 | #[derive(Debug, Copy, Clone)]
6 | pub struct Pair {
7 | pub n: ::std::os::raw::c_int,
8 | pub m: ::std::os::raw::c_int,
9 | }
10 | #[test]
11 | fn bindgen_test_layout_Pair() {
12 | const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit();
13 | let ptr = UNINIT.as_ptr();
14 | assert_eq!(
15 | ::std::mem::size_of::(),
16 | 8usize,
17 | concat!("Size of: ", stringify!(Pair))
18 | );
19 | assert_eq!(
20 | ::std::mem::align_of::(),
21 | 4usize,
22 | concat!("Alignment of ", stringify!(Pair))
23 | );
24 | assert_eq!(
25 | unsafe { ::std::ptr::addr_of!((*ptr).n) as usize - ptr as usize },
26 | 0usize,
27 | concat!("Offset of field: ", stringify!(Pair), "::", stringify!(n))
28 | );
29 | assert_eq!(
30 | unsafe { ::std::ptr::addr_of!((*ptr).m) as usize - ptr as usize },
31 | 4usize,
32 | concat!("Offset of field: ", stringify!(Pair), "::", stringify!(m))
33 | );
34 | }
35 | extern "C" {
36 | #[doc = " @brief This function performs the greatest common division (gcd) of a `Pair`\n\n @param i Minimum gcd to search for.\n @param ps Pair of integers to find the gcd.\n @return Greatest common divisor of `ps` that is larger or equal to `i`."]
37 | pub fn gcd(i: ::std::os::raw::c_int, ps: *mut Pair) -> ::std::os::raw::c_int;
38 | }
39 |
--------------------------------------------------------------------------------
/src/lib.rs:
--------------------------------------------------------------------------------
1 | pub mod bindings;
2 |
--------------------------------------------------------------------------------
/src/main.rs:
--------------------------------------------------------------------------------
1 | use rust_ffi_playground::bindings::{gcd, Pair};
2 |
3 | fn main() {
4 | let ps = &mut Pair { n: 6, m: 3 };
5 | let a = unsafe { gcd(3, ps) };
6 |
7 | println!("Hello, world! {}", a);
8 | }
9 |
--------------------------------------------------------------------------------