Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow users to specify a crate version for bindings generation #901

Merged
merged 1 commit into from
Feb 26, 2024

Conversation

IceTDrinker
Copy link
Contributor

  • this is useful in a setting where several crates may share the same name in e.g. a semver trick setting https://github.com/dtolnay/semver-trick to allow adding compatibility code to older versions of a crate to allow users to migrate towards newer version of a crate
  • this is a pure addition and should keep all existing behaviors exactly the same

this is a PR that attemps to solve #900 in a way that does not break anything that already works with cbindgen as this is a pure addition to the code base leaving all existing behaviors untouched (other solutions may involve canonicalizing paths which may panic in places where there were no panics and may cause issues for any build systems with symlinks and network disks).

This is akin to cargo's package spec e.g. cargo build -p my_crate@0.1.0 to allow disambiguating which crate the command is referring to in cases where several crates either share the same name or several version of the same crates happen to be in the dependency/cargo metadata for a given project. The good news is that the package version is populated by Cargo in the environment when in a build system so it is easy to use for build script users. For binary users a quick parsing of their Cargo.toml with theri favorite Unix utils should be enough

To avoid changing flags a separate flag is added to the cbindgen binary and a with_crate_version is added to the cbindgen Builder to be able to use that in a build script.

@emilio as indicated in the contributing.md I am requesting a code review for this PR, I'm not quite sure how to write a test case for this right now, if you have some pointers? Maybe a separate crate_version file akin to what the profile test file might be doing ?

Cheers

@IceTDrinker
Copy link
Contributor Author

hello any news on that @emilio I guess (?) or @mversic sorry if I'm not pinging the right persons, but if this PR does not get a chance to progress we likely will have to publish a custom version of cbindgen and I'd prefer avoiding that

I'm afraid the deadline is too close anyways for us to hold out longer on this :|

Copy link
Contributor

@mversic mversic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. But I don't have maintainer privileges so I can't do anything

@mversic
Copy link
Contributor

mversic commented Jan 4, 2024

but I also think this could be resolved without introducing another flag

@IceTDrinker
Copy link
Contributor Author

but I also think this could be resolved without introducing another flag

Definitely agree, the thing is I have no idea how cbindgen might be used in the wild, not being a maintainer myself I chose a path of least resistance and safety with respect to the current behavior, adding a new flag and keeping the old default behavior was a way to guarantee things would work as before for people not aware/needing the flag.

Let me know what should be done here (not sure there is a « simple » way to derive a crate’s version apart from using the cargo env var about the version but that would make cbindgen depend on the cargo environment being there and set-up which I believe is not the case today)

@IceTDrinker
Copy link
Contributor Author

@mversic I think I have something which looks to be working with manifest paths, it probably can break things with people using relative paths so I added a fallback that has the old behavior of returning the first package that has been found, otherwise it means cbindgen needs to canonicalize some paths and this can result in panics that could never occur before

@IceTDrinker IceTDrinker force-pushed the am/feat/specify-crate-version branch 2 times, most recently from 3cb23c9 to 3092504 Compare January 4, 2024 11:00
- the old code was selecting the first package that was found which meant
that dependencies with the same name could be used for bindgen instead of
the intended package
- a fallback to the old behavior is kept for now in case manifest paths are
not matching because of relative paths for example
- this should be backwards compatible with all cbindgen usage, the
selection bug may still trigger in case the manifest path does not match
@IceTDrinker
Copy link
Contributor Author

IceTDrinker commented Jan 11, 2024

Gentle ping @emilio it was suggested on Zulip I pinged you here on this PR for issue #900.

Recap:

cbindgen parses the cargo metadata based on name only, which fails randomly to select the proper crate for cbindgen if a dependency has the same name as the main crate (as the cargo metadata is in a hash table).

I had a first implementation that was a pure addition, old code can still be found here: https://github.com/IceTDrinker/cbindgen/tree/saved/am/feat/specify-crate-version-v0

The first approach to a fix linked above is 100% backwards compatible by adding a new setting for the bindgen.

The current PR has a different approach validating the Cargo manifest path, issue here is I'm not sure it manages all edge cases with e.g. unresolved paths like relative paths. Canonicalizing paths could introduce panics that did not exist before, so I went for a middle ground which tries to validate the manifest path, and if it does not succeed falls back to the old behavior.

Would be happy to help or chat on the channel that is more convenient for you.

I'm unfortunately a bit time pressed and if the patch does not land in a release before January 19th we'll publish a crate which is cbindgen + that patch under a name that is distinct enough that it won't interfere with cbindgen on crates.io and will allow us to release

Cheers

Copy link
Collaborator

@emilio emilio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to get a test for this...

@emilio emilio merged commit f1d5801 into mozilla:master Feb 26, 2024
@IceTDrinker
Copy link
Contributor Author

Would be good to get a test for this...

Fully agree, if you have pointers on how to write them I'll take it, I was not quite sure how the test system worked

zshipko pushed a commit to extism/extism that referenced this pull request Aug 22, 2024
Updates the requirements on
[cbindgen](https://github.com/mozilla/cbindgen) to permit the latest
version.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/mozilla/cbindgen/blob/master/CHANGES">cbindgen's
changelog</a>.</em></p>
<blockquote>
<h1>0.27.0</h1>
<pre><code>  * Revert: The `Config` struct now has a private member.
* Allow users to specify a crate version for bindings generation
([#901](mozilla/cbindgen#901)).
* Update MSRV to 1.74
([#912](mozilla/cbindgen#912),
[#987](mozilla/cbindgen#987)).
* Support #[deprecated] on enum variants
([#933](mozilla/cbindgen#933)).
* Support integrating the package_version information in a header file
comment ([#939](mozilla/cbindgen#939)).
* Add a language backend
([#942](mozilla/cbindgen#942)).
* Support generics with defaulted args
([#959](mozilla/cbindgen#959)).
* Add `VaList` compatibility
([#970](mozilla/cbindgen#970)).
</code></pre>
<h1>0.26.0</h1>
<pre><code>  * Fix swapping of `&gt;&gt;=` and `&lt;&lt;=` in constants.
* Add support for #[deprecated]
([#860](mozilla/cbindgen#860)).
  * Built-in support for bitflags 2.0.
  * Support for &quot;C-unwind&quot; ABI.
* Generate bindings for non-public extern items if they are
#[no_mangle].
</code></pre>
<h2>0.25.0</h2>
<pre><code>  * Re-release of yanked 0.24.6 as a major release
  * Update MSRV to 1.57
* Support variadic arguments (`...`)
([#805](mozilla/cbindgen#805))
* Add --depfile option
([#820](mozilla/cbindgen#820))
  * Breaking changes: The `Config` struct now has a private member.
</code></pre>
<h2>0.24.6 (YANKED: depfile option was breaking, see <a
href="https://redirect.github.com/mozilla/cbindgen/issues/841">#841</a>)</h2>
<pre><code>  * Update MSRV to 1.57
* Support variadic arguments (`...`)
([#805](mozilla/cbindgen#805))
* Add --depfile option
([#820](mozilla/cbindgen#820))
</code></pre>
<h2>0.24.5</h2>
<pre><code>  * Don't enforce tempfile version.
</code></pre>
<h2>0.24.4</h2>
<pre><code> * Move expand infinite recursion fix
([#799](mozilla/cbindgen#799))
* Add with_cpp_compat to the builder
([#796](mozilla/cbindgen#796))
* Handle never type in return position consistently
([#780](mozilla/cbindgen#780))
* Fix warnings ([#816](mozilla/cbindgen#816),
[#819](mozilla/cbindgen#819))
* Updated documentation
([#788](mozilla/cbindgen#788),
[#791](mozilla/cbindgen#791),
[#792](mozilla/cbindgen#792),
[#810](mozilla/cbindgen#810),
[#823](mozilla/cbindgen#823))
</code></pre>
<h2>0.24.3</h2>
<pre><code> * Make struct expressions correctly generated through
typedefs ([#768](mozilla/cbindgen#768)).
</code></pre>
<h2>0.24.2</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/mozilla/cbindgen/commit/58c6156b0d91e82abb03c26187b8d18fa4345ce0"><code>58c6156</code></a>
Bump MSRV again for clap.</li>
<li><a
href="https://github.com/mozilla/cbindgen/commit/103a8de0ac1ac311d54843acdfc10ee8c203a3ba"><code>103a8de</code></a>
Cargo update and version bump.</li>
<li><a
href="https://github.com/mozilla/cbindgen/commit/67cb560430cf91fecdd402cd1239d0a51baff634"><code>67cb560</code></a>
Update CHANGES since v0.26.0</li>
<li><a
href="https://github.com/mozilla/cbindgen/commit/316298182ebf508240c95ddf9943556b2fb546e1"><code>3162981</code></a>
Output condition for globals.</li>
<li><a
href="https://github.com/mozilla/cbindgen/commit/e469e44c0027f4ca039a4556f6062c0ba343a5b4"><code>e469e44</code></a>
Add missing parens to log message</li>
<li><a
href="https://github.com/mozilla/cbindgen/commit/3cbb637bbf16c7378ce4d6cb4b73e5d2d2bd33fa"><code>3cbb637</code></a>
Update cython expectations from the previous patch.</li>
<li><a
href="https://github.com/mozilla/cbindgen/commit/785e066e03b0e22a32c31e9adab78a18f6ce195b"><code>785e066</code></a>
Fix variadic arguments when used in function pointer</li>
<li><a
href="https://github.com/mozilla/cbindgen/commit/aa8ea654e156fd1b8e5b1b755c7b43fe4ea81331"><code>aa8ea65</code></a>
deps: Update syn to 2.0</li>
<li><a
href="https://github.com/mozilla/cbindgen/commit/9f632843b8b9dacbdc7a153868a4a9546e196e2e"><code>9f63284</code></a>
Generalize Item to expose documentation and generic params</li>
<li><a
href="https://github.com/mozilla/cbindgen/commit/1dda6162e53df57cb1769e9a6f942f6de839f50b"><code>1dda616</code></a>
Used documented method of specifying variadic arguments</li>
<li>Additional commits viewable in <a
href="https://github.com/mozilla/cbindgen/compare/0.26.0...v0.27.0">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants