Untuk pengembangan dan kompilasi MEGAchat , kami terutama menggunakan CMake sebagai alat konfigurasi proyek lintas platform. Kami juga menggunakan VCPKG untuk mengelola dependensi yang diperlukan untuk membangun MEGAchat di sebagian besar platform: Windows, MacOS, dan Linux.
Untuk detail tentang alat pembuatan yang diperlukan untuk setiap sistem operasi, tinjau bab Alat pembuatan di repositori MEGA SDK.
Informasi lebih lanjut untuk kompilasi WebRTC Android di WebRTC untuk Android
MEGAchat memerlukan beberapa dependensi agar dapat berfungsi. Kebanyakan darinya diunduh secara otomatis dan dibuat menggunakan VCPKG selama tahap konfigurasi.
Untuk Linux, beberapa perpustakaan tambahan diperlukan dalam sistem agar VCPKG dapat membangun dependensi. Untuk distribusi berbasis Debian, Anda dapat menginstal perpustakaan yang diperlukan menggunakan perintah berikut:
sudo apt install python3-pkg-resources libglib2.0-dev libgtk-3-dev libasound2-dev libpulse-dev
Nama paket mungkin berbeda untuk distribusi Linux yang berbeda, tetapi paket tersebut harus berhasil dibangun dengan paket yang menyediakan pustaka yang sama.
Anda dapat melihat set lengkap dependensi di file vcpkg.json di root repositori.
MEGAchat juga memerlukan perpustakaan MEGA SDK. Nanti ada instruksi dalam dokumen ini tentang cara menggunakannya dengan MEGAchat . Proyek MEGA SDK secara otomatis dimuat oleh MEGAchat CMake, jadi Anda hanya perlu mengkloningnya di jalur yang diharapkan.
Hanya ada satu ketergantungan opsional tambahan yang harus dipasang di sistem: Qt Framework. Hal ini hanya diperlukan untuk membangun Aplikasi Contoh Qt tetapi tidak diperlukan untuk pengujian, contoh CLI, atau perpustakaan itu sendiri.
Pertama-tama, siapkan direktori pilihan Anda untuk bekerja dengan MEGAchat . Direktori mega
akan digunakan sebagai direktori ruang kerja pada contoh di dokumen ini.
mkdir mega
cd mega
Setelah menyiapkan direktori, kloning repositori MEGAchat untuk mendapatkan kode sumber MEGAchat .
git clone https://github.com/meganz/MEGAchat
Karena MEGAchat memerlukan MEGA SDK agar berfungsi, kloning MEGA SDK di jalur yang diharapkan.
git clone https://github.com/meganz/sdk MEGAchat/third-party/mega
Terakhir, clone repositori VCPKG di sebelah folder MEGAchat . Jika Anda sudah menggunakan VCPKG dan memiliki klon repositori lokal, Anda dapat melewati langkah ini dan menggunakan VCPKG yang ada di sistem Anda.
git clone https://github.com/microsoft/vcpkg
Petunjuk berikut adalah untuk mengonfigurasi proyek dari antarmuka baris perintah (CLI), tetapi cmake-gui atau editor atau IDE apa pun yang kompatibel dengan CMake harus sesuai jika parameter CMake yang sama dikonfigurasi.
MEGAchat dikonfigurasi seperti proyek CMake reguler lainnya. Satu-satunya parameter yang selalu diperlukan adalah direktori VCPKG untuk mengelola dependensi pihak ketiga. Ketergantungan MEGA SDK dibangun sebagai bagian dari build MEGAchat .
Untuk mengkonfigurasi MEGAchat , dari ruang kerja (direktori mega
), jalankan CMake:
cmake -DVCPKG_ROOT=vcpkg -DCMAKE_BUILD_TYPE=Debug -S MEGAchat -B build_dir
Catatan 1 : -DCMAKE_BUILD_TYPE=<Debug|Release>
mungkin tidak diperlukan untuk generator multikonfigurasi, seperti Visual Studio.
Catatan 2 Jika Qt Framework diinstal pada sistem Anda tetapi CMake gagal mendeteksinya, Anda dapat menambahkan -DCMAKE_PREFIX_PATH=</path/to/qt/install/dir>
sehingga CMake dapat menemukannya. Jika Qt tidak diinstal dan Anda memilih untuk tidak menginstalnya, Anda dapat menonaktifkan Aplikasi Contoh Qt dengan menyetel -DENABLE_CHATLIB_QTAPP=OFF
. Pustaka, contoh CLI, dan pengujian akan tetap dibuat.
Dalam perintah cmake di atas, jalur relatif telah digunakan untuk kesederhanaan. Jika Anda ingin mengubah lokasi VCPKG, MEGAchat atau direktori build, cukup berikan jalur relatif atau absolut yang valid untuk salah satu lokasi tersebut.
Selama konfigurasi proyek, VCPKG akan membangun dan mengkonfigurasi perpustakaan yang diperlukan untuk platform tersebut. Mungkin diperlukan waktu beberapa saat saat dijalankan pertama kali, namun setelah perpustakaan dibuat, VCPKG akan mengambilnya dari cache biner.
MEGAchat dapat dikonfigurasi dengan opsi berbeda, beberapa di antaranya dapat ditemukan di file chatlib_options.cmake. Opsi untuk mengelola contoh dan pengujian ada di CMakeLists.txt.
Setelah MEGAchat dikonfigurasi, cukup buat proyek lengkapnya:
cmake --build build_dir
Anda dapat menentukan --target=<target>
seperti CHATlib
atau megaclc
, atau biarkan perintah apa adanya untuk membuat semua taget. Selain itu, -j <N>
atau --parallel <N>
dapat ditambahkan untuk mengelola konkurensi dan mempercepat pembangunan.
Setelah pembangunan selesai, binari akan tersedia di build_dir
, yang ditentukan dalam perintah konfigurasi CMake.
Untuk mengabstraksi kompleksitas kode, MEGAchat menyediakan lapisan perantara yang memungkinkan pembuatan aplikasi baru dengan cepat.
Dokumentasi tersedia di src/ MEGAchat api.h
Model threading MEGAchat mirip dengan model threading javascript - semuanya berjalan di thread utama (GUI), pemblokiran tidak pernah diizinkan, dan kejadian eksternal (jaringan, pengatur waktu, dll., acara webrtc, dll) memicu panggilan balik di thread utama. Agar ini berfungsi, MEGAchat harus dapat berinteraksi dengan loop peristiwa aplikasi - ini biasanya merupakan loop peristiwa/pesan kerangka GUI dalam kasus aplikasi GUI, atau loop pesan khusus dalam kasus aplikasi konsol. Karena loop pesan ini sangat spesifik untuk platform, pengembang aplikasi bertanggung jawab untuk mengimplementasikan antarmuka antara loop pesan ini dan MEGAchat . Ini mungkin terdengar lebih rumit daripada kenyataannya - antarmuka terdiri dari dua bagian. Salah satu bagiannya adalah penerapan fungsi megaPostMessageToGui(void*)
, yang memposting penunjuk void*
buram ke loop pesan aplikasi. Fungsi ini biasanya dipanggil oleh thread selain thread utama, tetapi bisa juga dipanggil oleh thread GUI itu sendiri. Bagian lainnya adalah kode dalam loop pesan aplikasi yang mengenali jenis pesan ini dan meneruskannya kembali ke MEGAchat , dengan memanggil megaProcessMessage(void*)
dengan penunjuk yang sama - kali ini dalam konteks thread utama (GUI). Semua ini diterapkan di /src/base/gcm.h
dan /src/base/gcm.hpp
. File-file ini berisi dokumentasi terperinci. Contoh penerapan ini di Windows adalah: megaPostMessageToGui(void*)
akan melakukan PostMessage()
dengan jenis pesan pengguna, dan void*
sebagai lParam atau wParam pesan, dan dalam pernyataan switch
pemrosesan acara, akan ada entri untuk jenis pesan tersebut, mendapatkan penunjuk void*
dengan mentransmisikan lParam atau wParam pesan, dan meneruskannya ke megaProcessMessage(void*)
.
MEGAchat mengandalkan libuv, yang berjalan di thread khusus miliknya, untuk memantau beberapa soket untuk kejadian I/O mentah, dan untuk mengimplementasikan pengatur waktu. Ini juga bergantung pada fungsionalitas I/O tingkat tinggi dari libuv seperti resolusi DNS dan soket SSL. Lapisan tipis di atas libuv, disebut 'layanan' ( /src/base/?services*.*
) diimplementasikan di atas libuv dan GCM untuk memiliki API C++11 async yang sederhana dan mirip javascript untuk pengatur waktu ( src/base/timer.h
), resolusi DNS ( /src/base/services-dns.hpp
), klien http ( /src/base/services-http.hpp
). Lapisan ini awalnya dirancang untuk memiliki komponen tingkat rendah dengan antarmuka C biasa (file cservices*.cpp/h
), sehingga layanan dapat digunakan oleh beberapa DLL yang dibangun dengan kompiler berbeda, dan C khusus header tingkat tinggi. Lapisan ++11 yang merupakan frontend dan berisi API publik - ini adalah file .hpp.
Semua perpustakaan jaringan di MEGAchat (libcurl) menggunakan libuv untuk operasi jaringan dan pengatur waktu (perpustakaan C menggunakan libuv secara langsung, kode C++ menggunakan lapisan C++11, yaitu timers.hpp
). Sangat disarankan agar pengguna SDK juga melakukan hal yang sama, meskipun misalnya ada kemungkinan untuk memiliki thread pekerja khusus yang memblokir soket, dan memposting kejadian ke thread GUI melalui GCM.
Pola penggunaannya adalah sebagai berikut: panggilan balik didaftarkan untuk peristiwa tertentu (peristiwa I/O soket, pengatur waktu, dll), dan panggilan balik tersebut dipanggil oleh thread libuv ketika peristiwa tersebut terjadi. Jika peristiwa dapat menyebar ke luar perpustakaan yang panggilan baliknya dipanggil, dan khususnya ke GUI, maka, pada titik tertentu, pemrosesan peristiwa harus diarahkan ke thread GUI, menggunakan mekanisme GCM. Namun, jika kejadian tersebut bersifat internal dan tidak pernah menyebar ke luar perpustakaan, maka kejadian tersebut dapat ditangani secara langsung dalam konteks thread libuv (asalkan tidak pernah memblokirnya). Hal ini menghemat biaya kinerja penyusunannya ke thread GUI, dan direkomendasikan jika peristiwa terjadi pada frekuensi tinggi, misalnya peristiwa potongan data masuk yang hanya memerlukan data yang ditambahkan ke buffer. Ketika transfer selesai, peristiwa penyelesaian dapat disusun di thread GUI satu kali per transfer, sehingga menggabungkan keunggulan kedua pendekatan.
MEGAchat memiliki fasilitas logging canggih yang mendukung logging file dan konsol dengan warna, rotasi file log, beberapa saluran log, masing-masing dengan level log individual. Level log dikonfigurasikan saat runtime (saat startup), dan bukan pada waktu kompilasi (yaitu bukan dengan menonaktifkan makro log). Hal ini memungkinkan aplikasi yang dibuat untuk rilis mengaktifkan logging debug penuh untuk saluran apa pun. Saluran log ditentukan dan dikonfigurasi secara default di src/base/loggerChannelConfig.h. File tersebut berisi dokumentasi terperinci. Untuk kenyamanan, makro logging khusus untuk setiap saluran biasanya ditentukan dalam kode yang menggunakannya - lihat makro XXX_LOG_DEBUG/WARN/ERROR di karereCommon.h sebagai contoh. Pengguna SDK bebas membuat saluran log tambahan jika diperlukan. Saluran log GUI sudah ditentukan. Konfigurasi saluran log dapat diganti saat runtime oleh variabel lingkungan KRLOG. Formatnya adalah sebagai berikut:
KRLOG=<chan name>=<log level>,<chan name2>=<log level2>...
Level log adalah 'tidak aktif', 'kesalahan', 'peringatkan', 'info', 'verbose', 'debug', 'debugv'.
Ada satu nama saluran khusus - 'semua'. Menyetel level log saluran ini akan menyetel level log semua saluran. Hal ini memungkinkan misalnya untuk membungkam semua saluran dengan mudah kecuali satu (atau beberapa), dengan:
KRLOG=all=warn,mychannel=debug,myotherchannel=info
Saluran yang sama dapat dikonfigurasi beberapa kali, dan hanya pengaturan terakhir yang akan efektif, sehingga trik di atas dapat dilakukan.
MEGAchat memerlukan fungsi karere::getAppDir()
untuk didefinisikan oleh aplikasi pada waktu kompilasi, untuk mengetahui di mana membuat file log dan mulai mencatat sedini mungkin, sebelum main()
dimasukkan. Jika MEGAchat dibuat sebagai lib statis, ini tidak menjadi masalah. Dalam kasus lib dinamis, fungsi ini harus berupa simbol yang lemah, sehingga MEGAchat sendiri dapat dikompilasi tanpa implementasi fungsi, dan implementasi harus ditautkan ketika lib bersama MEGAchat dimuat saat startup aplikasi. Simbol yang lemah tidak mudah dibawa-bawa di seluruh kompiler, dan ini mungkin menjadi masalah. Namun mereka didukung oleh gcc dan clang. Jika tidak ada simbol lemah yang didukung, karer harus dibuat sebagai lib statis.
base/promise.h
dan contoh penggunaan misalnya di /src/test-promise.cpp
setTimeout()
dan setInterval()
di /src/base/timers.hpp
marshallCall()
mengatur panggilan lambda dari thread pekerja ke thread GUI. Contoh penggunaannya bisa dilihat misalnya di /src/webrtcAdapter.h
dan di banyak tempat berbeda. Mekanisme ini tidak secara langsung diperlukan dalam kode tingkat tinggi yang berjalan di thread GUI./src/chatClient.h;.cpp
megaPostMessageToGui()
, cara memulai 'layanan', dan cara membuat instance klien MEGAchat . Juga menunjukkan cara mengimplementasikan metode getAppDir()
, yang merupakan simbol lemah yang diperlukan oleh perpustakaan MEGAchat untuk membuat file log dan memulai pencatatan sedini mungkin, sebelum main()
dimasukkan.src/rtcModile/IRtcModule.h
dan header terkaitmegaPostMessageToGui()
, tetapi dapat memiliki nama apa pun, asalkan tanda tangannya adalah extern "C" void(void*)
. Fungsi ini adalah inti dari mekanisme penyampaian pesan (disebut Gui Call Marshaller, atau GCM) yang diandalkan oleh MEGAchat . Anda harus meneruskan pointer ke fungsi ini ke services_init()
.