Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android ndk nested modules

I have a native project that in frustration with the make system I got working by simply jamming all the code together many years ago. I attempted to port the project properly to gradle-experimental, but that's still a disaster 2.5 years later. I'm now trying to get the Android.mk system to work within the reorganized (for gradle-experimental) project.

Here's the organization:

  • jpeg (full native)
  • processor (full native, dependent on jpeg)
  • library (jni, dependent on processor and jpeg)

module
-jni (contains Application.mk, Android.mk)
-jpeg
--src
---main
----jni
-----Android.mk (and source co-located)
-processor
--src
----main
-----jni
------Android.mk
------/processor(source)
-library
--src
----main
-----java
-----jni
-----Android.mk (and source co-located)

I know I could flatten this if I use the make files, but I figure someday in 2020 Android Studio will truly support native so I figured I'd keep the current project format.

Here are my make files:

module/jni:

LOCAL_PATH := $(call my-dir)
STARTUP_DIR := $(LOCAL_PATH)

include $(STARTUP_DIR)/../jpeg/src/main/jni/Android.mk
include $(STARTUP_DIR)/../processor/src/main/jni/Android.mk
include $(STARTUP_DIR)/../library/src/main/jni/Android.mk

include $(CLEAR_VARS)

jpeg/jni:

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

LOCAL_ARM_MODE := arm

LOCAL_SRC_FILES := [truncated]

LOCAL_CFLAGS += -DAVOID_TABLES
LOCAL_CFLAGS += -O3 -fstrict-aliasing -fprefetch-loop-arrays
#LOCAL_CFLAGS += -march=armv6j

# enable tile based decode
LOCAL_CFLAGS += -DANDROID_TILE_BASED_DECODE

ifeq ($(TARGET_ARCH_VARIANT),x86-atom)
  LOCAL_CFLAGS += -DANDROID_INTELSSE2_IDCT
  LOCAL_SRC_FILES += jidctintelsse.c
endif

# enable armv6 idct assembly
ifeq ($(strip $(TARGET_ARCH)),arm)
  LOCAL_CFLAGS += -DANDROID_ARMV6_IDCT
endif

# use mips assembler IDCT implementation if MIPS DSP-ASE is present
ifeq ($(strip $(TARGET_ARCH)),mips)
  ifeq ($(strip $(ARCH_MIPS_HAS_DSP)),true)
  LOCAL_CFLAGS += -DANDROID_MIPS_IDCT
  LOCAL_SRC_FILES += \
      mips_jidctfst.c \
      mips_idct_le.S
  endif
endif

LOCAL_MODULE := libjpeg

include $(BUILD_STATIC_LIBRARY)

processor/jni

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_CFLAGS += -DUSE_JPEG
LOCAL_STATIC_LIBRARIES += libjpeg
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../jpeg/src/main/jni

LOCAL_MODULE     := processor

LOCAL_SRC_FILES := [truncated]

LOCAL_C_INCLUDES += [truncated]

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/processor/include
LOCAL_LDLIBS += -lz

include $(BUILD_SHARED_LIBRARY)

When I run ndk-build it will successfully build jpeg when it gets to the processor build. It will however fail to build any code referencing jpeg (in processor) with undefined references such as:

undefined reference to `jpeg_std_error(jpeg_error_mgr*)'

I have a feeling I'm doing something slightly wrong in setting up the parent Android.mk such that LOCAL_STATIC_LIBRARIES += libjpeg is not correctly importing. Anyone know what I might be doing wrong here?

like image 870
Anthony Avatar asked Apr 22 '16 19:04

Anthony


1 Answers

Turns out I pulled the wrong jpeg header which didn't have extern "C" to help with name mangling in c++. Fixing the header addressed the issue.

Additionally, I had to reorganize the folder structure as nested NDK is a nightmare if all projects don't fall under jni. It will start mangling LOCAL_PATH, wildcards, and basically any relative path.

like image 136
Anthony Avatar answered Nov 02 '22 11:11

Anthony