问题
I had built VTK on Linux with Android NDK r17c and the result was 54 static (.a) libraries of total 600+ MB. Now, I had imported these librarires to my AndroidStudio 3.3 project and I would like to use the built libraries in my native code. In Android Studio I am using the same version of the NDK (r17c).
In AndroidStudio I had created new module for using the VTK and inside that module I am using ndk-build for building the library. The structure of the module is:
...
|--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
I am using the VTK library in my vtk-lib.cpp file (which I am accessing from Java code).
In order just to get this to work, I wasn't building the library for all of the supported android architectures (but only for my arm64-v8a device), so I defined an Application.mk file like this:
APP_STL := c++_static
API_ABI := arm64-v8a
In my Android.mk file, I had defined 54 modules with PREBUILT_STATIC_LIBRARY
(one for each of the 54 built .a files). In the end, I am building a BUILD_SHARED_LIBRARY
with vtk-lib.cpp file to be accessible from 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)
When I try to build the application a get a bunch of the errors regarding the undefined reference
as shown below:
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
I had came across this github thread so I had tried using the LOCAL_WHOLE_STATIC_LIBRARIES
instead of LOCAL_STATIC_LIBRARIES
, different versions of LOCAL_LDLIBS
and LOCAL_LDFLAGS
but still no luck.
Any help?
回答1:
This is most likely not circular dependency, but only wrong order on the list.
If all undefined references are from VTK libraries, you can simply find the working order for LOCAL_STATIC_LIBRARIES, eliminating these link errors one by one. E.g. the first error means that vtkCommonCore
must go behind vtkFiltersSources
, the second – that vtkCommonExecutionModel
should also go after vtkFiltersSources
.
VTK supports CMake, so if you use CMake instead of Android.mk build scripts, it may be easier to achieve the correct dependency order.
回答2:
I ended up using CMake insted of ndk-build.
I needed to add this code to my module's 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"
}
}
}
And, my CMakeLists.txt looks like this:
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
)
来源:https://stackoverflow.com/questions/56296901/linking-vtk-with-ndk-build-on-ndk-r17c-results-with-undefined-references-error