꿈소년의 개발 이야기

More than one file was found with OS independent path 본문

Android Development

More than one file was found with OS independent path

꿈소년 2021. 1. 21. 12:33
반응형

앱 빌드를 실패했다.

 멀티 모듈 구조에서 앱 모듈에 필요한 기능을 붙이기 위해서 해당 기능을 구현한 모듈을 하나 생성했습니다.

demeter law 라는 걸 아실까요? 모듈 간 의존성을 제외 시키기 위해서 기존 구성을 변경했습니다.


 라이브러리 모듈을 생성해서 넣어두었는데, 예기치 못한 빌드 시점에 아래와 같은 에러가 생기면서 apk 패키징이 되지 않는 현상이 발생했습니다.

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:mergeDevDebugNativeLibs'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
   > More than one file was found with OS independent path 'lib/armeabi-v7a/libsMRman.so'. If you are using jniLibs and CMake IMPORTED targets, see https://developer.android.com/studio/preview/features#automatic_packaging_of_prebuilt_dependencies_used_by_cmake

  위 에러 로그에 있는 링크가 도움이 될까 싶어서 가봤지만, 이미 다른 내용으로 채워진 페이지가 나타납니다.

그렇다고 포기할 순 없죠. 원래 보여주려던 내용이 뭐였는지 찾아봤습니다. 그랬더니 아래 내용이 있었습니다.
https://developer.android.com/studio/releases/gradle-plugin#cmake-imported-targets

 

Android Gradle 플러그인 출시 노트  |  Android 개발자  |  Android Developers

Android 스튜디오 빌드 시스템은 Gradle을 기반으로 하며 Android Gradle 플러그인에는 Android 앱을 빌드하는 데 사용하는 몇 가지 추가 기능이 있습니다.

developer.android.com

 그래들이 변경되면서 예전 so 라이브러리 파일들에 대한 처리를 자동 패키징 해준다고 되어 있습니다. 오류 메시지에 대해서도 설명이 나와 있는데, 동일한 so 라이브러리가 중복으로 들어가게 되면서 나타난 오류라고 합니다.

중복을 제거하기 위한 방안

 동일한 오류 메시지이지만, 원문에서 말하는 것과 제가 찾아서 해결한 방식은 조금 달랐습니다.

 일단 여기 링크에 나온 내용은 빌드 그래들에 설정된 jniLibs 관련 내용을 제거하는 것이지만, 이번 경우에는 결국 어디선가 같은 so 라이브러리를 사용하고 있다는 것이 문제가 되는 상황이였습니다.

 그래서 해당 라이브러리 말고도 중복되는 라이브러리가 있는지 확인해봤는데, 총 3개의 라이브러리 so 파일 중에 2개가 중복되어 있었습니다. 따로 찾아내려고 찾은 건 아니고, 패키징 시점에 어디선가 들어가는 것 같은데, 알 길이 없어서 에러가 난 라이브러리 파일을 지우면서 확인했습니다.

 그랬더니 중복된 라이브러리 so 파일을 모두 찾아 냈고요. 이 파일들을 제거하고, 빌드 한 결과로는 패키징에 문제가 없이 진행되었습니다.

다른 방안

 만약 패키징 처리를 할 때, 라이브러리 so 파일들을 제거하지 않고 남겨 두고 진행하고 싶다면, 패키징 대상이 대는 모듈에서  빌드 그래들에 아래 내용을 추가해주면 됩니다.

    packagingOptions {
        pickFirst 'lib/arm64-v8a/*'
        pickFirst 'lib/armeabi-v7a/*'
    }

추가 항목은 ABI 타입에 맞춰서 더 추가하면 될 겁니다.

이 방식은 먼저 사용할 것을 미리 지정한 방식이기 때문에 잘 생각해보고 진행해 봐야 할 것 같습니다.

동일한  so 라이브러리가 있을 때, 과연 그 라이브러리 내부 코드가 동일한 버전인지 여부는 알 수 없을 것 같거든요.

 

그리고 중요한 건, 기능 상 문제가 없는지도 여전히 확인해봐야 합니다.