-
Notifications
You must be signed in to change notification settings - Fork 5
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
Add build script for Linux, update readme. #52
Conversation
This works fantastic for the project I tested this with. #[cfg(target_os = "linux")]
{
let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
let api_loc = [
format!("./fmod/api/core/lib/{target_arch}"),
format!("./fmod/api/studio/lib/{target_arch}")
];
for loc in api_loc {
println!("cargo:rustc-link-search={loc}");
println!("cargo:rustc-env=LD_LIBRARY_PATH={loc}");
}
} the library structure fmod provides is already sorted by arch, so this seemed a bit nicer to me in my case. Apologies if I'm jumping the gun a bit. I also don't think it makes sense to copy the files for debug builds, I don't see an advantage or difference, other than time spent copying files. On another note, it does not break the |
Glad to hear you got it working! I like this direction but I have two problems:
format!("./fmod/api/core/lib/{target_arch}"),
format!("./fmod/api/studio/lib/{target_arch}") to something like format!("./fmod/api/combined/lib/{target_arch}") and put all the SO files in there, then it does work. I wonder if I missed anything or if there is maybe a difference between distros on how this is handled?
Btw if you can expand a bit more on "you need to set the LD_LIBRARY_PATH when running it as well." I would highly appreciate it! As for this:
This was just an idea for a workaround to get dynamic-linking working, but it sounds like that won't be necessary anymore :) |
No idea how to replicate the issue, could you tell me a bit more on how you got this? Perhaps which one wasn't found? Somehow I'm doubting that it's a distro issue. Hmm, according to https://doc.rust-lang.org/reference/conditional-compilation.html#target_arch Regarding runtime linking, it's fairly trivial. If you're running the resulting binary directly, you have to specify the target/debug/deps:~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib:./fmod/api/core/lib/x86_64:./fmod/api/studio/lib/x86_64:$LD_LIBRARY_PATH So depending on how you'd like run it, either place this in your IDEs env config for launch targets, or
|
What I did was clone the repo, add a build.rs with your solution, add the fmod libs as you described and then I ran
was overriding the first one, but then I changed LD_LIBRARY_PATH to LD_RUN_PATH and the environment variable in my IDE config to |
I feel like instead of using the IDE it should also be possible to use a config.toml to set the env variable, but I haven't managed to make it work so far. It would be nice to have a solution that is IDE agnostic but also not just executing a raw executable. Anyways I have added the improvements we have so far, thank you for helping out! |
It would be possible to make an ide independent solution with cargo-make for example, but that would be yet another dependency. It should be possible to set run time env in the config, or .cargo/ at least, not sure if that's ideal. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this logic work in a built game? Once built, the files are in target/release
. When a developer ships his game, only that folder will be shipped. How do we bundle the libraries?
Btw, this might be also an issue for windows, needs investigation.
- Create a new folder `fmod` in the root of your project. | ||
- Extract the `api` folder into it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we replicate the behavior of windows of putting these files into the root?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO that will get real ugly real soon, as that's 12 files you would be adding to your project root. And if you are shipping the game for different target architectures on linux you need the folders anyways. And if we add the Steam Audio plugin later it's going to be even more lib files in the root.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's also less work for the user this way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case, we should streamline this for all platforms, including Windows. Not sure what convention to use. I've seen in other projects written in different languages the use of a ./vendor
folder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we use a different folder than root for Windows then Windows users will also need to use a build.rs... Maybe let's decide on this in a different PR/issue?
let mut target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); | ||
|
||
// Account for the naming mismatch between FMOD library folders and the target architecture | ||
if target_arch == "aarch64" { | ||
target_arch = "arm64".into(); | ||
} | ||
|
||
let api_loc = [ | ||
format!("./fmod/api/core/lib/{target_arch}"), | ||
format!("./fmod/api/studio/lib/{target_arch}"), | ||
]; | ||
for loc in api_loc { | ||
println!("cargo:rustc-link-search={loc}"); | ||
println!("cargo:rustc-env=LD_RUN_PATH={loc}"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we wrap this logic into a function of the library? That way, a developer doesn't have to copy all of this code, but only call a function in his build.rs
file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's possible, but the user will have to add a separate dependency under [build-dependencies] in their Cargo.toml. It cannot be combined afaik. I can look into it if you think that's the way to go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really annoying how much of a hassle it is to link to dynamic libraries in Rust.
Would love to find a simple and consistent across platforms solution.
For shipping a game, I added this line in the build.rs comments which should give enough direction hopefully: I think on Windows you can just put the dll's in the same folder as the exe, but I haven't tried it out yet. |
A comment in build.rs has no visibility to the developer unless included in the documentation.
If you mean the Question: On Windows (maybe) and macOS, it works like that. Can you put the FMOD *.so files next to the binary, and it automatically recognizes them? In that case, it might make more sense to replace the proposed solution here with a bundling mechanism. It will copy the dynamic libraries from some folder in the repository to the output folder. |
Bundling and shipping the game/app is up to the user, this is a library, it cannot decide how the app is going to be built. All that can be done is guide users towards potential solutions that might fit their use cases. For dev builds, copying files has no benefit, using dynamic linking the way it is intended makes much more sense to me. Ultimately you don't have to dynamically link at all if you don't want to, if you'd rather avoid the clutter. For a release build that's likely preferable anyway. Regarding the visibility of build.rs, it's highly visible to anyone looking at the included examples and wanting to figure out how to use this library. It should also be mentioned in documentation/readme, but saying it has no visibility seems rather odd. |
Co-authored-by: Fabian Fritzsche <salzian.dev@gmail.com>
Closes #3. It may not be ideal (breaks Bevy dynamic_linking) but hopefully someone with more Linux experience comes along as we continue working on this crate. Edit: This is no longer an issue.