Skip to content

Dynamically linked libraries #35

@paulyoung

Description

@paulyoung

tl; dr

It seems possible to use dynamically linked libraries with the simulator but I can't figure out how to modify the search paths.

Hopefully this is doable on device as well or this is all moot.


I'm depending on a crate that provides bindings for a library, and it expects the library to be dynamically linked.

At first I was getting Undefined symbols for architecture with crank build. I've addressed that with the following build.rs:

use std::{env, path::Path};

fn main() {
    let cargo_manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();

   // This approach doesn't work because the library is named `foo_libqux.dylib`
   /*
    println!(
        "cargo:rustc-link-search=all={}",
        Path::new(&cargo_manifest_dir).join("lib").display()
    );

    println!("cargo:rustc-link-lib=dylib=retro");
   */

    println!(
        "cargo:rustc-link-arg={}",
        Path::new(&cargo_manifest_dir).join("lib/foo_libqux.dylib").display()
    );
}

However, crank build --run results in this error at runtime:

dlopen(/Users/py/projects/paulyoung/MyProject/main/target/My Project.pdx/pdex.dylib, 0x0006): Library not loaded: foo_libqux.dylib
  Referenced from: /Users/py/projects/paulyoung/MyProject/main/target/My Project.pdx/pdex.dylib
  Reason: tried: '/nix/store/g8b81w9kpb82gm7702ca692mp5flm7pf-apple-framework-CoreFoundation-11.0.0/Library/Frameworks/foo_libqux.dylib' (no such file), '/nix/store/g8b81w9kpb82gm7702ca692mp5flm7pf-apple-framework-CoreFoundation-11.0.0/Library/Frameworks/foo_libqux.dylib' (no such file), '/usr/lib/swift/foo_libqux.dylib' (no such file), '/Users/py/Developer/PlaydateSDK/bin/Playdate Simulator.app/Contents/MacOS/../Frameworks/foo_libqux.dylib' (no such file), '/Users/py/Developer/PlaydateSDK/bin/Playdate Simulator.app/Contents/MacOS/../Frameworks/foo_libqux.dylib' (no such file), '/usr/lib/swift/foo_libqux.dylib' (no such file), '/Users/py/Developer/PlaydateSDK/bin/Playdate Simulator.app/Contents/MacOS/../Frameworks/foo_libqux.dylib' (no such file), '/Users/py/Developer/PlaydateSDK/bin/Playdate Simulator.app/Contents/MacOS/../Frameworks/foo_libqux.dylib' (no such file), 'foo_libqux.dylib' (no such file), '/usr/local/lib/foo_libqux.dylib' (no such file), '/usr/lib/foo_libqux.dylib' (no such file), '//foo_libqux.dylib' (no such file), '/usr/local/lib/foo_libqux.dylib' (no such file), '/usr/lib/foo_libqux.dylib' (no such file)
(expand for a bulleted list of search paths)
  • /nix/store/g8b81w9kpb82gm7702ca692mp5flm7pf-apple-framework-CoreFoundation-11.0.0/Library/Frameworks/foo_libqux.dylib
  • /nix/store/g8b81w9kpb82gm7702ca692mp5flm7pf-apple-framework-CoreFoundation-11.0.0/Library/Frameworks/foo_libqux.dylib
  • /usr/lib/swift/foo_libqux.dylib
  • /Users/py/Developer/PlaydateSDK/bin/Playdate Simulator.app/Contents/MacOS/../Frameworks/foo_libqux.dylib
  • /Users/py/Developer/PlaydateSDK/bin/Playdate Simulator.app/Contents/MacOS/../Frameworks/foo_libqux.dylib
  • /usr/lib/swift/foo_libqux.dylib
  • /Users/py/Developer/PlaydateSDK/bin/Playdate Simulator.app/Contents/MacOS/../Frameworks/foo_libqux.dylib
  • /Users/py/Developer/PlaydateSDK/bin/Playdate Simulator.app/Contents/MacOS/../Frameworks/foo_libqux.dylib
  • foo_libqux.dylib
  • /usr/local/lib/foo_libqux.dylib
  • /usr/lib/foo_libqux.dylib
  • //foo_libqux.dylib
  • /usr/local/lib/foo_libqux.dylib
  • /usr/lib/foo_libqux.dylib

I've tried setting LD_LIBRARY_PATH=./lib, DYLD_LIBRARY_PATH=./lib, and DYLD_FALLBACK_LIBRARY_PATH=./lib when invoking crank but it doesn't make a difference to the search paths. I tried the same thing with open -a "Playdate Simulator" ./target/My\ Project.pdx but that didn't change anything either.

I also tried adding those environment variables via cmd.env in run_pdc and run_simulator in main.rs but still no change.

This obviously isn't a solution, but I copied the library and made it available at ~/Developer/PlaydateSDK/bin/Playdate Simulator.app/Contents/Frameworks/foo_libqux.dylib and things appear to work.

It at least seems to demonstrate that this should work for the simulator as long as the search paths are set correctly. I don't have a device yet and I'm not sure where to begin on making this work there but hopefully there's nothing preventing this.

If I could get some insight or advice on how to go about this properly I'd be very grateful. Happy to make a PR to propose changes or document what I've found as a result.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions