Связывание VTK с ndk-build на NDK r17c приводит к ошибкам «неопределенные ссылки» - PullRequest
1 голос
/ 24 мая 2019

Я построил VTK для Linux с Android NDK r17c, и в результате было получено 54 статических (.a) библиотеки общей емкостью 600+ МБ.Теперь я импортировал эти библиотеки в свой проект AndroidStudio 3.3, и я хотел бы использовать встроенные библиотеки в своем нативном коде.В Android Studio я использую ту же версию NDK (r17c).

В AndroidStudio я создал новый модуль для использования VTK, а внутри этого модуля я использую ndk-build для сборки библиотеки.Структура модуля:

...
|--jni/
|--|--include/
|--|--|--vtkAbstractArray.h
|--|--|--vtkAbstractCellLinks.h
|--|--|-- ...
|--|--lib/
|--|--|--arm64-v8a/
|--|--|--|--libvtkCommonColor-8.9.0.a
|--|--|--|--libvtkCommonComputationalGeometry-8.9.0.a
|--|--|--|--...
|--|--Application.mk
|--|--Android.mk
|--|--vtk-lib.cpp

Я использую библиотеку VTK в моем файле vtk-lib.cpp (доступ к которому осуществляется из кода Java).

Чтобы это работало, я не собирал библиотеку для всех поддерживаемых архитектур Android (а только для моего устройства arm64-v8a ), поэтому я определил приложение .mk файл выглядит так:

APP_STL := c++_static
API_ABI := arm64-v8a

В моем файле Android.mk я определил 54 модулей с PREBUILT_STATIC_LIBRARY (по одному на каждыйиз 54 встроенных файлов .a).В конце я создаю BUILD_SHARED_LIBRARY с файлом vtk-lib.cpp, который будет доступен из Java:

LOCAL_PATH := $(call my-dir)

#prepare vtk-common-color
include $(CLEAR_VARS)
LOCAL_MODULE := vtk-common-color
LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libvtkCommonColor-8.90.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

#...53 more modules for every .a static library

include $(CLEAR_VARS)
LOCAL_SRC_FILES  := vtk-lib.cpp
LOCAL_MODULE     := vtk-lib
LOCAL_STATIC_LIBRARIES := vtk-common-color ... # 53 more module names
LOCAL_CPP_FEATURES := rtti exceptions
LOCAL_CPPFLAGS += --std=c++11
include $(BUILD_SHARED_LIBRARY)

Когда я пытаюсь построить приложение, получаю кучу ошибок, касающихся undefined reference как показано ниже:

Build command failed.
Error while executing process [some path]\Android\sdk\ndk-bundle\ndk- 
build.cmd with arguments {NDK_PROJECT_PATH=null 
APP_BUILD_SCRIPT=[some path]\src\main\jni\Android.mk NDK_APPLICATION_MK= 
[some path]\src\main\jni\Application.mk APP_ABI=arm64-v8a 
NDK_ALL_ABIS=arm64-v8a NDK_DEBUG=1 APP_PLATFORM=android-23 
NDK_OUT=[some path]/build/intermediates/ndkBuild/debug/obj 
NDK_LIBS_OUT=[some path]\build\intermediates\ndkBuild\debug\lib [some 
path]build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/libvtk-lib.so}

[arm64-v8a] Compile++      : vtk-lib <= vtk-lib.cpp
[arm64-v8a] SharedLibrary  : libvtk-lib.so
[some path]/src/main/jni/lib/arm64-v8a/libvtkFiltersSources- 
8.90.a(vtkConeSource.cxx.o): In function `vtkConeSource::New()':
[some path ON LINUX]/VTK/Filters/Sources/vtkConeSource.cxx:30: undefined 
reference to `vtkObjectBase::InitializeObjectBase()'
[some path]/src/main/jni/lib/arm64-v8a/libvtkFiltersSources- 
8.90.a(vtkConeSource.cxx.o): In function 
`vtkConeSource::vtkConeSource(int)':
[some path ON LINUX]/VTK/Filters/Sources/vtkConeSource.cxx:35: undefined 
reference to `vtkPolyDataAlgorithm::vtkPolyDataAlgorithm()'

#etc etc many more errors

Я сталкивался с этим потоком github , поэтому я попытался использовать LOCAL_WHOLE_STATIC_LIBRARIES вместо LOCAL_STATIC_LIBRARIES, различные версии LOCAL_LDLIBS иLOCAL_LDFLAGS но все равно не повезло.

Любая помощь?

Ответы [ 2 ]

2 голосов
/ 24 мая 2019

Скорее всего, это не круговая зависимость, а только неправильный порядок в списке.

Если все неопределенные ссылки взяты из библиотек VTK, вы можете просто найти рабочий порядок для LOCAL_STATIC_LIBRARIES, устраняя эти ошибки ссылки по одной. Например. первая ошибка означает, что vtkCommonCore должна идти после vtkFiltersSources, вторая - что vtkCommonExecutionModel также должна идти после vtkFiltersSources.

VTK поддерживает CMake, поэтому если вы используете CMake вместо Android.mk сценариев сборки, может быть проще добиться правильного порядка зависимостей.

1 голос
/ 25 мая 2019

В итоге я использовал CMake вместо ndk-build.

Мне нужно было добавить этот код в build.gradle моего модуля:

android {
    ...

    defaultConfig {
        ...

        externalNativeBuild {
            cmake {
                cppFlags "-std=c++11"
                arguments "-DANDROID_CPP_FEATURES=rtti exceptions",
                        "-DANDROID_STL=gnustl_shared"
                abiFilters 'arm64-v8a'
            }
        }
    }

    ...

    externalNativeBuild {
        cmake {
            path "src/main/jni/CMakeLists.txt"
        }
    }
}

И мой CMakeLists.txt выглядит следующим образом:

cmake_minimum_required(VERSION 3.4.1)

set(LIB_DIR ${PROJECT_SOURCE_DIR}/lib/${ANDROID_ABI})

add_library(vtk-common-color STATIC IMPORTED)
set_target_properties(vtk-common-color
    PROPERTIES IMPORTED_LOCATION
    ${LIB_DIR}/libvtkCommonColor-8.90.a)

#53 more libraries

add_library( vtk-lib SHARED ${PROJECT_SOURCE_DIR}/vtk-lib.cpp)

target_include_directories(vtk-lib PRIVATE ${PROJECT_SOURCE_DIR}/include)

target_link_libraries(
    vtk-lib
    -Wl,--start-group -L ${TARGET_OUT}
    vtk-common-color
    #53 more libraries names
    -Wl,--end-group
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...