如何让Conan.io将预构建ARM共享库放入Android项目jniLibs目录?
Great question! When working with pre-built ARM .so libraries packaged via Conan, getting them automatically copied to Android's jniLibs directory isn't covered in basic docs, but there are two straightforward approaches to solve this:
Approach 1: CMake Post-Build Copy (Simplest, Works With Existing Setup)
Since you're already linking the library via CMake, you can add a custom post-build command to copy the .so file directly to the correct jniLibs subdirectory. This avoids modifying your Conan package configuration entirely.
- In your project's
CMakeLists.txt, after callingconan_basic_setupandtarget_link_libraries, add this code:
# Replace "YourAndroidTarget" with your actual CMake target name get_target_property(LIBRARY_SO_PATH YourAndroidTarget IMPORTED_LOCATION) # Map Conan architecture to Android jniLibs subdirectory if(${CONAN_SETTINGS_ARCH} STREQUAL "armv7") set(ANDROID_ARCH_SUBDIR "armeabi-v7a") elif(${CONAN_SETTINGS_ARCH} STREQUAL "armv8") set(ANDROID_ARCH_SUBDIR "arm64-v8a") else() set(ANDROID_ARCH_SUBDIR "${CONAN_SETTINGS_ARCH}") endif() # Define the full jniLibs path (adjust the base path if your project structure differs) set(JNI_LIBS_DEST ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ARCH_SUBDIR}) # Create the directory if it doesn't exist file(MAKE_DIRECTORY ${JNI_LIBS_DEST}) # Copy the .so file after building the target (only if it's changed) add_custom_command(TARGET YourAndroidTarget POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${LIBRARY_SO_PATH} ${JNI_LIBS_DEST}/ COMMENT "Copying pre-built .so to jniLibs/${ANDROID_ARCH_SUBDIR}")
This will automatically copy the library every time you build your Android target, and handles different ARM architectures correctly.
Approach 2: Conan Deployer (Conan-Managed Workflow)
If you prefer to let Conan handle the deployment entirely, you can extend your package's Conan configuration to include a dedicated deploy step.
Step 1: Create a Custom Conanfile for Your Package
Instead of using conan export-pkg with just command-line args, create a conanfile.py in your package source directory:
from conans import ConanFile class LibraryNameConan(ConanFile): name = "LibraryName" version = "0.1" settings = "os", "compiler", "build_type", "arch" exports_sources = "*.h", "lib/*.so" def package(self): # Copy headers and pre-built .so to the standard Conan package structure self.copy("*.h", dst="include") self.copy("*.so", dst="lib", src="lib") def deploy(self): # Map Conan arch to Android jniLibs subdirectory arch_map = { "armv7": "armeabi-v7a", "armv8": "arm64-v8a" } android_arch = arch_map.get(str(self.settings.arch), str(self.settings.arch)) # Define the destination jniLibs path (adjust relative path as needed for your project) jni_libs_dest = f"{self.deploy_folder}/../src/main/jniLibs/{android_arch}" # Copy the .so files to jniLibs self.copy("*.so", dst=jni_libs_dest, src="lib")
Step 2: Export and Install with Deployment
- Export the package with your new Conanfile:
conan export-pkg . ext/stable --force -pr android_19_arm_clang
- Run Conan install with the deploy flag to trigger the copy:
conan install . --deploy deploy -pr android_19_arm_clang
This will automatically copy the .so files to the correct jniLibs subdirectory during the Conan install step.
Key Notes
- Ensure your Conan profile (
android_19_arm_clang) correctly sets the architecture (armv7/armv8) matching your pre-built library. - Adjust the base path to
jniLibsin either approach if your project uses a non-standard structure (e.g., multi-module Android projects).
内容的提问来源于stack exchange,提问作者Soccertrash

