google / prefab

Prefab is a tool for generating build system integrations for prebuilt C/C++ libraries.
https://google.github.io/prefab/
Apache License 2.0
210 stars 32 forks source link

[BUG] Library not exposing c++ symbols, still enforcing its STL in the abi.json #158

Closed rpavlik closed 2 years ago

rpavlik commented 2 years ago

Describe the bug As recommended by the guidance for middleware authors, we've switched our AAR to being built with the static STL. The library exposes a purely-C API/ABI, the use of C++ is an internal implementation detail. Exported symbols are limited with an exports file so in theory it should be unobservable that the library uses C++. However, now that we have a shared library with static STL, the gradle build (I think in the prefab tool itself) fails with Library is a shared library with a statically linked STL and cannot be used with any library using the STL.

To Reproduce Steps to reproduce the behavior:

  1. Add linking to the OpenXR 1.0.25 library AAR to a gradle project - this exposes only a C API but internally uses C++ with the static runtime, so you could do similarly yourself to any library.
  2. Try building
  3. You'll see an error "com.google.prefab.api.NoMatchingLibraryException"

Expected behavior Would expect that it would link and run fine.

I'm told that for projects using it without Gradle (e.g. Unity projects) the contents of the AAR work fine, so it's specific to using prefab/gradle to do the build.

Logs

> Task :classic-teapot:configureCMakeDebug[arm64-v8a] FAILED
C/C++: prefabcom.google.prefab.api.NoMatchingLibraryException: No compatible library found for //OpenXR/openxr_loader. Rejected the following libraries:
C/C++: prefabandroid.arm64-v8a: Library is a shared library with a statically linked STL and cannot be used with any library using the STL
C/C++: prefabandroid.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
C/C++: prefabandroid.x86: User is targeting arm64-v8a but library is for x86
C/C++: prefabandroid.x86_64: User is targeting arm64-v8a but library is for x86_64

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':classic-teapot:configureCMakeDebug[arm64-v8a]'.
> C/C++: /home/ryan/src/androidteapots/classic-teapot/src/main/cpp/CMakeLists.txt debug|arm64-v8a : CMake Error at /home/ryan/src/androidteapots/classic-teapot/src/main/cpp/CMakeLists.txt:19 (find_package):
    Could not find a package configuration file provided by "OpenXR" with any
    of the following names:

      OpenXRConfig.cmake
      openxr-config.cmake

    Add the installation prefix of "OpenXR" to CMAKE_PREFIX_PATH or set
    "OpenXR_DIR" to a directory containing one of the above files.  If "OpenXR"
    provides a separate development package or SDK, be sure it has been
    installed.

Environment: Prefab version: As provided in AGP 7.2.2

Host OS: Linux Target platform: Android Target ABI: any Target OS version: SDK 33 Build system: Gradle

Additional context Should we be specifying a different value in those abi.json files? Omitting that key fails, as does providing null. Looks like if we specify "none" as a string instead it will link and finish the build, at least.

DanAlbert commented 2 years ago

Prefab doesn't create packages, it only reads them. You need to file this bug against whatever system created the package (looks to be AGP?)

rpavlik commented 2 years ago

Is the correct value to put in the file "none" then? Wasn't actually made with agp because of other bugs in agp, so more home brewed than that. But I suspect that agp probably does put the stl in the file because I doubt it's introspecting the symbols exported.

DanAlbert commented 2 years ago

If your library does not enforce any STL constraints on the user, yes, use none.