{"id":17654914,"url":"https://github.com/grandchild/c-library-autoreload-from-rust","last_synced_at":"2026-05-17T10:37:02.495Z","repository":{"id":224431791,"uuid":"763235725","full_name":"grandchild/c-library-autoreload-from-rust","owner":"grandchild","description":"Automatically reload a C library API within a Rust application for rapid debugging","archived":false,"fork":false,"pushed_at":"2024-02-25T23:36:41.000Z","size":10,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-22T17:51:12.737Z","etag":null,"topics":["autoreload","c","debugging","dynamiclibrary","example","ffi","library","prototyping","reloading","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/grandchild.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-25T22:19:03.000Z","updated_at":"2024-02-25T22:27:21.000Z","dependencies_parsed_at":"2024-02-25T23:38:58.149Z","dependency_job_id":null,"html_url":"https://github.com/grandchild/c-library-autoreload-from-rust","commit_stats":null,"previous_names":["grandchild/c-library-autoreload-from-rust"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/grandchild/c-library-autoreload-from-rust","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grandchild%2Fc-library-autoreload-from-rust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grandchild%2Fc-library-autoreload-from-rust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grandchild%2Fc-library-autoreload-from-rust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grandchild%2Fc-library-autoreload-from-rust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/grandchild","download_url":"https://codeload.github.com/grandchild/c-library-autoreload-from-rust/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grandchild%2Fc-library-autoreload-from-rust/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33135105,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-17T09:28:26.183Z","status":"ssl_error","status_checked_at":"2026-05-17T09:27:52.702Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["autoreload","c","debugging","dynamiclibrary","example","ffi","library","prototyping","reloading","rust"],"created_at":"2024-10-23T12:40:17.932Z","updated_at":"2026-05-17T10:37:02.478Z","avatar_url":"https://github.com/grandchild.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dynamic-Library Autoreload in Rust\n\n\n## What is this?\n\nAn example of how to auto-reload a dynamic C library from Rust whenever the\nunderlying C library file changes. This is immensely useful for rapid\nprototyping and short debug cycles.\n\nIt contains a simple C library and a Rust application that uses it. The library\nis reloaded whenever it's recompiled, and the Rust application continues to use\nthe new library functions without needing to be restarted.\n\n\n### Initial Situation\n- A dynamically-linked library (`.so` or `.dll` or `.dylib` file)\n- The library has a C API/ABI\n- A Rust application using said API\n- The _library_ is under development\n- The feedback cycle from library changes is too long, i.e. restarting the app\n  often is manual \u0026 cumbersome\n\n### What We Want\n- The Rust application should continuously run library code\n- When the library file changes, the library is reloaded\n- The Rust application should not need to be restarted\n- The Rust application should not need to be recompiled\n\n### The Plan\n- Load the library dynamically\n- Check mtime of the library file every second\n- If the mtime has changed, reload the library which updates the function\n  pointers\n- Resume using the library functions\n\n### How It's Done\n- Use either [`libloading`](https://crates.io/crates/libloading) or the two\n  available APIs of [`dlopen2`](https://crates.io/crates/dlopen2) to load the\n  library dynamically\n- Use `std::fs::metadata` to get the mtime of the library file\n- Use `std::thread::sleep` to wait for a second\n- Repeat\n\n\n## Run\n\nBuild the library:\n\n```sh\ncmake -B build\ncmake --build build\n```\n\nRun the Rust application:\n\n```sh\ncargo run\n```\n\nNow you can edit [src/lib.c](src/lib.c) and re-run `cmake --build build` to see\nthe changes reflected in the running Rust application:\n\n\n```sh\n# In Rust Land                            # In C Land\n\n$ cargo run | ts -s\n  ...\n00:00:03 foo() -\u003e 4\n00:00:03 bar() is not defined         # Editing to change `foo()` and add `bar()`\n00:00:04 foo() -\u003e 4                   $ cmake --build build\n00:00:04 bar() is not defined         [ 50%] Building C object CMakeFiles/foo.dir/src/lib.c.o\n00:00:05 foo() -\u003e 4                   [100%] Linking C shared library libfoo.so\n00:00:05 bar() is not defined         [100%] Built target foo\n00:00:06 Reloading \"build/libfoo.so\"\n00:00:06 foo() -\u003e 5\n00:00:06 bar() -\u003e 10\n00:00:07 foo() -\u003e 5\n00:00:07 bar() -\u003e 10\n  ...\n```\n\n(If you don't know `ts`, then check out the\n[`moreutils`](https://joeyh.name/code/moreutils) package, there's some nice\ngadgets in there!)\n\n## Inspect\n\n- [CMakeLists.txt](CMakeLists.txt) - The manifest for the C library\n- [src/lib.c](src/lib.c) - The C library\n\n- [Cargo.toml](Cargo.toml) - The manifest for the Rust application\n- [src/main.rs](src/main.rs) - The Rust application\n\nIn the Rust application there are three similar sections, the first for\n`libloading`, the other two for `dlopen2`'s two APIs. Only one of the sections\nmay be uncommented at a time. Use the `//*`/`/*` trick at the beginning of\na section to toggle it with a single character.\n\n\n## Caveats\n\n- The C library functions are exported via `__attribute__` which probably only\n  works out of the box in GCC/Clang.\n- Tested only with GCC on Linux.\n\n## License\n\nCC0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrandchild%2Fc-library-autoreload-from-rust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgrandchild%2Fc-library-autoreload-from-rust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrandchild%2Fc-library-autoreload-from-rust/lists"}