KISS

Keep It Simple Stupid

Android: NDK clean failed on fts_read

| comments

I happen to migrate one of my projects to gradle, as the future build system for Android. The best_project also uses several NDK libraries, so I had to add the proper build steps to the script. However, when I do clean, it often fails with rm: fts_read: No such file or directory. The fix is below.

To start, here is the relevant part of the build.gradle:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
task cleanNative(type: Exec) {
    def ndkBuild;
    def ndkBuildingDir = mainSrcDir;
    def hasNdk = false;
    if (System.env.ANDROID_NDK_HOME != null) {
        hasNdk = true;
        ndkBuild = new File(System.env.ANDROID_NDK_HOME, 'ndk-build')
    }

    commandLine ndkBuild, "--directory", ndkBuildingDir, "clean"

    doFirst {
        if (!hasNdk) {
            logger.error('##################')
            logger.error("Failed NDK build")
            logger.error('Reason: Reason: ANDROID_NDK_HOME not set.')
            logger.error('##################')
        }
        assert hasNdk : "ANDROID_NDK_HOME not set."
    }
}

Sources:

The logs when I do gradle cleanNative:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
:best_project:cleanNative
make: Entering directory `…/best_project/src/main'
Clean: super_lib [armeabi]
Clean: gnustl_shared [armeabi]
Clean: gnustl_static [armeabi]
Clean: awesome_lib [armeabi]
rm: fts_read: No such file or directory
rm: fts_read: No such file or directory
make: *** [clean-super_lib-armeabi] Error 1
make: *** Waiting for unfinished jobs....
make: *** [clean-awesome_lib-armeabi] Error 1
rm: fts_read: No such file or directory
make: *** [clean-gnustl_static-armeabi] Error 1
make: Leaving directory `…/best_project/src/main'
:best_project:cleanNative FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':best_project:cleanNative'.
> Process 'command '…/android-ndk-r9/ndk-build'' finished with non-zero exit value 2

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

The pattern is interesting. First time it fails, and second time it works. After building the libraries, it’s the same. Running ndk-build V=1 NDK_LOG=1 clean with debug output didn’t help.

man fts_read tells us that’s a function related to traversing file systems. All in all, it looks like a parallel processing issue. And I’ve never seen it in Android Studio.

Then it hit me. With the env command I found this: MAKEFLAGS="-j4", which means every make command automatically gets the -j4 flag, and will run the build process in four parallel processes. That’s the cause. So the fix is to add -j1 to the clean command in the script above (line 10):

1
commandLine ndkBuild, "--directory", ndkBuildingDir, "-j1", "clean"

Comments