javaandroidjarandroid-source

"No rule to make target" error when adding a library in android source application


I am working in the AOSP build system. I added another library dependency in my application (in packages/apps) and I get this strange error:

mmm -B packages/apps/MyApp/
make: Entering directory `/home/user/workspace/aosp'
target R.java/Manifest.java: MyApp (out/target/common/obj/APPS/MyApp_intermediates/src/R.stamp)
make: *** No rule to make target `out/target/common/obj/JAVA_LIBRARIES/bcprov-jdk15on-152_intermediates/javalib.jar', needed by `out/target/common/obj/APPS/MyApp_intermediates/classes-full-debug.jar'.  Stop.

I do not have this error with Android Studio and the libraries work as expected, but I need to build it in AOSP.

Here's the Android.mk:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

# TAGS is test, so apk will end up in /data/app
LOCAL_MODULE_TAGS := tests
LOCAL_MODULE_OWNER := mycompany

# Java sources are in ./java
LOCAL_SRC_FILES := $(call all-java-files-under, java)

# Resources are in ./res
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res

# We need all these jars
LOCAL_STATIC_JAVA_LIBRARIES += android-support-v4
LOCAL_STATIC_JAVA_LIBRARIES := restlet-2.3.2-jsslutils
LOCAL_STATIC_JAVA_LIBRARIES += restlet-2.3.2-restlet-ext-nio
LOCAL_STATIC_JAVA_LIBRARIES += restlet-2.3.2-restlet
LOCAL_STATIC_JAVA_LIBRARIES += bcprov-jdk15on-152
LOCAL_STATIC_JAVA_LIBRARIES += ksoap2-android-assembly-3.4.0-jar-with-dependencies

LOCAL_JAVA_LIBRARIES :=  com.mycompany.myservice.lib

# The name of this application
LOCAL_PACKAGE_NAME := MyApp

# No Proguard
LOCAL_PROGUARD_ENABLED := disabled

# Build an APK
include $(BUILD_PACKAGE)

And the AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="mycompany.myapp" >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />

    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-feature android:name="android.hardware.sensor" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_people"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <uses-library
            android:name="com.mycompany.myservice.lib"
            android:required="true" />

        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".ws.CommandIntentService"
            android:exported="false" >
        </service>
        <service
            android:name=".ws.WSRequestIntentService"
            android:exported="false" >
        </service>
        <service
            android:name=".ws.CloudClientService"
            android:enabled="true"
            android:exported="false" >
        </service>
    </application>

</manifest>

I get this error for both bountycaste(bcprov...) and ksoap libraries.

Seeking differences between working/failing libs, I tried a java decompiler. I was able to decompile classes from the restlet and the ksoap2 classes, using unzip and jad (java decompiler). Both files were decompiled without problems.

I also tried to include the library as precompiled using LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES, but it didn't work.


Solution

  • LOCAL_STATIC_JAVA_LIBRARIES must refer to libraries built either in other module, or in this one. Since you're using pre-built jar files, you do need to add LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES to your manifest. It could look like:

    include $(CLEAR_VARS)
    
    LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := android-support-v4:libs/android-support-v4.jar \
        restlet-2.3.2-jsslutils:libs/restlet-2.3.2-jsslutils.jar \
        restlet-2.3.2-restlet-ext-nio:libs/restlet-2.3.2-restlet-ext-nio.jar <add here other libraries>
    
    include $(BUILD_MULTI_PREBUILT)
    

    It can be added at the bottom of your Android.mk. Mention that android-support-v4 etc are just virtual names of libraries, so you could use other names, just they need to match definitions between LOCAL_STATIC_JAVA_LIBRARIES and LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES.

    Syntax for LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES is following: <lib_name>:<path_to_jar_file.jar>. I mean that lib_name is not necessary to be the same as jar file name (but it may, of course).

    BTW I think you have a mistake in following line:

    LOCAL_STATIC_JAVA_LIBRARIES := restlet-2.3.2-jsslutils
    

    it should be

    LOCAL_STATIC_JAVA_LIBRARIES += restlet-2.3.2-jsslutils
    

    := should be used in the first statement

    EDITED1:

    It may be convenient to put several restlet-2.3.2-*.jar files into single library ie restlet:

    LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := restlet:libs/restlet-2.3.2-jsslutils.jar \
        restlet:libs/restlet-2.3.2-restlet-ext-nio.jar restlet:libs/restlet-2.3.2-restlet.jar
    

    I didn't use it myself, but I think it may work.

    EDITED2:

    Most likely shared library android-support-v4 is already present in your AOSP ROM, so you do not need to specify it in LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES

    EDITED3:

    I see in the manifest that you're using an Android project library

        <uses-library
            android:name="com.mycompany.myservice.lib"
            android:required="true" />
    

    Such libraries are not supported in AOSP - just regular jar libraries are supported, so resource files need to be handled additionally. Check answers here: Add one android project as a library in AOSP App

    The simplest solution is to put the library source into your app project, if it's acceptable. Or see workarounds at the provided link