I've been building some native modules in order to improve my React Native app's performance.
I've learned how to build a native module with JSI bindings, which let you pass binary data as ArrayBuffer from JS to C++ so you can handle strings with NULL characters safely and process large data efficiently.
Here are two modules I made:
Now, it's time to integrate them with my app.
But I encountered an error when compiling the Android app:
More than one file was found with OS independent path 'lib/arm64-v8a/libcpp.so'
I confirmed each module works correctly on a separate project, so I suspected my project setting is wrong.
Checked build.gradle
and app/build.gradle
, but they look fine. Interesting.
Then, I found that it doesn't occur when I only installed one of them to my project.
So, using two causes the error. I looked closely at the error message. It says "More than one file" and both depend on "libcpp.so".
Well, where did "libcpp.so" come from? It looks like a std lib but no. I grepped the modules but couldn't find such build instruction.
I thought that it's the name of the shared libraries that my modules derive, and my project try to link them, but the name is duplicate.
react-native-quick-md5/android/CMakeLists.txt
looks like so:
cmake_minimum_required(VERSION 3.4.1)
set (CMAKE_VERBOSE_MAKEFILE ON)
set (CMAKE_CXX_STANDARD 11)
add_library(cpp
SHARED
../../react-native/ReactCommon/jsi/jsi/jsi.cpp
../cpp/quick-md5.cpp
../cpp/md5.cpp
cpp-adapter.cpp
)
# Specifies a path to native header files.
include_directories(
../cpp
../../react-native/React
../../react-native/React/Base
../../react-native/ReactCommon/jsi
)
add_library
adds a library to the project with specified name:
add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
[<source>...])
Bingo. So, both modules are trying to add themselves as the same name: "cpp".
In android/src/main/java/com/reactnativequickmd5/QuickMd5Module.java
, it calls System.loadLibrary("cpp");
like so:
class QuickMd5Module extends ReactContextBaseJavaModule {
static {
System.loadLibrary("cpp");
}
}
Well, let's rename it.
diff --git a/android/CMakeLists.txt b/android/CMakeLists.txt
index 3ea329f..5540dbe 100644
--- a/android/CMakeLists.txt
+++ b/android/CMakeLists.txt
@@ -4,19 +4,20 @@ set (CMAKE_VERBOSE_MAKEFILE ON)
set (CMAKE_CXX_STANDARD 11)
include_directories(
- ../cpp
- ../../react-native/React
- ../../react-native/React/Base
- ../../react-native/ReactCommon/jsi
-)
+ ../cpp
+ ../../react-native/React
+ ../../react-native/React/Base
+ ../../react-native/ReactCommon/jsi
+ )
-add_library(cpp
- SHARED
- ../../react-native/ReactCommon/jsi/jsi/jsi.cpp
- ../cpp/md5.cpp
- ../cpp/md5.h
- ../cpp/react-native-quick-md5.cpp
- ../cpp/react-native-quick-md5.h
- cpp-adapter.cpp
-)
+add_library(quickmd5 # Library name
+ SHARED
+ ../../react-native/ReactCommon/jsi/jsi/jsi.cpp
+ ../cpp/md5.cpp
+ ../cpp/md5.h
+ ../cpp/react-native-quick-md5.cpp
+ ../cpp/react-native-quick-md5.h
+ cpp-adapter.cpp
+ )
+target_link_libraries(quickmd5)
diff --git a/android/src/main/java/com/reactnativequickmd5/QuickMd5Module.java b/android/src/main/java/com/reactnativequickmd5/QuickMd5Module.java
index 8c9ce9a..223d319 100644
--- a/android/src/main/java/com/reactnativequickmd5/QuickMd5Module.java
+++ b/android/src/main/java/com/reactnativequickmd5/QuickMd5Module.java
@@ -8,7 +8,7 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
class QuickMd5Module extends ReactContextBaseJavaModule {
static {
- System.loadLibrary("cpp");
+ System.loadLibrary("quickmd5");
}
It worked!
Hope it helps :)