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

Enable Windows for Android emulator and JVM #240

Closed
2 tasks done
thunderbiscuit opened this issue May 18, 2022 · 12 comments
Closed
2 tasks done

Enable Windows for Android emulator and JVM #240

thunderbiscuit opened this issue May 18, 2022 · 12 comments

Comments

@thunderbiscuit
Copy link
Member

thunderbiscuit commented May 18, 2022

Let's get these two working for the Android emulator and JVM:

  • x86_64-pc-windows-gnu 64-bit MinGW (Windows 7+)
  • x86_64-pc-windows-msvc 64-bit MSVC (Windows 7+)
@thunderbiscuit thunderbiscuit transferred this issue from bitcoindevkit/bdk-kotlin Nov 15, 2022
@thunderbiscuit thunderbiscuit changed the title Enable local build on Windows Enable Windows Nov 17, 2022
@thunderbiscuit thunderbiscuit changed the title Enable Windows Enable Windows for Android emulator and JVM Nov 17, 2022
@yellowHatpro
Copy link
Contributor

Hello @thunderbiscuit., I am willing to contribute to this feature. However, I only have a little knowledge regarding this. Can you help me get started with understanding the issue?
Any resources for that matter will be sufficient.

@thunderbiscuit
Copy link
Member Author

thunderbiscuit commented Mar 29, 2023

I think the first step for this is to use the workflow in the Gradle plugins we developed. Take time to review the code in there and see what it does. If you have access to a macOS or Linux operating system that will help you because you'll be able to see the files in your directories and see them move. You can basically call the commands one at a time to reproduce what the plugins are doing.

When calling the cargo build ... command, you're building the binary files you'll need to add to the correct directories to make them accessible from a Windows environment. I'm not sure if the files will be called something like libbdkffi.so or another extension, but that's what you'd need to move into the correct directories under something like bdk-jvm/lib/src/main/resources/windows-something-something/.

This is probably a bit vague but I don't know the exact names of the files and directories you'll get when you build on Windows. You'll probably need to fiddle around with it a bit.

Note that you'll need to add the triple above as a compilation target for your cargo tool (something like):

rustup target add x86_64-pc-windows-gnu

And from there your build command might look something like

cargo build --profile release-smaller --target x86_64-pc-windows-gnu

And you'll have to see what comes out in your target/ directory.

Feel free to use this thread as a place to ask questions.

@yellowHatpro
Copy link
Contributor

@thunderbiscuit is the generated bdk.kt file a sign of a successful build??
I was able to generate it on my windows machine.

@thunderbiscuit
Copy link
Member Author

Yes that's a great start. The bindings really come down to two things:

  1. A file like bdk.kt
  2. A binary file like libbdkffi.so.

The bdk.kt file references that binary library file. Building and connecting the two is the crux of the problem here, and I think you're going in the right direction for sure.

@yellowHatpro
Copy link
Contributor

@thunderbiscuit Yeah I was able to generate both. A small change here, though, is the format. I think the binary file format is .dll in windows, not .so . I made the changes in the UniFfiJvmPlugin file accordingly. What should be the next step I should follow??

@thunderbiscuit
Copy link
Member Author

thunderbiscuit commented Apr 2, 2023

Oh sweet ok yes that makes sense. Ok well step 1: you don't need to tag me in every message 🤣 (I am a maintainer of this repo so I get all messages/replies/PRs/issues).

Step 2: You'll need the plugin to understand when it's being used on a Windows machine, and to have an enum variant for that in the Enums.kt file. From there you'll need custom logic to trigger the build command for the Windows target(s) (not sure which one you need of the two options above) and to move the binary files in their correct directories (I don't know what those would be for Windows I think you'll need to trial/error a bit for that or Stack Overflow).

https://github.com/bitcoindevkit/bdk-ffi/blob/master/bdk-jvm/plugins/src/main/kotlin/org/bitcoindevkit/plugins/UniFfiJvmPlugin.kt#L16-L85

@yellowHatpro
Copy link
Contributor

Sowwy for the first step 🤣
I figured out the build command for the windows, but it's gonna be somewhat messy. I tried the x86_64-pc-windows-gnu target, but the ring crate gives an error with it.
So we are left with x86_64-pc-windows-msvc target, with which everything works fine. But, to make it the default host, we need Visual Studio build tools on the local machine.
I will make an enum entry for the Enums file, but is figuring out the target name enough? ( x86_64-pc-windows-msvc in this case)

@thunderbiscuit
Copy link
Member Author

Mmmm ok. The ring crate giving you an error is super common, there are a few different places where this has come up.

Are you attempting to build the bdk-jvm library first or the bdk-android? (start with bdk-jvm if you can). You're right I don't know how we should go about deciding which one of those two to build if the user has Windows. Assume it is whatever it is on your machine and you can make work, and from there we can iterate and add extra logic maybe to decide or choose between different builds (for example if the gradle task had an optional flag where you could ask which version of the Windows build you want to trigger). For now let's just keep it simple; if you can make it work on your machine, any of the two above is already a big win. We can work on enabling the other after that.

Just putting this here for future reference: https://rust-lang.github.io/rustup/installation/windows.html

@yellowHatpro
Copy link
Contributor

Yeah I am building bdk-jvm first.
Ok so now my current goals are :

  1. Add enums for windows machine
  2. Check the cause of the failure of the ring crate/ is it possible to build using x86_64-pc-windows-gnu
  3. Make corresponding changes in the UniFfiJvmPlugin file, and add values for the windows machine.

I will try to raise a PR soon. Hope I am in the right direction

@yellowHatpro
Copy link
Contributor

enters
image
leaves

@yellowHatpro
Copy link
Contributor

yellowHatpro commented Apr 4, 2023

So I was able to build the bdk ffi lib, and after locally using the repo, I was finally able to run the tatooine server (in windows).
There are a couple of tricks involved rn, but I think I finally figured out how things work in windows (i suppose).

@thunderbiscuit
Copy link
Member Author

thunderbiscuit commented Jul 7, 2023

Thanks for all the hard work on this, the bdk-jvm version compatible with Windows is now out!

After looking into the two targets for Windows, I now think that supporting x86_64-pc-windows-msvc is all we need. If ever there is a request for the other target we can revisit.

Here is what ChatGPT had to say about the difference between the two targets:

Quoting ChatGPT

In Rust, when you target Windows, you have two major options for the ABI (Application Binary Interface) and the toolchain you can use. These two options are represented by the targets x86_64-pc-windows-gnu and x86_64-pc-windows-msvc.

  1. x86_64-pc-windows-gnu:

    • This target uses the GCC toolchain on Windows, specifically the MinGW-w64 distribution of GCC.
    • It uses the GNU ABI.
    • It is generally more compatible with C libraries that are compiled with GCC.
    • You may find this target more familiar if you are coming from a Unix-like environment.
    • The produced binaries depend on mingw runtime libraries.
    • It can be somewhat less performant compared to MSVC, especially if not properly optimized.
  2. x86_64-pc-windows-msvc:

    • This target uses the Microsoft Visual C++ (MSVC) toolchain.
    • It uses the MSVC ABI.
    • It is generally more compatible with libraries and tools in the Windows ecosystem.
    • It is often seen as more "native" for Windows development.
    • The produced binaries depend on the Microsoft Visual C++ Runtime.
    • The compiler tends to have better optimizations and debugging experience on Windows.

Which one to choose depends on your specific needs. If you are interfacing with libraries that are compiled with MSVC or if performance is critical, you might choose the MSVC target. If, however, you are porting software from a Unix-like environment, or dealing with libraries that are compiled with GCC, then the GNU target might be more appropriate.

In practice, the MSVC target is more commonly used for Windows development unless there are specific reasons to prefer the MinGW toolchain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Status: Done
Development

No branches or pull requests

3 participants