Skip to content

Using a class from an external crate generate an extension conflict #1078

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

Closed
gcesars opened this issue Mar 12, 2025 · 5 comments
Closed

Using a class from an external crate generate an extension conflict #1078

gcesars opened this issue Mar 12, 2025 · 5 comments
Labels
status: duplicate This issue or pull request already exists

Comments

@gcesars
Copy link

gcesars commented Mar 12, 2025

I am trying to organize the code and avoid a huge library with the entire game and data logic in a single file.

Let's say I have a crate_a with a class/resource and a crate_b that needs to refer to this class for any reason.

Just by adding use crate_a::class_name in the crate_b library, it stops working. However, it compiles and runs the game.

The error is: ERROR: Attempt to register extension class 'InputManager', which appears to be already registered.

My guess is that the class is being registered when the library_a is loaded and it is being registered again when library_b is loaded.

Is this a user error? How to avoid it?

@Bromeon
Copy link
Member

Bromeon commented Mar 13, 2025

Can you elaborate your crate setup?

Are the two crates both cdylib? Dependencies?

@gcesars
Copy link
Author

gcesars commented Mar 13, 2025

For sure:

crate_a cargo.toml:

[package]
name = "game"     # Part of dynamic library name; we use {YourCrate} placeholder.
version = "0.1.0" # You can leave version and edition as-is for now.
edition = "2024"

[lib]
crate-type = ["cdylib", "lib"] # Compile this crate to a dynamic C library.

[dependencies]
godot = { workspace = true }

crate_b cargo.tml:

[package]
name = "level"    # Part of dynamic library name; we use {YourCrate} placeholder.
version = "0.1.0" # You can leave version and edition as-is for now.
edition = "2024"

[lib]
crate-type = ["cdylib", "lib"] # Compile this crate to a dynamic C library.

[dependencies]
godot = { workspace = true }
game = { version = "0.1.0", path = "../game" }

I need to include "lib" in the crate type. Otherwise, crate_a cannot be referred to in crate_b. I think this might be the issue.

Both crates have one declared class with some #[extern] fields.

Without crate_b referring crate_a in use statement, I can see both classes in the editor and the game logic works.

@Bromeon
Copy link
Member

Bromeon commented Mar 13, 2025

I need to include "lib" in the crate type. Otherwise, crate_a cannot be referred to in crate_b. I think this might be the issue.

Yes, indeed. There are some general problems with this setup in Rust, see e.g. "Problems" section in #986.

But you'll find most information + some trade-offs in #951. In short, dependencies between libraries is a workflow that's not properly supported yet, and there are probably a few things we need to do to avoid errors like these.

@gcesars
Copy link
Author

gcesars commented Mar 13, 2025

Thanks.
For now, I'm just exploring and learning. Having all logic in a single library isn't a big deal.
It is a problem in the long term, though. The compilation time will increase, and patching will become more complex.
I hope the team can figure it out eventually.
Apologies for not being capable of contributing to the solution.

@Bromeon
Copy link
Member

Bromeon commented Mar 13, 2025

All good, no worries! I agree it's an important topic 🙂

I'll close this in favor of #951 to keep things in one place, but in case you have more input on this topic in the future, feel free to comment there directly!

@Bromeon Bromeon closed this as completed Mar 13, 2025
@Bromeon Bromeon added the status: duplicate This issue or pull request already exists label Mar 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

2 participants