Search code examples
androidcmakeandroid-ndkopusexternal-project

Use ExternalProject_Add to include Opus in Android


This is probably quite simple.

I have an Android project that uses NDK. I will like to include the opus source code in the native code. I have tried using the ExternalProject_Add property of CMake but my native code still cannot import headers from the Opus library and fails to build.

Below is my ExternalProject_Add definition:

ExternalProject_Add(project_opus
  URL https://archive.mozilla.org/pub/opus/opus-1.2.1.tar.gz
  CONFIGURE_COMMAND <SOURCE_DIR>/configure --prefix=<INSTALL_DIR>
  BUILD_COMMAND make
  INSTALL_COMMAND make install
)

ExternalProject_Get_Property(project_opus install_dir)
include_directories(${install_dir}/include)

add_library(opus SHARED IMPORTED)
add_dependencies(opus project_opus)

target_link_libraries( # Specifies the target library.
                       native-lib

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} opus oboe OpenSLES)

Solution

  • So, here is the CMakeLists.txt for opus:

    cmake_minimum_required(VERSION 3.4.1)
    include(ExternalProject)
    
    set(OPUS_ROOT ${Project_BINARY_DIR}/project_opus-prefix/src/project_opus)
    
    ExternalProject_Add(project_opus
      URL https://archive.mozilla.org/pub/opus/opus-1.2.1.tar.gz
      CONFIGURE_COMMAND ""
      INSTALL_COMMAND ""
      BUILD_COMMAND
        ${ANDROID_NDK}/ndk-build
        -C ${OPUS_ROOT}
        NDK_PROJECT_PATH=null
        APP_BUILD_SCRIPT=${Project_SOURCE_DIR}/opus.mk
        NDK_OUT=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/../..
        NDK_LIBS_OUT=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/..
        APP_ABI=${ANDROID_ABI}
        NDK_ALL_ABIS=${ANDROID_ABI}
        APP_PLATFORM=${ANDROID_PLATFORM}
      BUILD_BYPRODUCTS ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libopus.so
    )
    
    add_library(opus SHARED IMPORTED)
    add_dependencies(opus project_opus)
    
    set_target_properties(opus PROPERTIES IMPORTED_LOCATION ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libopus.so )
    include_directories(${OPUS_ROOT}/include)
    
    target_link_libraries( # Specifies the target library.
                       native-lib
    
                       # Links the target library to the log library
                       # included in the NDK.
                       log opus oboe OpenSLES)
    

    Next to this file, you must put this opus.mk file which I borrowed from android-ffmpeg-builder on GitHub:

    LOCAL_PATH := .
    
    include $(CLEAR_VARS)
    
    #include the .mk files
    include $(LOCAL_PATH)/celt_sources.mk
    include $(LOCAL_PATH)/silk_sources.mk
    include $(LOCAL_PATH)/opus_sources.mk
    
    MY_MODULE_DIR       := opus
    
    LOCAL_MODULE        := $(MY_MODULE_DIR)
    
    #fixed point sources
    SILK_SOURCES += $(SILK_SOURCES_FIXED)
    
    #ARM build
    CELT_SOURCES += $(CELT_SOURCES_ARM)
    SILK_SOURCES += $(SILK_SOURCES_ARM)
    LOCAL_SRC_FILES     := \
        $(CELT_SOURCES) \
        $(SILK_SOURCES) \
        $(OPUS_SOURCES) \
        $(OPUS_SOURCES_FLOAT)
    
    LOCAL_LDLIBS        := -lm -llog
    
    LOCAL_C_INCLUDES    := \
        $(LOCAL_PATH)/include \
        $(LOCAL_PATH)/silk \
        $(LOCAL_PATH)/silk/fixed \
        $(LOCAL_PATH)/silk/float \
        $(LOCAL_PATH)/celt
    
    # don't disable the float api
    LOCAL_CFLAGS        := -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64
    LOCAL_CFLAGS        += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT=1 -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -O3 -fno-math-errno
    LOCAL_CPPFLAGS      := -DBSD=1
    LOCAL_CPPFLAGS      += -ffast-math -O3 -funroll-loops
    
    include $(BUILD_SHARED_LIBRARY)
    

    On the face of it, this only supports ARM build.