MEGAchat 의 개발 및 컴파일을 위해 우리는 주로 CMake를 크로스 플랫폼 프로젝트 구성 도구로 사용합니다. 또한 VCPKG를 사용하여 Windows, MacOS 및 Linux 등 대부분의 플랫폼에서 MEGAchat 구축하는 데 필요한 종속성을 관리합니다.
각 운영 체제에 필요한 빌드 도구에 대한 자세한 내용은 MEGA SDK 저장소의 빌드 도구 장을 검토하세요.
Android용 WebRTC의 WebRTC Android 컴파일에 대한 추가 정보
MEGAchat 작동하려면 몇 가지 종속성이 필요합니다. 대부분은 구성 단계에서 VCPKG를 사용하여 자동으로 다운로드되고 구축됩니다.
Linux의 경우 VCPKG가 종속성을 구축할 수 있도록 시스템에 일부 추가 라이브러리가 필요합니다. Debian 기반 배포판의 경우 다음 명령을 사용하여 필요한 라이브러리를 설치할 수 있습니다.
sudo apt install python3-pkg-resources libglib2.0-dev libgtk-3-dev libasound2-dev libpulse-dev
패키지 이름은 Linux 배포판마다 다를 수 있지만 동일한 라이브러리를 제공하는 패키지를 사용하여 성공적으로 빌드되어야 합니다.
리포지토리 루트에 있는 vcpkg.json 파일에서 전체 종속성 세트를 살펴볼 수 있습니다.
MEGAchat MEGA SDK 라이브러리도 필요합니다. 이 문서 뒷부분에 MEGAchat 과 함께 사용하는 방법에 대한 지침이 있습니다. MEGA SDK 프로젝트는 MEGAchat CMake에 의해 자동으로 로드되므로 예상 경로에 복제하기만 하면 됩니다.
시스템에 설치해야 하는 추가 선택적 종속성은 Qt Framework뿐입니다. Qt 예제 앱을 빌드하는 데만 필요하지만 테스트, CLI 예제 또는 라이브러리 자체에는 필요하지 않습니다.
우선, MEGAchat 으로 작업하기 위해 선택한 디렉토리를 준비하십시오. mega
디렉터리는 이 문서의 예제에서 작업 공간 디렉터리로 사용됩니다.
mkdir mega
cd mega
디렉터리를 준비한 후 MEGAchat 저장소를 복제하여 MEGAchat 소스 코드를 얻습니다.
git clone https://github.com/meganz/MEGAchat
MEGAchat 작동하려면 MEGA SDK가 필요하므로 예상 경로에 MEGA SDK를 복제하세요.
git clone https://github.com/meganz/sdk MEGAchat/third-party/mega
마지막으로 MEGAchat 폴더 옆에 VCPKG 저장소를 복제합니다. 이미 VCPKG를 사용하고 있고 리포지토리의 로컬 복제본이 있는 경우 이 단계를 건너뛰고 시스템에서 기존 VCPKG를 사용할 수 있습니다.
git clone https://github.com/microsoft/vcpkg
다음 지침은 명령줄 인터페이스(CLI)에서 프로젝트를 구성하기 위한 것이지만, 동일한 CMake 매개변수가 구성된 경우 cmake-gui 또는 CMake와 호환되는 모든 편집기나 IDE가 적합해야 합니다.
MEGAchat 다른 일반 CMake 프로젝트처럼 구성됩니다. 항상 필요한 유일한 매개변수는 타사 종속성을 관리하는 VCPKG 디렉터리입니다. MEGA SDK 종속성은 MEGAchat 빌드의 일부로 구축됩니다.
MEGAchat 구성하려면 작업 공간( mega
디렉터리)에서 CMake를 실행합니다.
cmake -DVCPKG_ROOT=vcpkg -DCMAKE_BUILD_TYPE=Debug -S MEGAchat -B build_dir
참고 1 : Visual Studio와 같은 다중 구성 생성기에는 -DCMAKE_BUILD_TYPE=<Debug|Release>
가 필요하지 않을 수 있습니다.
참고 2 Qt Framework가 시스템에 설치되어 있지만 CMake가 이를 감지하지 못하는 경우 CMake가 찾을 수 있도록 -DCMAKE_PREFIX_PATH=</path/to/qt/install/dir>
추가할 수 있습니다. Qt가 설치되어 있지 않고 설치를 원하지 않는 경우 -DENABLE_CHATLIB_QTAPP=OFF
설정하여 Qt 예제 앱을 비활성화할 수 있습니다. 라이브러리, CLI 예제 및 테스트는 계속 빌드됩니다.
위의 cmake 명령에서는 단순화를 위해 상대 경로가 사용되었습니다. VCPKG, MEGAchat 또는 빌드 디렉터리의 위치를 변경하려면 해당 항목에 대해 유효한 상대 또는 절대 경로를 제공하기만 하면 됩니다.
프로젝트 구성 중에 VCPKG는 플랫폼에 필요한 라이브러리를 구축하고 구성합니다. 처음 실행하는 데 시간이 걸릴 수 있지만 일단 라이브러리가 빌드되면 VCPKG가 바이너리 캐시에서 해당 라이브러리를 검색합니다.
MEGAchat 다양한 옵션으로 구성할 수 있으며 그 중 일부는 chatlib_options.cmake 파일에서 찾을 수 있습니다. 예제와 테스트를 관리하는 옵션은 CMakeLists.txt에 있습니다.
MEGAchat 이 구성되면 전체 프로젝트를 빌드하기만 하면 됩니다.
cmake --build build_dir
CHATlib
또는 megaclc
처럼 --target=<target>
지정하거나 명령을 그대로 두어 모든 태그를 빌드할 수 있습니다. 또한 -j <N>
또는 --parallel <N>
추가하여 동시성을 관리하고 빌드 속도를 높일 수 있습니다.
빌드가 완료되면 CMake 구성 명령에 지정된 build_dir
에서 바이너리를 사용할 수 있습니다.
코드 복잡성을 추상화하기 위해 MEGAchat 새로운 애플리케이션을 빠르게 생성할 수 있는 중간 계층을 제공합니다.
문서는 src/ MEGAchat api.h
에서 볼 수 있습니다.
MEGAchat 스레딩 모델은 자바스크립트 스레딩 모델과 유사합니다. 모든 것이 기본(GUI) 스레드에서 실행되고 차단이 허용되지 않으며 외부 이벤트(네트워크, 타이머 등, webrtc 이벤트 등)가 기본 스레드에서 콜백을 트리거합니다. 이것이 작동하려면 MEGAchat 이 애플리케이션의 이벤트 루프와 상호 작용할 수 있어야 합니다. 이는 일반적으로 GUI 애플리케이션의 경우 GUI 프레임워크의 이벤트/메시지 루프이거나 콘솔 애플리케이션의 경우 사용자 정의 메시지 루프입니다. 이 메시지 루프는 매우 플랫폼별로 다르므로 메시지 루프와 MEGAchat 간의 인터페이스를 구현하는 것은 애플리케이션 개발자의 책임입니다. 이는 실제보다 더 복잡하게 들릴 수 있습니다. 인터페이스는 두 부분으로 구성됩니다. 그 중 하나는 애플리케이션의 메시지 루프에 불투명한 void*
포인터를 게시하는 megaPostMessageToGui(void*)
함수의 구현입니다. 이 함수는 일반적으로 메인 스레드가 아닌 스레드에 의해 호출되지만 GUI 스레드 자체에 의해 호출될 수도 있습니다. 다른 부분은 이러한 유형의 메시지를 인식하고 동일한 포인터로 megaProcessMessage(void*)
를 호출하여 이번에는 메인(GUI) 스레드의 컨텍스트에서 이를 MEGAchat 에 다시 전달하는 애플리케이션의 메시지 루프에 있는 코드입니다. 이 모든 것은 /src/base/gcm.h
및 /src/base/gcm.hpp
에서 구현됩니다. 이 파일에는 자세한 문서가 포함되어 있습니다. Windows에서 이를 구현하는 예는 다음과 같습니다. megaPostMessageToGui(void*)
사용자 메시지 유형으로 PostMessage()
수행하고 메시지의 lParam 또는 wParam으로 void*
수행하며 이벤트 처리 switch
문에는 다음이 있습니다. 해당 메시지 유형에 대한 항목, 메시지의 lParam 또는 wParam을 캐스팅하고 이를 megaProcessMessage(void*)
에 전달하여 void*
포인터를 가져옵니다.
MEGAchat 자체 전용 스레드에서 실행되는 libuv를 사용하여 원시 I/O 이벤트에 대해 여러 소켓을 모니터링하고 타이머를 구현합니다. 또한 DNS 확인 및 SSL 소켓과 같은 libuv의 상위 수준 I/O 기능에 의존합니다. libuv 위에 '서비스'( /src/base/?services*.*
)라고 하는 얇은 계층이 libuv 및 GCM 위에 구현되어 타이머용 자바스크립트와 유사한 간단한 비동기 C++11 API를 갖습니다. ( src/base/timer.h
), DNS 확인 ( /src/base/services-dns.hpp
), http 클라이언트 ( /src/base/services-http.hpp
). 이 계층은 원래 일반 C 인터페이스( cservices*.cpp/h
파일)가 있는 하위 수준 구성 요소를 갖도록 설계되었으므로 다양한 컴파일러로 구축된 여러 DLL과 상위 수준 헤더 전용 C에서 서비스를 사용할 수 있습니다. 프런트엔드이고 공개 API를 포함하는 ++11 레이어 - 이는 .hpp 파일입니다.
MEGAchat (libcurl)의 모든 네트워크 라이브러리는 네트워크 작동 및 타이머에 libuv를 사용합니다(C 라이브러리는 libuv를 직접 사용하고 C++ 코드는 C++11 레이어, 즉 timers.hpp
사용합니다). SDK 사용자도 동일한 작업을 수행하는 것이 좋습니다. 예를 들어 전용 작업자 스레드가 소켓을 차단하고 GCM을 통해 GUI 스레드에 이벤트를 게시하는 것이 가능합니다.
사용 패턴은 다음과 같습니다. 특정 이벤트(소켓 I/O 이벤트, 타이머 등)에 대해 콜백을 등록하고 해당 이벤트가 발생하면 해당 콜백이 libuv 스레드 에 의해 호출됩니다. 이벤트가 콜백이 호출되는 라이브러리 외부, 특히 GUI로 전파될 수 있는 경우 특정 시점에서 이벤트 처리는 GCM 메커니즘을 사용하여 GUI 스레드로 마샬링되어야 합니다. 그러나 이벤트가 내부적이고 라이브러리 외부로 전파되지 않는 경우 libuv 스레드의 컨텍스트에서 직접 처리할 수 있습니다(단, 차단하지 않는 경우). 이는 GUI 스레드에 마샬링하는 데 따른 성능 비용을 절약하고 이벤트가 높은 빈도로 발생하는 경우 권장됩니다(예: 버퍼에 추가된 데이터만 필요한 수신 데이터 청크 이벤트). 전송이 완료되면 두 접근 방식의 장점을 결합하여 전송당 한 번씩 GUI 스레드에서 완료 이벤트를 마샬링할 수 있습니다.
MEGAchat 에는 색상, 로그 파일 회전, 다중 로그 채널(각각 개별 로그 수준)을 갖춘 파일 및 콘솔 로깅을 지원하는 고급 로깅 기능이 있습니다. 로그 수준은 컴파일 시간이 아닌 런타임(시작 시)에 구성됩니다(예: 로그 매크로를 비활성화하지 않음). 이를 통해 릴리스 기반 앱이 모든 채널에 대해 전체 디버그 로깅을 활성화할 수 있습니다. 로그 채널은 src/base/loggerChannelConfig.h에 정의되고 기본적으로 구성됩니다. 파일에는 자세한 문서가 포함되어 있습니다. 편의를 위해 각 채널에 대한 전용 로깅 매크로는 일반적으로 이를 사용하는 코드에 정의됩니다. 예를 보려면 karereCommon.h의 XXX_LOG_DEBUG/WARN/ERROR 매크로를 참조하세요. SDK 사용자는 필요한 경우 추가 로그 채널을 자유롭게 만들 수 있습니다. GUI 로그 채널이 이미 정의되어 있습니다. 로그 채널 구성은 런타임 시 KRLOG 환경 변수에 의해 재정의될 수 있습니다. 형식은 다음과 같습니다.
KRLOG=<chan name>=<log level>,<chan name2>=<log level2>...
로그 수준은 '해제', '오류', '경고', '정보', '자세한 정보', '디버그', 'debugv'입니다.
'all'이라는 특별한 채널 이름이 하나 있습니다. 이 채널의 로그 수준을 설정하면 모든 채널의 로그 수준이 설정됩니다. 예를 들어 다음과 같은 방법으로 하나(또는 몇 개)를 제외한 모든 채널을 쉽게 무음으로 설정할 수 있습니다.
KRLOG=all=warn,mychannel=debug,myotherchannel=info
동일한 채널을 여러 번 구성할 수 있으며 마지막 설정만 유효하므로 위의 트릭이 가능합니다.
MEGAchat 로그 파일을 생성할 위치를 파악하고 main()
이 입력되기 전에 가능한 한 빨리 로깅을 시작하기 위해 컴파일 타임에 애플리케이션에서 karere::getAppDir()
함수를 정의해야 합니다. MEGAchat 정적 라이브러리로 구축된 경우에는 문제가 되지 않습니다. 동적 lib의 경우 이 함수는 약한 심볼이어야만 MEGAchat 자체가 함수 구현 없이 컴파일이 가능하며, 앱 시작 시 MEGAchat 공유 라이브러리가 로드될 때 구현이 연결됩니다. 약한 기호는 실제로 컴파일러 간에 이식 가능하지 않으며 이것이 문제가 될 수 있습니다. 그러나 gcc와 clang 모두에서 지원됩니다. 약한 기호가 지원되지 않으면 karer는 정적 lib로 빌드되어야 합니다.
base/promise.h
의 Promise lib 및 /src/test-promise.cpp
의 예제 사용법/src/base/timers.hpp
의 setTimeout()
및 setInterval()
타이머 함수marshallCall()
함수는 작업자 스레드에서 GUI 스레드로 람다 호출을 마샬링합니다. 예를 들어 /src/webrtcAdapter.h
및 다양한 위치에서 사용 예를 볼 수 있습니다. 이 메커니즘은 GUI 스레드에서 실행되는 고급 코드에 직접적으로 필요하지 않습니다./src/chatClient.h;.cpp
의 전체 클라이언트 구조megaPostMessageToGui()
구현하는 방법, '서비스'를 시작하는 방법, MEGAchat 클라이언트를 인스턴스화하는 방법을 보여줍니다. 또한 main()
이 입력되기 전에 로그 파일을 생성하고 가능한 한 빨리 로깅을 시작하기 위해 MEGAchat 라이브러리에 필요한 약한 기호인 getAppDir()
메서드를 구현하는 방법을 보여줍니다.src/rtcModile/IRtcModule.h
및 관련 헤더의 비디오 모듈 공개 인터페이스megaPostMessageToGui()
로 참조되지만 서명이 extern "C" void(void*)
인 경우 어떤 이름이든 가질 수 있습니다. . 이 기능은 MEGAchat 의존하는 메시지 전달 메커니즘(Gui Call Marshaller 또는 GCM이라고 함)의 핵심입니다. 이 함수에 대한 포인터를 services_init()
에 전달해야 합니다.