MSM8994의 화룡점정 블로그

[Ubuntu] WebRTC 안드로이드용 라이브러리 컴파일 본문

코딩

[Ubuntu] WebRTC 안드로이드용 라이브러리 컴파일

msm8994 2019. 3. 12. 06:30

WebRTC는 영상 통화에 쓰이는 로열티프리 공개 웹 기술입니다.

구글, 모질라, 오페라 등이 지원하는 프로젝트인데

크롬, 파이어폭스, 오페라, 안드로이드, iOS용 코드가 제공됩니다.


오늘은 WebRTC 그중에서 안드로이드용 라이브러리 사용에 대해서 알려드리려고 합니다.




과거

2년 전인 2017년만해도 안드로이드용 WebRTC 라이브러리는 공식적으로 미리 컴파일된 라이브러리가 없어서 쓸 사람이 직접 컴파일 했어야 했습니다. 라이브러리를 컴파일 하는데 요구 성능이 높고, 소스 코드만 20GB는 가뿐히 넘고 컴파일시 더 불어나는 저장공간 점유 문제가 있고, 어렵사리 컴파일을 하더라도 크롬의 업데이트 주기인 6주 또는 수시로 갱신되서 자주 컴파일 해줬어야했습니다.



현재

이제는 사정이 다릅니다. 구글이 공식적으로 컴파일을 해서 내놓고 있고, 안드로이드 스튜디오에서 아래 명령어를 build.gradle에 넣어두기만 하면 20MB 정도의 다운로드로 WebRTC 지원을 앱에 추가할 수 있습니다.

implementation 'org.webrtc:google-webrtc:1.0.+'



그럼 왜 컴파일을 하죠?

각자의 요구사항이 있을겁니다. 소스코드에서 잘못을 못찾겠어서 라이브러리 잘못인지 의심하기 위해서 로그를 봐야할 수도 있고, PlayRTC 등 여러 독자 서비스처럼 자신들의 요구사항을 하나하나 반영시키는 개조의 사례도 있을 것이기 때문이죠. 그래서 오늘은 컴파일 하는 방법을 소개시켜드리려고 합니다.




시스템 요구사항 (Xubuntu LTS 18.04 x64 기준)


코어갯수 많고 성능 좋은 CPU 

노트북은 웬만해선 권장하지 않습니다.

i5 구세대 저전력 CPU는 듀얼코어여서 한 아키텍쳐(arm, arm64 ...)당 컴파일이 3시간 가까이 걸렸기 때문이죠. 

플레이 스토어 역시 2019년 8월부터 앱스토어 처럼 64비트 기기 지원이 의무가 됐는데 OS 업데이트 배급이 지지부진한 안드로이드는 iOS처럼 32비트 기기를 쳐내진 못했습니다. 따라서 32비트 기기도 지원을 해야하기 때문에 최소 2번의 컴파일이 필요합니다.


4GB 이상의 램

저사양용 우분투 변종 Xubuntu를 설치한 VM에다 3GB 램을 할당해서 돌려도 2GB 도 안넘는 때가 많고 컴파일도 잘 됩니다만 혹시나 중단될 수 있으므로 4GB 이상을 준비하십시오.


48GB 이상의 용량을 가진 디스크

컴파일 후 프로젝트 폴더가 24GB가 넘고 컴파일당 4GB 넘는 용량이 점유됩니다. 여기에 OS 자체 공간도 들고 빌드 도구까지 따로 설치하면 공간이 더 필요하겠죠?

기본 소스코드 취득 도구 depot_tools 및 소스코드 source 폴더의 용량


arm 및 arm64용으로 컴파일된 파일들의 용량차지

물론 실제로 앱에 탑재해야할 파일은 20MB가 채 되지 않습니다.



처음부터 컴파일 하기

여기서는 저사양용 우분투 변종 Xubuntu 64비트를 통한 컴파일을 설명드리도록 하겠습니다. 일반 우분투는 그래픽 효과 등 자원 점유율이 더 많아 더 많은 램 등 높은 성능이 요구됩니다 


1.먼저 git을 설치합니다.

Xubuntu에는 git이 설치되어있지 않습니다.

아래 명령어를 실행하는 도중 멈추면 엔터키를 누르거나 Y를 입력합니다.

sudo apt install git




2. 오라클JDK를 설치합니다. 오픈JDK는 컴파일에 필요한 도구가 일부 없어 작업을 완료할 수 없습니다.

Xubuntu에는 openJDK 포함 JDK가 설치되어있지 않으며 오라클은 별도 저장소를 가져오기 해야합니다.

아래 명령을 실행하는 도중 멈추면 엔터키를 눌러주세요

sudo add-apt-repository ppa:webupd8team/java




실행 후 우분투 소프트웨어 저장소 정보를 새로고침합니다.

sudo apt update

이제 오라클 JDK를 설치합니다 멈추면 화살표 키를 이용해 Accept를 빨간색으로 강조한 뒤 엔터를 눌러주세요

sudo apt install oracle-java8-installer




3. depot_tools를 설치합니다.

depot_tools를 가져옵니다. 자동으로 프롬프트가 있던 폴더에 새롭게 depot_tools 폴더를 만들어 들어가집니다.

git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git



가져온 depot_tools를 ~/.bashrc 파일에 반영하는데, Xfce에는 마우스패드라는 텍스트 에디터가 있습니다.

mousepad ~/.bashrc

새롭게 뜬 창 맨 아랫줄에 다음 코드를 추가합니다. 이 때 /프롬프트가/있던/폴더의/depot_tools 는 본인 상황에 맞게 바꿔줍니다. 제 경우는 /home/test/Downloads/depot_tools 입니다.

export PATH=$PATH:/프롬프트가/있던/폴더의/depot_tools

Ctrl+S 를 눌러 저장합니다.



4. 소스코드를 가져옵니다.

새 폴더 source를 만든 뒤 source로 들어갑니다.

mkdir source
cd source

소스코드를 가져온뒤 동기화 합니다. Android SDK와 NDK 파일이 거대해서 이것만으로도 차지할 저장공간이 16GB가 넘습니다.

fetch --nohooks webrtc_android
gclient sync




5. 의존성 도구를 설치합니다.

새로 생성된 src 폴더로 들어가는게 먼저입니다.

cd src
이후 스크립트를 실행하세요

./build/install-build-deps.sh



6. 환경 구성을 합니다.

이 작업은 다운받은 소스코드의 third_party/android_tools 를 PATH에 연결해 adb 등을 사용하게 해줍니다.

. build/android/envsetup.sh



7. (건너뛰기 가능) 코드 수정이 필요하다면 합니다

시험삼아 같은 일을 하는 코드를 다른 모양으로 고쳐봤습니다.



8. 컴파일합니다

각 아키텍쳐별로 out 폴더를 생성하고 컴파일 합니다.

컴파일에는 수 시간이 걸립니다. 인내를 갖고 기다립시다.


ARM: 32비트. 오래된 안드로이드의 주류 아키텍쳐

gn gen out/arm --args='target_os="android" target_cpu="arm"'
ninja -C out/arm

ARM64: 64비트. 롤리팝 이후 최신폰의 주류 아키텍쳐

gn gen out/arm64 --args='target_os="android" target_cpu="arm64"'
ninja -C out/arm64

x86: 32비트. 인텔 CPU가 주로 쓰인 듀얼부팅 태블릿 또는 PC의 가상/에뮬레이터 앱플레이어용

gn gen out/x86 --args='target_os="android" target_cpu="x86"'
ninja -C out/x86

x86_64: 64비트. 인텔 CPU가 주로 쓰인 듀얼부팅 태블릿 또는 PC의 가상/에뮬레이터 앱플레이어용

gn gen out/x86_64 --args='target_os="android" target_cpu="x86_64"'
ninja -C out/x86_64



이후 소스코드가 업데이트 된다면 4번의 마지막 작업인 gclient sync를 한 다음 5번부터 다시 진행하시면 됩니다.




파일 꺼내기

컴파일이 완료되었습니다. 파일을 꺼냅시다.

자바코드인 jar는 아키텍쳐별로 따로 분리해서 사용하지 않으므로 한 번만 꺼내시면 되고,

C코드인 so 파일은 아키텍쳐별로 다 다르므로 하나씩 다 꺼내셔야 합니다.


jar: (아키텍쳐별 폴더)/lib.java/sdk/android/libwebrtc.jar (1MB 정도)


so: (아키텍쳐별 폴더)/lib.unstripped/libjingle_peerconnection_so.so(40MB 정도)


직접 컴파일한건 왠지 모르게 용량이 크더라구요.




프로젝트에 넣기

안드로이드 스튜디오 프로젝트 폴더의 최상위에서 libs 폴더에 jar 파일을 넣습니다.

안드로이드 스튜디오 프로젝트 폴더의 모듈("app" 등) 폴더의 src/main로 들어가 jniLibs 폴더를 생성합니다. 


아래의 이름대로 jniLibs 안에 4개의 폴더를 생성합니다.

arm64-v8a
armeabi-v7a
x86
x86_64

arm64-v8a에는 arm64에서 꺼낸 so 파일을

armeabi-v7a에는 arm에서 꺼낸 so 파일을

x86에는 x86에서 꺼낸 so 파일을

x86_64에는 x86_64에서 꺼낸 so 파일을


넣어줍니다.



해당 모듈의 build.gradle 에서 아래 줄이 있는지 확인합니다. 없으면 추가하세요.

implementation fileTree(dir: 'libs', include: ['*.jar'])



이제 Sync Project with Gradle 하시면 라이브러리가 인식되고 앱 제작시 반영될 것입니다.





번외: 릴리즈 브랜치로 작업하기

지금까지 설명드린 컴파일 과정은 master branch를 기준으로, 최신 커밋이 반영되어있지만, 검증되지 않은 수정이 뾰족하고 튀어나올 수 있습니다. 이미 release 되어 변경이 잘 없을 브랜치로 이동해 작업하는 것을 설명드리겠습니다.

1. 브랜치 목록 보기

git branch -r


Enter키를 계속 누르다가 (END)표시가 뜨면 q를 눌러 빠져나오면 됩니다.


2. branch 변경

브랜치를 갈아타기전에 혹시 수정하신 사항이 있는지 확인해야 합니다.

수정한 사항이 있다면 임시보관 처리해야 합니다.

git stash save

이제 변경 사항이 stash로 임시보관 처리되었습니다. git 사용법은 지면상 적지 않겠습니다.


브랜치를 변경합니다. 방금 git branch -r로 확인하셨죠? 그걸 브랜치이름 대신 넣으시면 됩니다.

git checkout -b refs/remotes/브랜치이름


다시 동기화합니다.

gclient sync


변경사항을 불러옵니다.

git stash pop

stash에 임시보관된 내용이 다시 코드에 적용됩니다.

만약 코드의 다른 부분 때문에 오류가 발생한다면 충돌을 직접 해결하셔야 합니다.


이제 컴파일을 5번 작업부터 다시 하시면 됩니다.





맺음말


오늘은 코딩 작업에 도움이 될 만한 팁을 준비했습니다.

보통은 구글이 제공하는걸 갖다쓰도록 그래들에 한 줄 넣는걸로 해결되시겠지만, 

만약의 경우가 발생했을 때 이 글이 부디 도움이 되셨길 기원합니다. 감사합니다.

Comments