From 5077e2d301c29a9365cf5a04bec4b2fbc9f505e0 Mon Sep 17 00:00:00 2001
From: Nicolas Werner <nicolas.werner@hotmail.de>
Date: Sun, 8 Nov 2020 00:52:56 +0100
Subject: [PATCH] Initial barebones meson support

---
 examples/meson.build             |  31 ++++++++
 meson.build                      | 121 +++++++++++++++++++++++++++++++
 meson_options.txt                |   2 +
 subprojects/Olm.wrap             |   6 ++
 subprojects/gtest.wrap           |  10 +++
 subprojects/nlohmann_json.wrap   |   8 ++
 subprojects/olm-wrap/meson.build |   6 ++
 subprojects/spdlog.wrap          |   9 +++
 tests/media_api.cpp              |   6 +-
 tests/meson.build                |  30 ++++++++
 tests/responses.cpp              |   6 +-
 tests/test_helpers.hpp           |  12 +++
 12 files changed, 242 insertions(+), 5 deletions(-)
 create mode 100644 examples/meson.build
 create mode 100644 meson.build
 create mode 100644 meson_options.txt
 create mode 100644 subprojects/Olm.wrap
 create mode 100644 subprojects/gtest.wrap
 create mode 100644 subprojects/nlohmann_json.wrap
 create mode 100644 subprojects/olm-wrap/meson.build
 create mode 100644 subprojects/spdlog.wrap
 create mode 100644 tests/meson.build

diff --git a/examples/meson.build b/examples/meson.build
new file mode 100644
index 000000000..23328d65f
--- /dev/null
+++ b/examples/meson.build
@@ -0,0 +1,31 @@
+spdlog_dep = dependency('spdlog', fallback: ['spdlog', 'spdlog_dep'])
+
+room_feed = executable('room_feed',
+    'room_feed.cpp',
+    dependencies: [matrix_client_dep],
+    include_directories : '../tests'
+    )
+
+if meson.get_compiler('cpp').has_header('filesystem')
+media_downloader = executable('media_downloader',
+    'media_downloader.cpp',
+    dependencies: [matrix_client_dep],
+    include_directories : '../tests'
+    )
+endif
+
+simple_bot = executable('simple_bot',
+    'simple_bot.cpp',
+    dependencies: [matrix_client_dep],
+    include_directories : '../tests'
+    )
+crypto_bot = executable('crypto_bot',
+    'crypto_bot.cpp',
+    dependencies: [matrix_client_dep, spdlog_dep],
+    include_directories : '../tests'
+    )
+online_backup_exporter = executable('online_backup_exporter',
+    'online_backup_exporter.cpp',
+    dependencies: [matrix_client_dep],
+    include_directories : '../tests'
+    )
diff --git a/meson.build b/meson.build
new file mode 100644
index 000000000..e9dc6de38
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,121 @@
+project(
+  'mtxclient',
+  'cpp',
+version : '0.3.1',
+meson_version : '>=0.55.0',
+license : 'MIT',
+default_options : 'cpp_std=c++17'
+)
+
+cmake = import('cmake')
+
+boost_dep = dependency('boost', version: '>=1.70', modules : ['iostreams', 'system', 'thread'])
+thread_dep = dependency('threads')
+openssl_dep = dependency('OpenSSL', version: '>=1.1')
+
+olm_dep = dependency('Olm', method: 'cmake', fallback: ['olm-wrap', 'olm_dep'])
+
+json_dep = dependency('nlohmann_json', version: '>=3.2.0')
+
+deps = [
+  boost_dep,
+  thread_dep,
+  olm_dep,
+  openssl_dep,
+  json_dep
+]
+
+inc = include_directories('include')
+src = [
+  'lib/http/client.cpp',
+  'lib/http/session.cpp',
+  'lib/crypto/client.cpp',
+  'lib/crypto/encoding.cpp',
+  'lib/crypto/types.cpp',
+  'lib/crypto/utils.cpp',
+  'lib/utils.cpp',
+  'lib/log.cpp',
+  'lib/structs/common.cpp',
+  'lib/structs/errors.cpp',
+  'lib/structs/events.cpp',
+  'lib/structs/identifiers.cpp',
+  'lib/structs/pushrules.cpp',
+  'lib/structs/requests.cpp',
+  'lib/structs/secret_storage.cpp',
+  'lib/structs/user_interactive.cpp',
+  'lib/structs/events/aliases.cpp',
+  'lib/structs/events/avatar.cpp',
+  'lib/structs/events/canonical_alias.cpp',
+  'lib/structs/events/common.cpp',
+  'lib/structs/events/collections.cpp',
+  'lib/structs/events/create.cpp',
+  'lib/structs/events/encrypted.cpp',
+  'lib/structs/events/encryption.cpp',
+  'lib/structs/events/guest_access.cpp',
+  'lib/structs/events/history_visibility.cpp',
+  'lib/structs/events/join_rules.cpp',
+  'lib/structs/events/member.cpp',
+  'lib/structs/events/name.cpp',
+  'lib/structs/events/pinned_events.cpp',
+  'lib/structs/events/power_levels.cpp',
+  'lib/structs/events/presence.cpp',
+  'lib/structs/events/reaction.cpp',
+  'lib/structs/events/redaction.cpp',
+  'lib/structs/events/tag.cpp',
+  'lib/structs/events/tombstone.cpp',
+  'lib/structs/events/topic.cpp',
+  'lib/structs/events/voip.cpp',
+  'lib/structs/events/nheko_extensions/hidden_events.cpp',
+  'lib/structs/events/messages/audio.cpp',
+  'lib/structs/events/messages/emote.cpp',
+  'lib/structs/events/messages/file.cpp',
+  'lib/structs/events/messages/image.cpp',
+  'lib/structs/events/messages/notice.cpp',
+  'lib/structs/events/messages/text.cpp',
+  'lib/structs/events/messages/video.cpp',
+  'lib/structs/responses/common.cpp',
+  'lib/structs/responses/create_room.cpp',
+  'lib/structs/responses/crypto.cpp',
+  'lib/structs/responses/empty.cpp',
+  'lib/structs/responses/groups.cpp',
+  'lib/structs/responses/login.cpp',
+  'lib/structs/responses/media.cpp',
+  'lib/structs/responses/messages.cpp',
+  'lib/structs/responses/notifications.cpp',
+  'lib/structs/responses/profile.cpp',
+  'lib/structs/responses/register.cpp',
+  'lib/structs/responses/sync.cpp',
+  'lib/structs/responses/turn_server.cpp',
+  'lib/structs/responses/version.cpp',
+  'lib/structs/responses/well-known.cpp'
+]
+
+matrix_client = shared_library('matrix_client',
+    src,
+    dependencies: deps,
+    include_directories : inc,
+    install : true)
+
+matrix_client_dep = declare_dependency(
+  link_with: matrix_client,
+  dependencies: deps,
+  include_directories: inc)
+
+conf = configuration_data()
+
+cmake.write_basic_package_version_file(
+  name: 'MatrixClient',
+  compatibility: 'AnyNewerVersion',
+  version: meson.project_version())
+cmake.configure_package_config_file(
+  name: 'MatrixClient',
+  input: 'cmake/MatrixClientConfig.cmake.in',
+  configuration: conf)
+
+if get_option('examples').enabled()
+  subdir('examples')
+endif
+
+if get_option('tests').enabled()
+  subdir('tests')
+endif
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 000000000..4b2df169f
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,2 @@
+option('examples', type : 'feature', value : 'enabled')
+option('tests', type : 'feature', value : 'enabled')
diff --git a/subprojects/Olm.wrap b/subprojects/Olm.wrap
new file mode 100644
index 000000000..db184479b
--- /dev/null
+++ b/subprojects/Olm.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+directory = Olm
+url = https://git.matrix.org/git/olm.git
+revision = 3.1.4
+buildsystem = cmake
+
diff --git a/subprojects/gtest.wrap b/subprojects/gtest.wrap
new file mode 100644
index 000000000..ca5d699ec
--- /dev/null
+++ b/subprojects/gtest.wrap
@@ -0,0 +1,10 @@
+[wrap-file]
+directory = googletest-release-1.10.0
+
+source_url = https://github.com/google/googletest/archive/release-1.10.0.zip
+source_filename = gtest-1.10.0.zip
+source_hash = 94c634d499558a76fa649edb13721dce6e98fb1e7018dfaeba3cd7a083945e91
+
+patch_url = https://wrapdb.mesonbuild.com/v1/projects/gtest/1.10.0/1/get_zip
+patch_filename = gtest-1.10.0-1-wrap.zip
+patch_hash = 04ff14e8880e4e465f6260221e9dfd56fea6bc7cce4c4aff0dc528e4a2c8f514
diff --git a/subprojects/nlohmann_json.wrap b/subprojects/nlohmann_json.wrap
new file mode 100644
index 000000000..abdd8685d
--- /dev/null
+++ b/subprojects/nlohmann_json.wrap
@@ -0,0 +1,8 @@
+[wrap-file]
+lead_directory_missing = true
+source_url = https://github.com/nlohmann/json/releases/download/v3.9.1/include.zip
+source_filename = nlohmann_json-3.9.1.zip
+source_hash = 6bea5877b1541d353bd77bdfbdb2696333ae5ed8f9e8cc22df657192218cad91
+
+[provide]
+nlohmann_json = nlohmann_json_multiple_headers
diff --git a/subprojects/olm-wrap/meson.build b/subprojects/olm-wrap/meson.build
new file mode 100644
index 000000000..f81c695bc
--- /dev/null
+++ b/subprojects/olm-wrap/meson.build
@@ -0,0 +1,6 @@
+project('olm-wrap', 'cpp', version: '3.1.4', meson_version: '>=0.55.0')
+
+cmake = import('cmake')
+
+olm_subproj = cmake.subproject('Olm')
+olm_dep = olm_subproj.dependency('olm')
diff --git a/subprojects/spdlog.wrap b/subprojects/spdlog.wrap
new file mode 100644
index 000000000..51e0ddbcf
--- /dev/null
+++ b/subprojects/spdlog.wrap
@@ -0,0 +1,9 @@
+[wrap-file]
+directory = spdlog-1.8.0
+source_url = https://github.com/gabime/spdlog/archive/v1.8.0.tar.gz
+source_filename = v1.8.0.tar.gz
+source_hash = 1e68e9b40cf63bb022a4b18cdc1c9d88eb5d97e4fd64fa981950a9cacf57a4bf
+patch_url = https://wrapdb.mesonbuild.com/v1/projects/spdlog/1.8.0/1/get_zip
+patch_filename = spdlog-1.8.0-1-wrap.zip
+patch_hash = f783da51f6bebc99624504ca16fc1265b92add514956db9aa669a287d85b5049
+
diff --git a/tests/media_api.cpp b/tests/media_api.cpp
index f63435ab9..3cf6957d5 100644
--- a/tests/media_api.cpp
+++ b/tests/media_api.cpp
@@ -81,7 +81,7 @@ TEST(MediaAPI, UploadAudio)
     bob->login("bob", "secret", [bob](const mtx::responses::Login &, RequestErr err) {
         ASSERT_FALSE(err);
 
-        const auto audio = read_file("./fixtures/sound.mp3");
+        const auto audio = read_file(fixture_prefix() + "/fixtures/sound.mp3");
 
         bob->upload(audio,
                     "audio/mp3",
@@ -112,7 +112,7 @@ TEST(MediaAPI, UploadImage)
     carl->login("carl", "secret", [carl](const mtx::responses::Login &, RequestErr err) {
         ASSERT_FALSE(err);
 
-        const auto img = read_file("./fixtures/test.jpeg");
+        const auto img = read_file(fixture_prefix() + "/fixtures/test.jpeg");
 
         carl->upload(img,
                      "image/jpeg",
@@ -157,7 +157,7 @@ TEST(MediaAPI, UploadSVG)
     carl->login("carl", "secret", [carl](const mtx::responses::Login &, RequestErr err) {
         ASSERT_FALSE(err);
 
-        const auto img = read_file("./fixtures/kiwi.svg");
+        const auto img = read_file(fixture_prefix() + "/fixtures/kiwi.svg");
 
         carl->upload(img,
                      "image/svg",
diff --git a/tests/meson.build b/tests/meson.build
new file mode 100644
index 000000000..608744579
--- /dev/null
+++ b/tests/meson.build
@@ -0,0 +1,30 @@
+gtest_dep = dependency('gtest', main : true, required : false)
+
+client_api = executable('client_api', 'client_api.cpp', dependencies: [matrix_client_dep, gtest_dep])
+media_api = executable('media_api', 'media_api.cpp', dependencies: [matrix_client_dep, gtest_dep])
+e2ee = executable('e2ee', 'e2ee.cpp', dependencies: [matrix_client_dep, gtest_dep])
+utils = executable('utils', 'utils.cpp', dependencies: [matrix_client_dep, gtest_dep])
+pushrules = executable('pushrules', 'pushrules.cpp', dependencies: [matrix_client_dep, gtest_dep])
+connection = executable('connection', 'connection.cpp', dependencies: [matrix_client_dep, gtest_dep])
+identifiers = executable('identifiers', 'identifiers.cpp', dependencies: [matrix_client_dep, gtest_dep])
+events = executable('events', 'events.cpp', dependencies: [matrix_client_dep, gtest_dep])
+messages = executable('messages', 'messages.cpp', dependencies: [matrix_client_dep, gtest_dep])
+responses = executable('responses', 'responses.cpp', dependencies: [matrix_client_dep, gtest_dep])
+requests = executable('requests', 'requests.cpp', dependencies: [matrix_client_dep, gtest_dep])
+errors = executable('errors', 'errors.cpp', dependencies: [matrix_client_dep, gtest_dep])
+crypto = executable('crypto', 'crypto.cpp', dependencies: [matrix_client_dep, gtest_dep])
+
+test('connection', connection, protocol: 'gtest', suite: 'network', is_parallel: false)
+test('client_api', client_api, protocol: 'gtest', suite: 'network', is_parallel: false, timeout: 300)
+test('media_api', media_api, protocol: 'gtest', suite: 'network', is_parallel: false,env: ['FIXTURE_PREFIX='+meson.current_source_dir()])
+test('e2ee', e2ee, protocol: 'gtest', suite: 'network', is_parallel: false)
+test('pushrules', pushrules, protocol: 'gtest', suite: 'network', is_parallel: false)
+
+test('crypto', crypto, protocol: 'gtest', suite: 'nonetwork')
+test('errors', errors, protocol: 'gtest', suite: 'nonetwork')
+test('requests', requests, protocol: 'gtest', suite: 'nonetwork')
+test('responses', responses, protocol: 'gtest', suite: 'nonetwork',env: ['FIXTURE_PREFIX='+meson.current_source_dir()])
+test('messages', messages, protocol: 'gtest', suite: 'nonetwork')
+test('events', events, protocol: 'gtest', suite: 'nonetwork')
+test('identifiers', identifiers, protocol: 'gtest', suite: 'nonetwork')
+test('utils', utils, protocol: 'gtest', suite: 'nonetwork')
diff --git a/tests/responses.cpp b/tests/responses.cpp
index 9fd1cb3ac..652ade730 100644
--- a/tests/responses.cpp
+++ b/tests/responses.cpp
@@ -7,6 +7,8 @@
 
 #include <mtx.hpp>
 
+#include "test_helpers.hpp"
+
 using json = nlohmann::json;
 
 using namespace mtx::responses;
@@ -323,7 +325,7 @@ TEST(Responses, InvitedRoom)
 
 TEST(Responses, Sync)
 {
-    std::ifstream file("./fixtures/responses/sync.json");
+    std::ifstream file(fixture_prefix() + "/fixtures/responses/sync.json");
 
     json data1;
     file >> data1;
@@ -361,7 +363,7 @@ TEST(Responses, Sync)
 
 TEST(Responses, SyncWithEncryption)
 {
-    std::ifstream file("./fixtures/responses/sync_with_crypto.json");
+    std::ifstream file(fixture_prefix() + "/fixtures/responses/sync_with_crypto.json");
 
     json data;
     file >> data;
diff --git a/tests/test_helpers.hpp b/tests/test_helpers.hpp
index b70721c62..1f9aeeee4 100644
--- a/tests/test_helpers.hpp
+++ b/tests/test_helpers.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "gtest/gtest.h"
+#include <cstdlib>
 #include <iostream>
 #include <limits>
 #include <random>
@@ -90,3 +91,14 @@ get_event_ids(const std::vector<Collection> &events)
 
     return ids;
 }
+
+inline std::string
+fixture_prefix()
+{
+    auto var = std::getenv("FIXTURE_PREFIX");
+
+    if (var)
+        return var;
+    else
+        return ".";
+}
-- 
GitLab