Skip to content

Dynamically load JACK. #162

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

Merged
merged 23 commits into from
Feb 6, 2022
Merged

Dynamically load JACK. #162

merged 23 commits into from
Feb 6, 2022

Conversation

wmedrano
Copy link
Member

@wmedrano wmedrano commented Feb 5, 2022

Resolves #159

j::jack_set_buffer_size_callback(client, Some(buffer_size::<N, P>), data_ptr);
j::jack_set_sample_rate_callback(client, Some(sample_rate::<N, P>), data_ptr);
j::jack_set_client_registration_callback(
(LIB.jack_set_thread_init_callback)(client, Some(thread_init_callback::<N, P>), data_ptr);
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm confused by this. The dlib documentation says you need to use the ffi_dispatch! macro for this.

Copy link
Member Author

Choose a reason for hiding this comment

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

You don't really need it. I could update all the callers to enable static and dynamic dispatch.

Copy link
Member Author

@wmedrano wmedrano Feb 5, 2022

Choose a reason for hiding this comment

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

Full disclosure: I couldn't get the macro to work.

Other thing the dlib library seemed not to work well is specifying both statics and functions in the same external_library! definition. Even the README's example does not compile.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not being able to link directly defeats the purpose of using dlopen instead of using libloading directly.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed ffi_dispatch!. The issues I ran into were lack of support for trailing commas and no support for functions that don't have any arguments. The latter cases were handled manually, luckily there were only a couple of them.

Copy link
Contributor

Choose a reason for hiding this comment

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

Great, thanks for taking care of that. I suggest reporting those issues upstream.

@Be-ing
Copy link
Contributor

Be-ing commented Feb 5, 2022

Two big issues with this branch currently:

  1. There is no option to link libjack at build time. Perhaps this could be an issue for Linux distros? I'm not sure. It does defeat the purpose of using dlopen though.
  2. It searches for libjack.so at runtime which is provided by {pipewire-}jack-audio-connection-kit-devel on Fedora. libjack.so.0 is the file provided by the non-devel packages.

@wmedrano
Copy link
Member Author

wmedrano commented Feb 5, 2022

Updated to:

  • Allow static linking or dynamic through dlopen feature.
  • Use ffi_dispatch
  • Dynamically load from libjack.so.0.

pub const JACK_LIB: &'static str = "libjack.dll";

#[cfg(not(windows))]
pub const JACK_LIB: &'static str = "libjack.so.0\0";
Copy link
Contributor

@Be-ing Be-ing Feb 5, 2022

Choose a reason for hiding this comment

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

@Be-ing
Copy link
Contributor

Be-ing commented Feb 5, 2022

This is working on Fedora 35 now.

Using dlopen feature:

  1. sudo dnf remove pipewire-jack-audio-connection-kit
  2. Build application
  3. jack::Client::new returns Err(LoadLibraryError("Could not open the requested library: libjack.so.0: cannot open shared object file: No such file or directory")) as expected.
  4. sudo dnf install pipewire-jack-audio-connection-kit (without -devel package)
  5. Application works

Without dlopen feature:

  1. sudo dnf remove pipewire-jack-audio-connection-kit
  2. Build application
  3. Application build fails to link jack as expected.
  4. sudo dnf install pipewire-jack-audio-connection-kit-devel
  5. Build application
  6. Application works

@Be-ing
Copy link
Contributor

Be-ing commented Feb 5, 2022

I made a PR to fix the platform-specific library names: #164. It is working on Linux. I will test it on macOS and Windows.

* jack-sys: fix platform-specific dynamic library names

* jack-sys: do not use pkg-config with dlopen feature

If there happens to be a pkgconfig file but no libjack, downstream
applications may fail to link.
@Be-ing
Copy link
Contributor

Be-ing commented Feb 6, 2022

I tested #164 on macOS (x86-64) and Windows (x86-64 in QEMU-KVM). macOS is definitely working with and without the dlopen feature. On Windows, I got my application to run with dlopen and I think it connected to the JACK server. I wasn't able to really test if it was functional because my application's GUI depends on OpenGL which I guess wasn't available in the VM and I don't feel like investing the effort to get that working right now. However, when I commented out my application's GUI, the application did run. Curiously QJackCtl froze while my application was running, but I don't know if that's some artifact of virtualization or what. What matters for the sake of this PR is that it linked and the application loaded libjack without crashing. Without dlopen I was not able to get the application to link on Windows.

So I think this is ready to merge!

@wmedrano wmedrano merged commit cd561d9 into main Feb 6, 2022
@Be-ing
Copy link
Contributor

Be-ing commented Feb 6, 2022

Yaaaay! I'll make a PR to document the new behavior.

@Be-ing
Copy link
Contributor

Be-ing commented Feb 11, 2022

I got cross compiling to x86_64-pc-windows-gnu, x86_64-apple-darwin, and aarch64-apple-darwin from x86-64 Linux working! For macOS I had to use osxcross following this guide. So now it's possible to build cross platform JACK applications from Linux without even needing to build or link C! 🚀

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.

dynamically load libjack at runtime instead of linking
2 participants