Ask Your Question
0

Linking prebuilt opencv static library in Android.mk

asked 2019-01-15 12:40:34 -0500

epatton gravatar image

updated 2019-03-22 16:17:59 -0500

Hi I am trying to link prebuilt external/opencv3 libopencv_core.a in the Android tree to my project that's also in the tree. I get the following error

ninja: error: 'out/target/product/neo/obj/STATIC_LIBRARIES/libopencv_core_prebuilt_intermediates/export_includes', needed by 'out/target/product/neo/obj/STATIC_LIBRARIES/libNV_intermediates/import_includes', missing and no known rule to make it

I am able to link to libopencv_core when Android builds it, but I need to link to opencv3 built with opencl created using the following make.

cd /hdd/NEO8/external/opencv3/platforms
./scripts/cmake_android_arm.sh -DANDROID_ABI=arm64-v8a -DANDROID_NATIVE_API_LEVEL=android-23 -DWITH_OPENCL=yes -DWITH_CUDA=no
cd build_android_arm
make -j8
OpenCV static libraries are created in the lib/arm64-v8a directory.

My project is all native code (c++) with no jni or Java.

The tree structure is:

my_android_tree_root/
                external/opencv3  (this is where I build the libopencv_core.a)
                device/my_app  (this is where my Android.mk is)

The external/opencv3 code is v3.0 downloaded from Google.

I'd attach the Android.mk but this forum only allows image attachments. Below is how I'm adding the prebuilt to the Android.mk

include $(CLEAR_VARS)
PREBUILT_PATH := /hdd/NEO8/external/opencv3/platforms/build_android_arm/lib/arm64-v8a
PREBUILT_INCLUDE_PATH := /hdd/NEO8/external/opencv3
LOCAL_EXPORT_C_INCLUDE_DIRS := \
    $(PREBUILT_INCLUDE_PATH) \
    $(PREBUILT_INCLUDE_PATH)/modules/core/include \
    $(PREBUILT_INCLUDE_PATH)/opencv2 \
    $(PREBUILT_INCLUDE_PATH)/modules/hal/include
LOCAL_MODULE            := libopencv_core_prebuilt
LOCAL_SRC_FILES := $(PREBUILT_PATH)/libopencv_core.a
include $(PREBUILT_STATIC_LIBRARY)

The LOCAL_EXPORT_C_INCLUDE_DIRS is the same as what I use when I link to the Android built opencv3.

I can tell that the Android build process is finding the libopencv_core.a file because when I change the static library name to something bogus, i.e.

LOCAL_SRC_FILES := $(PREBUILT_PATH)/libopencv_core_bogusName.a

the linker says it can't find libopencv_core_bogusName.a.

Is there a way to get more information out of the Android build info like a verbose=true setting? Any ideas on what I can try would be greatly appreciated.

This is the entire Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
PREBUILT_PATH := /hdd/NEO8/external/opencv3/platforms/build_android_arm/lib/arm64-v8a
PREBUILT_INCLUDE_PATH := /hdd/NEO8/external/opencv3

LOCAL_EXPORT_C_INCLUDE_DIRS := \
    $(PREBUILT_INCLUDE_PATH) \
    $(PREBUILT_INCLUDE_PATH)/modules/core/include \
    $(PREBUILT_INCLUDE_PATH)/opencv2 \
    $(PREBUILT_INCLUDE_PATH)/modules/hal/include

LOCAL_MODULE            := libopencv_core_prebuilt
LOCAL_SRC_FILES := $(PREBUILT_PATH)/libopencv_core.a

include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE        := libNV
LOCAL_MODULE_TAGS   := optional
LOCAL_VENDOR_MODULE := true

LOCAL_C_INCLUDES := \
        external/opencv3/include/opencv \
        external/opencv3/include \
        external/opencv3/modules/core/include \
        external/opencv3/modules/hal/include \
        external/opencv3/modules/imgproc/include \
        external/opencv3/modules/photo/include \
        external/opencv3/modules/video/include \
        external/opencv3/modules/objdetect/include \
        external/opencv3/modules/features2d/include \
        external/opencv3/modules/flann/include \
        external/opencv3/modules/calib3d/include \
        external/opencv3/modules/imgcodecs/include \
        external/opencv3/modules/videoio/include \
        external/opencv3/modules/highgui/include \
        external/opencv3/modules/ml/include \
        external/opencv3/modules/shape/include \
        external/opencv3/modules/stitching/include \
        external/opencv3/modules/superres/include \
        external/opencv3/modules/videostab/include \
        external/jsoncpp/include \
        device/my_app/apps/external/OpenCL \
        $(LOCAL_PATH)/include \
        system/core/include

LOCAL_EXPORT_C_INCLUDE_DIRS := \
            $(LOCAL_PATH)/include

LOCAL_SRC_FILES := \
                src/NVOpencv.cpp \
                src/NVProcAngles.cpp \
                src/NVUtils.cpp \
                src/ILogger.cpp

LOCAL_CPPFLAGS := \
        -std=c++14 \
        -fPIC \
        -fsigned-char \
        -frtti \
        -fexceptions \
        -Wno-non-virtual-dtor \
        -Wno-unused-parameter \
        -Wno-write-strings

LOCAL_STATIC_LIBRARIES := \
        libopencv_hal \
        libopencv_core_prebuilt

LOCAL_SHARED_LIBRARIES := \
        libc++ \
        libopencv_imgproc ...
(more)
edit retag flag offensive close merge delete

Comments

This isn't a solution, but an interesting discovery. There is an example in the Android tree at

development/ndk/tests/prebuilt-library/jni

that follows the instructions at

https://developer.android.com/ndk/gui...

that also gives the same error as I get when built

ninja: error: 'out/target/product/neo/obj/SHARED_LIBRARIES/foo-prebuilt_intermediates/export_includes', needed by 'out/target/product/neo/obj/SHARED_LIBRARIES/foo-user_intermediates/import_includes', missing and no known rule to make it 08:50:08 ninja failed with: exit status 1 make: * [run_soong_ui] Error 1

epatton gravatar imageepatton ( 2019-01-21 10:58:21 -0500 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2019-03-05 11:44:10 -0500

epatton gravatar image

This is a possible solution using Android.bp (the Soong replacement for the Andoird make based built system). It works for the example found in the Android tree at (android-8.1.0_r52)

development/ndk/tests/prebuilt-library/jni

Now when typing "mm" i.e.

android-8.1.0_r52/development/ndk/tests/prebuilt-library/jni$ mm

The prebuilt shared libraries are linked and their export includes are found. Here are the steps (I'm in the process of trying this with my opencv project):

  1. android-8.1.0_r52/$ . build/envsetup.sh
  2. android-8.1.0_r52/$ lunch -> select #29 bullhead
  3. cd development/ndk/tests/prebuilt-library/jni
  4. Build 32-bit and 64-bit foo.so(s) export BUILD_FOO=1 mm
  5. mkdir lib lib64 cp $OUT/system/lib/foo.so lib/libfoo.so cp $OUT/system/lib64/foo.so lib64/libfoo.so
  6. Rename Android.mk to Android.mk.bu ("bu" for backup)
  7. Replace the $(gettop)/Android.bp with the Android.bp-top below (rename to Android.bp)
    • or simply add this line to the existing Android.bp: "development/ndk/tests/prebuilt-library/jni",
  8. Copy attached Android.bp to development/ndk/tests/prebuilt-library/jni
  9. mm

The steps above result in a native executable in a foo-user_exe in bullhead/system/bin/

Although this means I have to rewrite my existing Android.mk into a Android.bp, there are tools that can do this for you. i.e. "androidmk Android.mk > Android.bp"

Android.bp-top

subname = "Android.bp"

build = [
    "build/blueprint/Blueprints",
]

subdirs = [
    "build/soong",
]

optional_subdirs = [
    "art",
    "bionic",
    "bootable/recovery",
    "build/kati",
    "build/tools/*",
    "dalvik",
    "development/*",
    "development/ndk/tests/prebuilt-library/jni",
    "device/*/*",
    "external/*",
    "frameworks/*",
    "frameworks/compile/*",
    "frameworks/hardware/interfaces",
    "frameworks/opt/net/wifi",
    "hardware/*",
    "libcore",
    "libnativehelper",
    "packages/apps/*",
    "prebuilts/clang/host/linux-x86",
    "prebuilts/ndk",
    "prebuilts/sdk",
    "system/*",
    "system/hardware/interfaces",
    "system/tools/*",
    "test/vts",
    "test/vts-testcase/*",
    "vendor/*/*",
]

And the Android.bp

cc_prebuilt_library_shared {
    name: "libfoo",
    vendor: true,
    compile_multilib: "both",
    export_include_dirs: ["foo"],
    target: {
        android_arm: {
            srcs: ["lib/libfoo.so"],
        },
        android_arm64: {
            srcs: ["lib64/libfoo.so"],
        },
    },
    strip: {
        none:true,
    },
}

cc_library_shared {
    name: "foo-user",
    srcs: ["foo-user.c"],
    shared_libs: ["libfoo"],
}

cc_binary {
    name: "foo-user_exe",
    srcs: ["foo-user.c"],
    shared_libs: ["libfoo"],
    stl: "none",
}
edit flag offensive delete link more

Comments

Update: Since external/opencv3 is built on Android.mk, my Android.bp cannot see it's libraries. Apparently this is a known issue. Consequently I'm forced to using an Android.mk in my project yet have not figured out a way to get it to work.

epatton gravatar imageepatton ( 2019-03-22 16:20:32 -0500 )edit
Login/Signup to Answer

Question Tools

1 follower

Stats

Asked: 2019-01-15 12:40:34 -0500

Seen: 795 times

Last updated: Mar 22