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

:app:generateCrashlyticsSymbolFileRelease - Specified path for unstripped native libs is not a directory #1199

Closed
Kocjan opened this issue Feb 4, 2020 · 26 comments

Comments

@Kocjan
Copy link

Kocjan commented Feb 4, 2020

Describe your environment

    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.3'
        classpath 'com.google.gms:google-services:4.3.3'
        classpath 'com.google.firebase:firebase-crashlytics-gradle:2.0.0-beta02'
        classpath 'com.google.firebase:firebase-appdistribution-gradle:1.3.1'
    }

Describe the problem

Steps to reproduce:

When I try to run:
./gradlew clean assembleRelease uploadCrashlyticsSymbolFileRelease

I get next error:

Execution failed for task ':app:generateCrashlyticsSymbolFileRelease'.
> java.io.IOException: Specified path for unstripped native libs is not a directory: /Users/martin/repos/example-app-android/app/obj

If I manually move all my NDK libs to ./app folder I get the same error with different path:

Execution failed for task ':app:generateCrashlyticsSymbolFileRelease'.
> java.io.IOException: Specified path for stripped native libs is not a directory: /Users/martin/repos/example-app-android/app/build/intermediates/transforms/stripDebugSymbol/release

In this second case the build command sometimes fails, sometimes not.

This issue started to appear after I moved from Fabric Crashlytics plugin to Firebase Crashlytics plugin.
In the Fabric case, I had the option to define: androidNdkOut and androidNdkLibsOut paths.
Is that missing in the new Firebase plugin?

Relevant Code:

Old code example:

    crashlytics {
        enableNdk true
        androidNdkOut "$buildDir/ndklibs/obj"
        androidNdkLibsOut "$buildDir/ndklibs/libs"
    }

New Code example:

            firebaseCrashlytics {
                nativeSymbolUploadEnabled true

            }

In the Firebase case, I didn't specify any paths.

To collect all ndk libs I use following code:

    configurations {
        ndkzip
    }

    task setupNdklibs(type: Sync) {
        dependsOn configurations.ndkzip
        from {
            configurations.ndkzip.collect { zipTree(it) }
        }
        into "$buildDir/ndklibs/"
    }
    build.finalizedBy setupNdklibs

and executing ./gradlew build

@google-oss-bot
Copy link
Contributor

I found a few problems with this issue:

  • I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
  • This issue does not seem to follow the issue template. Make sure you provide all the required information.

@mrichards
Copy link
Contributor

In the new Firebase Crashlytics plugin, the androidNdkOut and androidNdkLibsOut properties have been changed to strippedNativeLibsDir and unstrippedNativeLibsDir, and should be declared in firebaseCrashlytics within the variant block, where you declared nativeSymbolUploadEnabled true.

Those options aren't currently documented, though they will be shortly.

@Kocjan
Copy link
Author

Kocjan commented Feb 11, 2020

@mrichards thanks for the info, I will test it and let you know.

@Kocjan
Copy link
Author

Kocjan commented Feb 12, 2020

@mrichards I tested and I get the same issues, but now the problem is with the path:

> java.io.IOException: Specified path for unstripped native libs is not a directory: /Users/martin/repos/example-app-android/app/Users/martin/repos/example-app-android/app/build/ndklibs/libs

It looks like this task prepends <your-path-to-app>/app to strippedNativeLibsDir and unstrippedNativeLibsDir paths.
Code:

            firebaseCrashlytics {
                nativeSymbolUploadEnabled true
                strippedNativeLibsDir "$buildDir/ndklibs/obj"
                unstrippedNativeLibsDir "$buildDir/ndklibs/libs"
            }

I solved my problem using relative paths:

            firebaseCrashlytics {
                nativeSymbolUploadEnabled true
                // These paths are relative to the app/ folder
                strippedNativeLibsDir "build/ndklibs/obj"
                unstrippedNativeLibsDir "build/ndklibs/libs"
            }

But it looks like a issue with the app:generateCrashlyticsSymbolFileRelease task :)

@mrichards
Copy link
Contributor

Glad you got it working! I'll take a look at the absolute path issue.

@gordinmitya
Copy link

gordinmitya commented Feb 22, 2020

Hello, thanks for your answer @mrichards
What should I do if I have multiple modules with native code in my project?
How do I specify paths?

nativeSymbolUploadEnabled true doesn't work

this is my output of find . -name "obj" in the root folder of project

./mace/build/intermediates/cmake/release/obj
./mace/build/intermediates/cmake/debug/obj
./mnn/build/intermediates/cmake/release/obj
./mnn/build/intermediates/cmake/debug/obj
./ncnn/build/intermediates/cmake/release/obj
./ncnn/build/intermediates/cmake/debug/obj

@ihar-abramovich
Copy link

Hello, thanks for your answer @mrichards
What should I do if I have a separate module with native code and include it in a project like aar?
Is it possible to work with new Crashlytics this way?

@darrentaft
Copy link

I'm trying to use this myself for the first time and seeing this same error. I don't do anything special with cmake, I don't override any default directories, and I didn't specify any androidNdkOut parameters with the Fabric version.
Having switched to Firebase Crashlytics, I can't get it to upload symbols due to error:

Execution failed for task ':app:generateCrashlyticsSymbolFileSportProdStoreRelease'.
> java.io.IOException: Specified path for stripped native libs is not a directory: /home/vsts/work/1/s/app/build/intermediates/stripped_native_libs/sportProdStoreRelease/out

Any clues on how I can debug this? Do I need to specify the xNativeLibsDir params? If so, with what values? FYI "sport" and "prod" are flavor dimensions, and "storeRelease" is the buildType.

Note: the app has a number of 3rd party libraries and a module that include includes libraries, but I don't have debug variants of them to specify unstripped libs.

@synman
Copy link

synman commented Apr 23, 2020

Thanks to mrichards on the new operatives. I had this issue today after doing some housekeeping (deleting old obj folders / etc) within my app module.

My app module does not have any (direct) native libraries within it -- I just have a couple jars I need packaged and keep them in app/libs.

firebaseCrashlytics {
      nativeSymbolUploadEnabled true
      strippedNativeLibsDir "libs"
       unstrippedNativeLibsDir "libs"
 }

@marius-bardan
Copy link

Since both properties are relative paths to 'app' dir, how should I reference other modules? For example, my native libs are in ':external' which sits on the same leve as ':app' dir.
setting something like the following doesn't work:
strippedNativeLibsDir "${rootProject.projectDir}/external/build/intermediates/stripped_native_libs/release/out/lib/"

@4ntoine
Copy link

4ntoine commented May 8, 2020

Yup, i'm also interested. Let's say :app depends on another android library (aar) with shared libs. I believe during the build they are extracted and collected somewhere in build dir. However i did not find not stripped libs (that are coming from aar) after assembleRelease just to adjust the paths. Anyone?

@marius-bardan
Copy link

This is what I'm currently using. But cannot attest it's correct due to another bug (NPE thrown when trying to upload symbols).

firebaseCrashlytics {
    nativeSymbolUploadEnabled true
    unstrippedNativeLibsDir "build/intermediates/merged_native_libs/release/out/lib/"
    strippedNativeLibsDir "build/intermediates/stripped_native_libs/release/out/lib/"
}

@4ntoine
Copy link

4ntoine commented May 8, 2020

@marius-bardan
It's interesting, i don't have the dirs that work for you. What's your versions (gradle and plugins)?

@marius-bardan
Copy link

com.android.tools.build:gradle:3.5.3
com.google.firebase:firebase-crashlytics-gradle:2.0.0

@4ntoine
Copy link

4ntoine commented May 8, 2020

@marius-bardan

classpath 'com.android.tools.build:gradle:3.3.0'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.0.0-beta02'

will check yours

@4ntoine
Copy link

4ntoine commented May 8, 2020

@marius-bardan
yup, with your versions the paths are correct. In my case the libs in ./app/build/intermediates/merged_native_libs/ were also stripped and it took some time to understand that it was "Release" build mode for 3rd-party lib (aar) and it contains already stripped libs. PS. I had to update Gradle version to 5.4.1 (minimum)

@darrentaft
Copy link

This issue is now intermittent for me. We use an Azure pipeline to build the app, so it's a fresh checkout and build every time on a clean environment with the same code. I just ran the pipeline 3 times in a row - first 2 failed with this error, 3rd time lucky.

@kevinkokomani
Copy link

@darrentaft To clarify, the issue you're referring to is the original "Specified path for unstripped native libs is not a directory" issue? If so, I'd be interested to know more about your 3 runs of the pipeline. Is there anything different you observed in the third run that made it work?

If you try to assemble and then upload symbols using manual Gradle tasks as a test, do you get the same error? What about if you make sure to manually clean between the ./gradlew assemble and ./gradlew uploadCrashlyticsSymbolFile? Maybe the Crashlytics plugin is having issues with custom build pipelines.

@darrentaft
Copy link

@kevinkokomani comparing the build runs, one thing I can see is that the build tasks don't appear to run in the same order every time. These are the tasks executed in the final steps before failure, just after it has finished building the native library. On the build that succeeded:

Task :app:compileTvSprintReleaseAmazonShaders
Task :app:generateTvSprintReleaseAmazonAssets
Task :app:mergeTvSprintReleaseAmazonAssets
Task :app:validateSigningTvSprintReleaseAmazon
Task :app:signingConfigWriterTvSprintReleaseAmazon
Task :app:mergeTvSprintReleaseAmazonJniLibFolders
Task :app:processTvSprintReleaseAmazonResources
Task :app:compileTvSprintReleaseAmazonKotlin
Task :app:mergeTvSprintReleaseAmazonNativeLibs
Task :app:stripTvSprintReleaseAmazonDebugSymbols
Task :app:processTvSprintReleaseAmazonJavaRes NO-SOURCE
Task :app:generateCrashlyticsSymbolFileTvSprintRelease
Task :app:uploadCrashlyticsSymbolFileTvSprintRelease
Task :app:generateCrashlyticsSymbolFileTvSprintReleaseAmazon
Task :app:uploadCrashlyticsSymbolFileTvSprintReleaseAmazon

Whereas on the build that failed:


> Task :app:compileTvSprintReleaseAmazonJavaWithJavac
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

> Task :app:compileTvSprintReleaseAmazonSources
> Task :app:lintVitalTvSprintReleaseAmazon
> Task :app:mergeTvSprintReleaseAmazonShaders
> Task :app:compileTvSprintReleaseAmazonShaders
> Task :app:generateTvSprintReleaseAmazonAssets
> Task :app:mergeTvSprintReleaseAmazonAssets
> Task :app:validateSigningTvSprintReleaseAmazon
> Task :app:signingConfigWriterTvSprintReleaseAmazon
> Task :app:mergeTvSprintReleaseAmazonJniLibFolders
> Task :app:mergeTvSprintReleaseAmazonGeneratedProguardFiles
> Task :app:processTvSprintReleaseAmazonJavaRes NO-SOURCE
> Task :app:generateCrashlyticsSymbolFileTvSprintRelease
> Task :app:uploadCrashlyticsSymbolFileTvSprintRelease
> Task :app:generateCrashlyticsSymbolFileTvSprintReleaseAmazon FAILED
> Task :app:mergeTvSprintReleaseAmazonJavaResource
> Task :app:mergeTvSprintReleaseAmazonNativeLibs

FAILURE: Build failed with an exception.

See how the app:mergeTvSprintReleaseAmazonNativeLibs step is being executed AFTER app:generateCrashlyticsSymbolFileTvSprintReleaseAmazon for the failed build - is it maybe too late by then?

There are numerous points throughout the build where the execution order is different, so I don't know if any of them are relevant.

As for changing the pipeline - could the random order maybe be caused by me building 2 variants at the same time? This is the command it runs:

gradlew assembleTvSprintRelease assembleTvSprintReleaseAmazon uploadCrashlyticsSymbolFileTvSprintRelease uploadCrashlyticsSymbolFileTvSprintReleaseAmazon

@kevinkokomani
Copy link

Thanks for this info -- it might be worth a shot to run the assemble and the upload separately, at least as a test. We're aware of an issue that occurs where running the assemble and the uploadCrashlytics commands simultaneously can sometimes cause the upload to fail, or to upload the wrong files (the assemble doesn't finish in time for the upload, so the library's paths haven't been rebuilt yet). The non-deterministic nature of the issue you're describing makes it sound like the above could be affecting you.

Do you get similar behavior with the varied order of the build steps if you explicitly wait for gradlew assemble to finish before running gradlew uploadCrashlyticsSymbolFileTvSprintRelease?

@darrentaft
Copy link

Thanks @kevinkokomani ... I've been running with this for over a week now, and since moving the upload to a separate task, the issue hasn't reoccurred. The upload task alone takes around 8 seconds, so it's not really having any impact on our build process - I'm happy enough with that. Cheers.

@mrichards
Copy link
Contributor

Crashlytics Gradle plugin v2.2.0 will fix both the task ordering issue and the absolute path issue. These two fixes together should make it easier to get symbols uploaded for 3rd party libraries using as described here.

We'll update this issue when the release goes live within the next couple of weeks.

@mrichards
Copy link
Contributor

Crashlytics Gradle plugin v2.2.0 will fix both the task ordering issue and the absolute path issue. These two fixes together should make it easier to get symbols uploaded for 3rd party libraries using as described here.

Crashlytics Gradle plugin 2.2.0 is now live! Absolute paths should now work as expected.

If you've previously had trouble getting symbols uploaded for 3rd party native libs or non-standard NDK builds, please take a look at the doc linked above and give it another shot. We cleaned up the task configuration for generateCrashlyticsSymbolFile & uploadCrashlyticsSymbolFile, and added some improved error messaging. It should be easier to get it working for more complex builds now.

@kenmorse
Copy link

@mrichards — Still doesn't seem quite right: with the 2.2.0 plugin, now get "Crashlytics could not find NDK build tasks on which to depend. You many need to manually enforce task dependencies for generateCrashlyticsSymbolFileFlavorAmazonRelease" message.

@rpattabi
Copy link

@mrichards Even after updating the crashlytics plugin to 2.2.0, I get the same error. It still assumes the given path is relative path. If this was expected to work, how do you differentiate whether the given path is absolute or relative?

@vfishv
Copy link

vfishv commented Jun 22, 2020

😠 firebase-crashlytics-gradle:2.2.0 can NOT build but 2.1.1 works good

Crashlytics could not determine stripped/unstripped native library directories for project ':app', variant Release. These are required for generating symbol files when NDK build tasks cannot be automatically inferred. Please specify strippedNativeLibsDir and unstrippedNativeLibsDir in the firebaseCrashlytics extension.

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

No branches or pull requests