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

use llvm-readelf to figure out dynamic libraries to include #47

Closed
dvc94ch opened this issue Apr 9, 2022 · 16 comments · Fixed by #65
Closed

use llvm-readelf to figure out dynamic libraries to include #47

dvc94ch opened this issue Apr 9, 2022 · 16 comments · Fixed by #65

Comments

@dvc94ch
Copy link
Contributor

dvc94ch commented Apr 9, 2022

No description provided.

@MarijnS95
Copy link
Member

MarijnS95 commented Apr 11, 2022

@dvc94ch It seems there's --dylibs-used but that's only for MachO, are you sure llvm-objdump is capable of parsing the dynamic section? ldd seems to be a replacement (though prints an error about only working on executables), perhaps llvm-readelf but then we need a fallback to llvm-objdump for Mac MachO binaries?

https://stackoverflow.com/questions/23697641/what-is-the-clang-analogue-of-ldd

As such llvm-readelf --needed-libs seems like a nice solution :)

@dvc94ch
Copy link
Contributor Author

dvc94ch commented Apr 11, 2022

llvm-readelf --needed-libs seems to work for all binaries:

linux:

llvm-readelf --needed-libs helloworld
NeededLibraries [
  ld-linux-x86-64.so.2
  libc.so.6
  libcairo-gobject.so.2
  libcairo.so.2
  libflutter_linux_gtk.so
  libgcc_s.so.1
  libgdk-3.so.0
  libgdk_pixbuf-2.0.so.0
  libgio-2.0.so.0
  libglib-2.0.so.0
  libgobject-2.0.so.0
  libgtk-3.so.0
  libm.so.6
  libpango-1.0.so.0
]

macos:

llvm-readelf --needed-libs helloworld
NeededLibraries [
  /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit
  /System/Library/Frameworks/Carbon.framework/Versions/A/Carbon
  /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
  /System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics
  /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices
  /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
  /System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore
  /usr/lib/libSystem.B.dylib
  /usr/lib/libiconv.2.dylib
  /usr/lib/libobjc.A.dylib
  /usr/lib/libresolv.9.dylib
  @rpath/FlutterMacOS.framework/Versions/A/FlutterMacOS
]

windows:

llvm-readelf --needed-libs helloworld.exe
NeededLibraries [
  GDI32.dll
  KERNEL32.dll
  USER32.dll
  bcrypt.dll
  comctl32.dll
  dwmapi.dll
  flutter_windows.dll
  ole32.dll
  oleaut32.dll
  shell32.dll
  shlwapi.dll
]

@MarijnS95
Copy link
Member

Perfect, I already started working this into a copy-pasted implementation from cargo-apk.

Still getting to grips with the project structure and layout, seems some things are "all over the place" or crammed together in a single lib.rs, not sure what to place where yet but I'll start with getting my project to run and go from there.

Seeing some flutter deps in there, can we also automate that bit instead of the current hardcoded lib inclusion?

@dvc94ch
Copy link
Contributor Author

dvc94ch commented Apr 11, 2022

I guess the question is which libraries to include? Instead of auto including stuff using readelf, why don't we make it configurable?

@dvc94ch
Copy link
Contributor Author

dvc94ch commented Apr 11, 2022

Also there was some previous work done here: 034b536 which I removed because I wasn't sure if it's really the way to go.

@MarijnS95
Copy link
Member

For Android I guess we can use the NDK to list available libraries (minus libc++_shared edgecase) and allow the user to specify additional search directories like cargo-apk? Then print warnings for any library that isn't found, just in case.

@MarijnS95
Copy link
Member

Also there was some previous work done here: 034b536 which I removed because I wasn't sure if it's really the way to go.

That seems to only pass additional libs to the linker? In addition we also need the libs to be copied to the APK, which is my main concern (for libc++_shared) to start with :)

@dvc94ch
Copy link
Contributor Author

dvc94ch commented Apr 11, 2022

For Android I guess we can use the NDK to list available libraries (minus libc++_shared edgecase) and allow the user to specify additional search directories like cargo-apk? Then print warnings for any library that isn't found, just in case.

well, the behaviour should be consistent accross platforms. I know we have a heuristic that works for android, not sure if/how that will work on other platforms

That seems to only pass additional libs to the linker? In addition we also need the libs to be copied to the APK, which is my main concern (for libc++_shared) to start with :)

yes, that's why I removed it, because it wasn't hooked up anyway

@MarijnS95
Copy link
Member

MarijnS95 commented Apr 11, 2022

For Android I guess we can use the NDK to list available libraries (minus libc++_shared edgecase) and allow the user to specify additional search directories like cargo-apk? Then print warnings for any library that isn't found, just in case.

well, the behaviour should be consistent accross platforms. I know we have a heuristic that works for android, not sure if/how that will work on other platforms

Obviously, but since I only develop on Android now and have no experience with iOS apps this is the only thing I can get started with. Once I have something I bet you'll have to test/improve it for the other target :)

That seems to only pass additional libs to the linker? In addition we also need the libs to be copied to the APK, which is my main concern (for libc++_shared) to start with :)

yes, that's why I removed it, because it wasn't hooked up anyway

Might be useful later when we allow users to bundle custom libs again, but afaik their build scripts should generally cover that. I think we might even be able to parse those cargo:rustc-link-search= like you did and use those as additional search paths to copy their dynamic libs to the target app package (apk or ios appbundle whatever they use).

@MarijnS95 MarijnS95 changed the title use llvm-objdump to figure out dynamic libraries to include use llvm-readelf to figure out dynamic libraries to include Apr 20, 2022
@MarijnS95
Copy link
Member

Still getting to grips with the codebase but I got this working and made our application fully compileable and runnable through xbuild 🥳!

Progress at master...MarijnS95:readelf, will clean this up, finish the TODOs, and open a PR soon :)

@MarijnS95
Copy link
Member

@dvc94ch I also need to add libraries that are dynamically loaded at runtime to an APK (ie. Vulkan validation layers) just like rust-mobile/ndk@fb52590, is that something you've planned? Where should we add it in the manifest, somewhere Android-specific or generic?

@dvc94ch
Copy link
Contributor Author

dvc94ch commented Apr 20, 2022

not planned yet, no. thinking about it a bit I think it's quite a complicated feature to work cross platforms, architectures etc. maybe we could do something like:

println!("xbuild:add_library:/path/to/library");

from build.rs scripts?

@MarijnS95
Copy link
Member

Doing it from build.rs scripts doesn't seem to be much different from configuring it in manifest.yaml, except that the latter won't work for crate dependencies. Not sure if we really want to give crate dependencies the ability to also add runtime libraries, being able to do this from the top-level crate only seems good enough already.

Besides, we'll already have to add support for scanning regular cargo:rustc-link-search= and I prefer if crate dependencies solely work with static libraries here.

@MarijnS95
Copy link
Member

MarijnS95 commented Apr 20, 2022

In addition, xbuild:add_library= may seem like it is already generic enough across all platforms? But we can also do that through the manifest outside the platform-specific configuration bit?

@dvc94ch
Copy link
Contributor Author

dvc94ch commented Apr 20, 2022

well, it's not quite the same. In build.rs there can be logic deciding for which platform and Cargo.toml supports target specific dependencies. to put it in the manifest we'd have to recreate that.

@MarijnS95
Copy link
Member

Fair enough, in android-ndk-rs we expect sub-folders with the target architecture (not even the triple, though), but that doesn't make it possible to omit or use a different library entirely depending on whatever logic the user wants (features, target, etc).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants