{"id":15417059,"url":"https://github.com/ivmarkov/linker-failure","last_synced_at":"2025-04-04T06:25:16.658Z","repository":{"id":77410049,"uuid":"541941431","full_name":"ivmarkov/linker-failure","owner":"ivmarkov","description":null,"archived":false,"fork":false,"pushed_at":"2022-09-27T08:19:35.000Z","size":2,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-09T17:41:53.328Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ivmarkov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2022-09-27T06:44:15.000Z","updated_at":"2022-09-27T06:45:45.000Z","dependencies_parsed_at":"2024-01-17T08:36:46.329Z","dependency_job_id":null,"html_url":"https://github.com/ivmarkov/linker-failure","commit_stats":{"total_commits":1,"total_committers":1,"mean_commits":1.0,"dds":0.0,"last_synced_commit":"f5b0a03ef5ee264fbcf6eeb89008fc1ace00315a"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivmarkov%2Flinker-failure","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivmarkov%2Flinker-failure/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivmarkov%2Flinker-failure/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivmarkov%2Flinker-failure/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ivmarkov","download_url":"https://codeload.github.com/ivmarkov/linker-failure/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247130812,"owners_count":20888658,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-10-01T17:14:33.626Z","updated_at":"2025-04-04T06:25:16.635Z","avatar_url":"https://github.com/ivmarkov.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Linker failure using the `extern \"Rust\" {}` magic\n\nProject dep tree is as follows (`cargo tree):\n```\nmybinary v0.1.0 (/linker-failure/mybinary)\n├── critical-section v1.1.1\n├── mycriticalimpl v0.1.0 (/linker-failure/mycriticalimpl)\n│   └── critical-section v1.1.1\n└── mylib v0.1.0 (/linker-failure/mylib)\n    └── critical-section v1.1.1\n```\n\n## Problem\n\nUPDATE: Analysis below most likely incorrect. There is something ESP-IDF specific in the linking process.\n\nThe above dep-tree (I believe) is linearized in the following library order by the linker:\n```\n[mybinary], [mycriticalimpl], [mylib], [critical-section]\n```\n\nWhat is important in the above order is that `[mycriticalimpl]` is ordered *before* `[critical-section]`:\n- This is so, because \"smart linkers\" like - say - GCC require to see the depending libnraries *before* their dependencies (see [this](https://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-sometimes-cause-errors-in-gcc) for more info)\n- Since `[mycriticalimpl]` depends on `[critical-section]` by using symbols from it, it is ordered before `[critical-section]`. This way the linker can \"record\" what symbols\n  `[mycriticalimpl]` needs and then can try to satisfy these from the subsequent libraries in the link order (`[critical-section]` specifically)\n- The trouble is that the `extern \"Rust\" {}` magic introduces a *circular* dependency between `[mycriticalimpl]` and `[critical-section]` \n  (which is otherwise not allowed in Rust):\n  - On one hand, `[mycriticalimpl]` (obviously) depends on `[critical-section]`, so the order should be `[mycriticalimpl], [critical-section]` \n    (and this is what Rust does, as it \"sees\" this dependency in the dependency graph)\n  - On the other hand, `[critical-section]` *also* depends on `[mycriticalimpl]` via the magic `_critical_section_1_0_acquire` and `_critical_section_1_0_release` symbols!\n  - However, Rust does not \"know\" about this dependency; and even if it did know, the order cannot be both `[mycriticalimpl], [critical-section]` and also `[critical-section], [mycriticalimpl]`...\n  - (such circular dependencies are supported by linkers, but then these circular libraries need to be enclosed in `-lstart-group` / `-lend-group` switches); \n\n## Solution??\n\nI don't have any besides instantiating the `critical_section::set_impl!(mycriticalimpl::cs::MyCriticalSection)` macro *from within the binary crate*. As noted on line 1 in `mybinary/main.rs`.\n\nWhy is that working? No idea (yet).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivmarkov%2Flinker-failure","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fivmarkov%2Flinker-failure","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivmarkov%2Flinker-failure/lists"}