diff --git a/.CI/CreateDMG.sh b/.CI/CreateDMG.sh
index 2dae79d38..3eb2202c4 100755
--- a/.CI/CreateDMG.sh
+++ b/.CI/CreateDMG.sh
@@ -1,5 +1,10 @@
#!/bin/sh
+if [ -d bin/chatterino.app ] && [ ! -d chatterino.app ]; then
+ >&2 echo "Moving bin/chatterino.app down one directory"
+ mv bin/chatterino.app chatterino.app
+fi
+
echo "Running MACDEPLOYQT"
$Qt5_DIR/bin/macdeployqt chatterino.app
echo "Creating python3 virtual environment"
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index a2013c08c..b10d39116 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -14,9 +14,30 @@ jobs:
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
qt-version: [5.15.2, 5.12.10]
+ build-system: [qmake, cmake]
+ exclude:
+ - os: windows-latest
+ qt-version: 5.12.10
+ build-system: cmake
+ include:
+ - os: windows-2016
+ qt-version: 5.12.10
+ build-system: cmake
fail-fast: false
steps:
+ - name: Set environment variables for windows-latest
+ if: matrix.os == 'windows-latest'
+ run: |
+ echo "vs_version=2019" >> $GITHUB_ENV
+ shell: bash
+
+ - name: Set environment variables for windows-2016
+ if: matrix.os == 'windows-2016'
+ run: |
+ echo "vs_version=2017" >> $GITHUB_ENV
+ shell: bash
+
- uses: actions/checkout@v2.3.4
with:
submodules: true
@@ -42,18 +63,12 @@ jobs:
version: ${{ matrix.qt-version }}
# WINDOWS
- - name: Cache conan
- if: startsWith(matrix.os, 'windows')
- uses: actions/cache@v2.1.4
- with:
- key: ${{ runner.os }}-conan-root-${{ hashFiles('**/conanfile.txt') }}
- path: ~/.conan
- name: Cache conan packages
if: startsWith(matrix.os, 'windows')
uses: actions/cache@v2.1.4
with:
- key: ${{ runner.os }}-conan-pkg-${{ hashFiles('**/conanfile.txt') }}
+ key: ${{ runner.os }}-conan-${{ hashFiles('**/conanfile.txt') }}-20210307
path: C:/.conan/
- name: Install dependencies (Windows)
@@ -65,9 +80,9 @@ jobs:
shell: cmd
- name: Build (Windows)
- if: startsWith(matrix.os, 'windows')
+ if: startsWith(matrix.os, 'windows') && matrix.build-system == 'qmake'
run: |
- call "%programfiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
+ call "%programfiles(x86)%\Microsoft Visual Studio\%vs_version%\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
mkdir build
cd build
"C:\Program Files\Conan\conan\conan.exe" install ..
@@ -80,17 +95,33 @@ jobs:
7z a chatterino-windows-x86-64.zip Chatterino2/
shell: cmd
+ - name: Build with CMake (Windows)
+ if: startsWith(matrix.os, 'windows') && matrix.build-system == 'cmake'
+ run: |
+ call "%programfiles(x86)%\Microsoft Visual Studio\%vs_version%\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
+ mkdir build
+ cd build
+ "C:\Program Files\Conan\conan\conan.exe" install ..
+ cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DUSE_CONAN=ON ..
+ set cl=/MP
+ nmake /S /NOLOGO
+ windeployqt bin/chatterino.exe --release --no-compiler-runtime --no-translations --no-opengl-sw --dir Chatterino2/
+ cp bin/chatterino.exe Chatterino2/
+ echo nightly > Chatterino2/modes
+ 7z a chatterino-windows-x86-64.zip Chatterino2/
+ shell: cmd
+
- name: Ensure build succeeded (Windows)
if: startsWith(matrix.os, 'windows')
run: |
cd build
- ls release/chatterino.exe
+ ls Chatterino2/chatterino.exe
- name: Upload artifact (Windows)
if: startsWith(matrix.os, 'windows')
uses: actions/upload-artifact@v2.2.2
with:
- name: chatterino-windows-x86-64-${{ matrix.qt-version }}.zip
+ name: chatterino-windows-x86-64-${{ matrix.qt-version }}-${{ matrix.build-system }}.zip
path: build/chatterino-windows-x86-64.zip
# LINUX
@@ -99,6 +130,9 @@ jobs:
run: |
sudo apt-get update
sudo apt-get -y install \
+ cmake \
+ virtualenv \
+ rapidjson-dev \
libssl-dev \
libboost-dev \
libxcb-randr0-dev \
@@ -116,7 +150,7 @@ jobs:
libxcb-xinerama0
- name: Build (Ubuntu)
- if: startsWith(matrix.os, 'ubuntu')
+ if: startsWith(matrix.os, 'ubuntu') && matrix.build-system == 'qmake'
run: |
mkdir build
cd build
@@ -124,6 +158,15 @@ jobs:
make -j8
shell: bash
+ - name: Build with CMake (Ubuntu)
+ if: startsWith(matrix.os, 'ubuntu') && matrix.build-system == 'cmake'
+ run: |
+ mkdir build
+ cd build
+ cmake -DCMAKE_INSTALL_PREFIX=appdir/usr/ -DCMAKE_BUILD_TYPE=Release -DPAJLADA_SETTINGS_USE_BOOST_FILESYSTEM=On ..
+ make -j8
+ shell: bash
+
- name: Package (Ubuntu)
if: startsWith(matrix.os, 'ubuntu')
run: |
@@ -135,18 +178,18 @@ jobs:
if: startsWith(matrix.os, 'ubuntu')
uses: actions/upload-artifact@v2.2.2
with:
- name: Chatterino-x86_64-${{ matrix.qt-version }}.AppImage
+ name: Chatterino-x86_64-${{ matrix.qt-version }}-${{ matrix.build-system }}.AppImage
path: build/Chatterino-x86_64.AppImage
# MACOS
- name: Install dependencies (MacOS)
if: startsWith(matrix.os, 'macos')
run: |
- brew install boost openssl rapidjson p7zip create-dmg
+ brew install boost openssl rapidjson p7zip create-dmg cmake tree
shell: bash
- name: Build (MacOS)
- if: startsWith(matrix.os, 'macos')
+ if: startsWith(matrix.os, 'macos') && matrix.build-system == 'qmake'
run: |
mkdir build
cd build
@@ -154,6 +197,18 @@ jobs:
make -j8
shell: bash
+ - name: Build with CMake (MacOS)
+ if: startsWith(matrix.os, 'macos') && matrix.build-system == 'cmake'
+ run: |
+ mkdir build
+ cd build
+ cmake \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl \
+ ..
+ make -j8
+ shell: bash
+
- name: Package (MacOS)
if: startsWith(matrix.os, 'macos')
run: |
@@ -168,7 +223,7 @@ jobs:
if: startsWith(matrix.os, 'macos')
uses: actions/upload-artifact@v2.2.2
with:
- name: chatterino-osx-${{ matrix.qt-version }}.dmg
+ name: chatterino-osx-${{ matrix.qt-version }}-${{ matrix.build-system }}.dmg
path: build/chatterino-osx.dmg
create-release:
@@ -192,19 +247,34 @@ jobs:
- uses: actions/download-artifact@v2.0.8
with:
- name: chatterino-windows-x86-64-5.15.2.zip
+ name: chatterino-windows-x86-64-5.15.2-qmake.zip
path: windows/
- uses: actions/download-artifact@v2.0.8
with:
- name: Chatterino-x86_64-5.15.2.AppImage
+ name: chatterino-windows-x86-64-5.15.2-cmake.zip
+ path: windows-cmake/
+
+ - uses: actions/download-artifact@v2.0.8
+ with:
+ name: Chatterino-x86_64-5.15.2-qmake.AppImage
path: linux/
- uses: actions/download-artifact@v2.0.8
with:
- name: chatterino-osx-5.15.2.dmg
+ name: Chatterino-x86_64-5.15.2-cmake.AppImage
+ path: linux-cmake/
+
+ - uses: actions/download-artifact@v2.0.8
+ with:
+ name: chatterino-osx-5.15.2-qmake.dmg
path: macos/
+ - uses: actions/download-artifact@v2.0.8
+ with:
+ name: chatterino-osx-5.15.2-cmake.dmg
+ path: macos-cmake/
+
# TODO: Extract dmg and appimage
# - name: Read upload URL into output
@@ -222,6 +292,16 @@ jobs:
asset_name: chatterino-windows-x86-64.zip
asset_content_type: application/zip
+ - name: Upload release asset (Windows) CMake
+ uses: actions/upload-release-asset@v1.0.2
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
+ asset_path: ./windows-cmake/chatterino-windows-x86-64.zip
+ asset_name: test-cmake-chatterino-windows-x86-64.zip
+ asset_content_type: application/zip
+
- name: Upload release asset (Ubuntu)
uses: actions/upload-release-asset@v1.0.2
env:
@@ -232,6 +312,16 @@ jobs:
asset_name: Chatterino-x86_64.AppImage
asset_content_type: application/x-executable
+ - name: Upload release asset (Ubuntu) CMake
+ uses: actions/upload-release-asset@v1.0.2
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
+ asset_path: ./linux-cmake/Chatterino-x86_64.AppImage
+ asset_name: test-cmake-Chatterino-x86_64.AppImage
+ asset_content_type: application/x-executable
+
- name: Upload release asset (MacOS)
uses: actions/upload-release-asset@v1.0.2
env:
@@ -241,3 +331,13 @@ jobs:
asset_path: ./macos/chatterino-osx.dmg
asset_name: chatterino-osx.dmg
asset_content_type: application/x-bzip2
+
+ - name: Upload release asset (MacOS) CMake
+ uses: actions/upload-release-asset@v1.0.2
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
+ asset_path: ./macos-cmake/chatterino-osx.dmg
+ asset_name: test-cmake-chatterino-osx.dmg
+ asset_content_type: application/x-bzip2
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 684fc4d04..6cb64b2c3 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -69,7 +69,7 @@ jobs:
- name: Build (Ubuntu)
if: startsWith(matrix.os, 'ubuntu')
run: |
- cmake -DBUILD_TESTS=On -DCMAKE_BUILD_TYPE=Release ..
+ cmake -DBUILD_TESTS=On -DBUILD_APP=OFF ..
cmake --build . --config Release
working-directory: build-test
shell: bash
@@ -77,6 +77,6 @@ jobs:
- name: Test (Ubuntu)
if: startsWith(matrix.os, 'ubuntu')
run: |
- ./chatterino-test --platform minimal
+ ./bin/chatterino-test --platform minimal
working-directory: build-test
shell: bash
diff --git a/.gitignore b/.gitignore
index e7cec67bb..09640e816 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,7 +26,8 @@ qrc_*.cpp
ui_*.h
Makefile*
*build-*/
-/build/
+[bB]uild
+/_build/
# QtCreator
@@ -78,3 +79,27 @@ Thumbs.db
# Other editors/IDEs
.vscode
+.idea
+dependencies
+
+### CMake ###
+CMakeLists.txt.user
+CMakeCache.txt
+CMakeFiles
+CMakeScripts
+Testing
+Makefile
+cmake_install.cmake
+install_manifest.txt
+compile_commands.json
+CTestTestfile.cmake
+_deps
+CMakeUserPresets.json
+
+### CMake Patch ###
+# External projects
+*-prefix/
+Stamp
+tmp
+Source
+Dependencies_*
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
index f02f148b2..1467b973c 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,6 @@
[submodule "lib/libcommuni"]
path = lib/libcommuni
- url = https://github.com/communi/libcommuni
+ url = https://github.com/Chatterino/libcommuni
[submodule "lib/qBreakpad"]
path = lib/qBreakpad
url = https://github.com/jiakuan/qBreakpad.git
diff --git a/BUILDING_ON_LINUX.md b/BUILDING_ON_LINUX.md
index 6c2e4cde6..878d15a11 100644
--- a/BUILDING_ON_LINUX.md
+++ b/BUILDING_ON_LINUX.md
@@ -6,29 +6,45 @@ Note on Qt version compatibility: If you are installing Qt from a package manage
_most likely works the same for other Debian-like distros_
-1. Install dependencies (and the C++ IDE Qt Creator) `sudo apt install qtcreator qtmultimedia5-dev libqt5svg5-dev libboost-dev libssl-dev libboost-system-dev libboost-filesystem-dev`
+1. Install dependencies (and the C++ IDE Qt Creator) `sudo apt install qtcreator qtmultimedia5-dev libqt5svg5-dev libboost-dev libssl-dev libboost-system-dev libboost-filesystem-dev cmake`
1. Open `chatterino.pro` with QT Creator and build
## Arch Linux
-install [chatterino2-git](https://aur.archlinux.org/packages/chatterino2-git/) from the aur or build manually as follows:
+### Through AUR
-1. `sudo pacman -S qt5-base qt5-multimedia qt5-svg gst-plugins-ugly gst-plugins-good boost rapidjson pkgconf openssl`
+- [chatterino2-git](https://aur.archlinux.org/packages/chatterino2-git/)
+
+### Manually
+
+1. `sudo pacman -S qt5-base qt5-multimedia qt5-svg gst-plugins-ugly gst-plugins-good boost rapidjson pkgconf openssl cmake`
1. go into project directory
1. create build folder `mkdir build && cd build`
+
+### Using QMake
+
1. `qmake .. && make`
+### Using CMake
+
+1. `cmake .. && make`
+
## Fedora 28 and above
_most likely works the same for other Red Hat-like distros. Substitue `dnf` with `yum`._
-### Development dependencies
-
-1. `sudo dnf install qt5-qtbase-devel qt5-qtmultimedia-devel qt5-qtsvg-devel libsecret-devel openssl-devel boost-devel`
+1. `sudo dnf install qt5-qtbase-devel qt5-qtmultimedia-devel qt5-qtsvg-devel libsecret-devel openssl-devel boost-devel cmake`
1. go into project directory
1. create build folder `mkdir build && cd build`
+
+### Using QMake
+
1. `qmake-qt5 .. && make -j$(nproc)`
+### Using CMake
+
+1. `cmake .. && make -j$(nproc)`
+
### Optional dependencies
_`gstreamer-plugins-good` package is retired in Fedora 31, see: [rhbz#1735324](https://bugzilla.redhat.com/show_bug.cgi?id=1735324)_
@@ -37,7 +53,14 @@ _`gstreamer-plugins-good` package is retired in Fedora 31, see: [rhbz#1735324](h
## NixOS 18.09+
-1. enter the development environment with all of the dependencies: `nix-shell -p openssl boost qt5.full pkg-config`
+1. enter the development environment with all of the dependencies: `nix-shell -p openssl boost qt5.full pkg-config cmake`
1. go into project directory
1. create build folder `mkdir build && cd build`
+
+### Using QMake
+
1. `qmake .. && make`
+
+### Using CMake
+
+1. `cmake .. && make`
diff --git a/BUILDING_ON_MAC.md b/BUILDING_ON_MAC.md
index 4101d3910..3a6bcb37d 100644
--- a/BUILDING_ON_MAC.md
+++ b/BUILDING_ON_MAC.md
@@ -14,6 +14,8 @@
8. Create build folder `mkdir build && cd build`
9. `qmake .. && make`
+_If you want to use cmake instead of qmake, just replace the above qmake command with cmake_
+
If the Project does not build at this point, you might need to add additional Paths/Libs, because brew does not install openssl and boost in the common path. You can get their path using
`brew info openssl`
diff --git a/BUILDING_ON_WINDOWS.md b/BUILDING_ON_WINDOWS.md
index 06e836407..16c890211 100644
--- a/BUILDING_ON_WINDOWS.md
+++ b/BUILDING_ON_WINDOWS.md
@@ -123,3 +123,12 @@ To produce all supplement files for a standalone build, follow these steps (adju
6. The `releases` directory will now be populated with all the required files to make the chatterino build standalone.
You can now create a zip archive of all the contents in `releases` and distribute the program as is, without requiring any development tools to be present on the target system. (However, the vcredist package must be present, as usual - see the [README](README.md)).
+
+## Building with CMake
+
+Open up your terminal with the Visual Studio environment variables, then:
+
+1. `mkdir build`
+2. `cd build`
+3. `cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DUSE_CONAN=ON ..`
+4. `nmake`
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cb07d3c53..c0e79ed88 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,84 +1,120 @@
cmake_minimum_required(VERSION 3.8)
+cmake_policy(SET CMP0087 NEW)
+include(FeatureSummary)
-project(chatterino)
-
-include_directories(src)
-
-set(chatterino_SOURCES
- src/common/NetworkRequest.cpp
- src/common/NetworkResult.cpp
- src/common/NetworkPrivate.cpp
- src/common/NetworkManager.cpp
- src/common/QLogging.cpp
- src/common/Modes.cpp
- src/common/ChatterinoSetting.cpp
-
- src/util/DebugCount.cpp
-
- src/singletons/Paths.cpp
-
- src/BaseSettings.cpp
-
- src/common/UsernameSet.cpp
- src/controllers/highlights/HighlightPhrase.cpp
-
-
- src/providers/emoji/Emojis.cpp
-
- src/messages/Emote.cpp
- src/messages/Image.cpp
- src/messages/ImageSet.cpp
- src/util/RapidjsonHelpers.cpp
-
- ${CMAKE_CURRENT_LIST_DIR}/resources/resources.qrc
- ${CMAKE_CURRENT_LIST_DIR}/resources/resources_autogenerated.qrc
+list(APPEND CMAKE_MODULE_PATH
+ "${CMAKE_SOURCE_DIR}/cmake"
)
-find_package(Qt5 5.9.0 REQUIRED COMPONENTS
- Core Widgets Network Concurrent
+project(chatterino VERSION 2.2.3)
+
+option(BUILD_APP "Build Chatterino" ON)
+option(BUILD_TESTS "Build the tests for Chatterino" OFF)
+option(USE_SYSTEM_PAJLADA_SETTINGS "Use system pajlada settings library" OFF)
+option(USE_SYSTEM_LIBCOMMUNI "Use system communi library" OFF)
+option(USE_SYSTEM_QT5KEYCHAIN "Use system Qt5Keychain library" OFF)
+
+option(USE_CONAN "Use conan" OFF)
+
+if (USE_CONAN OR CONAN_EXPORTED)
+ include(${CMAKE_CURRENT_BINARY_DIR}/conanbuildinfo.cmake)
+ conan_basic_setup(TARGETS NO_OUTPUT_DIRS)
+endif()
+
+find_program(CCACHE_PROGRAM ccache)
+if (CCACHE_PROGRAM)
+ set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}")
+ message("Using ${CCACHE_PROGRAM} for speeding up build")
+endif ()
+
+include(${CMAKE_CURRENT_LIST_DIR}/cmake/GIT.cmake)
+
+find_package(Qt5 REQUIRED
+ COMPONENTS
+ Core
+ Widgets
+ Gui
+ Network
+ Multimedia
+ Svg
+ Concurrent
)
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
+if (WIN32)
+ find_package(WinToast REQUIRED)
+endif ()
+
+# Find boost on the system
+find_package(Boost REQUIRED)
+
+# Find OpenSSL on the system
+find_package(OpenSSL REQUIRED)
+
+find_package(Threads REQUIRED)
+
+find_library(LIBRT rt)
+
+if (BUILD_APP)
+ if (USE_SYSTEM_LIBCOMMUNI)
+ find_package(LibCommuni REQUIRED)
+ else()
+ set(LIBCOMMUNI_ROOT_LIB_FOLDER "${CMAKE_SOURCE_DIR}/lib/libcommuni")
+ if (NOT EXISTS "${LIBCOMMUNI_ROOT_LIB_FOLDER}/CMakeLists.txt")
+ message(FATAL_ERROR "Submodules probably not loaded, unable to find lib/libcommuni/CMakeLists.txt")
+ endif()
+
+ add_subdirectory("${LIBCOMMUNI_ROOT_LIB_FOLDER}" EXCLUDE_FROM_ALL)
+ endif()
+
+ # Link QtKeychain statically
+ option(QTKEYCHAIN_STATIC "" ON)
+
+ if (USE_SYSTEM_QT5KEYCHAIN)
+ find_package(Qt5Keychain REQUIRED)
+ else()
+ set(QT5KEYCHAIN_ROOT_LIB_FOLDER "${CMAKE_SOURCE_DIR}/lib/qtkeychain")
+ if (NOT EXISTS "${QT5KEYCHAIN_ROOT_LIB_FOLDER}/CMakeLists.txt")
+ message(FATAL_ERROR "Submodules probably not loaded, unable to find lib/qtkeychain/CMakeLists.txt")
+ endif()
+
+ add_subdirectory("${QT5KEYCHAIN_ROOT_LIB_FOLDER}" EXCLUDE_FROM_ALL)
+ if (NOT TARGET qt5keychain)
+ message(FATAL_ERROR "qt5keychain target was not created :@")
+ endif()
+ endif()
+
+ find_package(RapidJSON REQUIRED)
+
+ find_package(Websocketpp REQUIRED)
+endif ()
if (BUILD_TESTS)
- set(BUILD_TESTS OFF)
- message("++ Tests enabled")
- find_package(GTest)
- enable_testing()
+ find_package(GTest REQUIRED)
+endif ()
- add_executable(chatterino-test
- ${chatterino_SOURCES}
+find_package(PajladaSerialize REQUIRED)
+find_package(PajladaSignals REQUIRED)
+find_package(LRUCache REQUIRED)
- tests/src/main.cpp
- tests/src/Emojis.cpp
- tests/src/NetworkRequest.cpp
- tests/src/UsernameSet.cpp
- tests/src/HighlightPhrase.cpp
- )
-
- target_compile_definitions(chatterino-test PRIVATE CHATTERINO_GIT_HASH="test" AB_CUSTOM_SETTINGS CHATTERINO_TEST)
-
- target_link_libraries(chatterino-test Qt5::Core Qt5::Widgets Qt5::Network Qt5::Concurrent)
-
- target_link_libraries(chatterino-test gtest gtest_main)
-
- add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/lib/settings)
- target_link_libraries(chatterino-test PajladaSettings)
- target_include_directories(chatterino-test PUBLIC PajladaSettings)
-
- find_package(Threads)
-
- target_link_libraries(chatterino-test Threads::Threads)
-
- add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/lib/serialize PajladaSerialize)
-
- target_link_libraries(chatterino-test PajladaSerialize)
-
- set_property(TARGET chatterino-test PROPERTY CXX_STANDARD 17)
- set_property(TARGET chatterino-test PROPERTY CXX_STANDARD_REQUIRED ON)
-
- # gtest_discover_tests(chatterino-test)
+if (USE_SYSTEM_PAJLADA_SETTINGS)
+ find_package(PajladaSettings REQUIRED)
else()
- message(FATAL_ERROR "This cmake file is only intended for tests right now. Use qmake to build chatterino2")
+ if (NOT EXISTS "${CMAKE_SOURCE_DIR}/lib/settings/CMakeLists.txt")
+ message(FATAL_ERROR "Submodules probably not loaded, unable to find lib/settings/CMakeLists.txt")
+ endif()
+
+ add_subdirectory("${CMAKE_SOURCE_DIR}/lib/settings" EXCLUDE_FROM_ALL)
endif()
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+if (BUILD_APP)
+ add_subdirectory(src)
+endif ()
+if (BUILD_TESTS)
+ enable_testing()
+ add_subdirectory(tests)
+endif ()
+
+feature_summary(WHAT ALL)
diff --git a/cmake/FindLRUCache.cmake b/cmake/FindLRUCache.cmake
new file mode 100644
index 000000000..829054364
--- /dev/null
+++ b/cmake/FindLRUCache.cmake
@@ -0,0 +1,14 @@
+include(FindPackageHandleStandardArgs)
+
+find_path(LRUCache_INCLUDE_DIR lrucache/lrucache.hpp HINTS ${CMAKE_SOURCE_DIR}/lib/lrucache)
+
+find_package_handle_standard_args(LRUCache DEFAULT_MSG LRUCache_INCLUDE_DIR)
+
+if (LRUCache_FOUND)
+ add_library(LRUCache INTERFACE IMPORTED)
+ set_target_properties(LRUCache PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${LRUCache_INCLUDE_DIR}"
+ )
+endif ()
+
+mark_as_advanced(LRUCache_INCLUDE_DIR)
diff --git a/cmake/FindLibCommuni.cmake b/cmake/FindLibCommuni.cmake
new file mode 100644
index 000000000..7418c9ffb
--- /dev/null
+++ b/cmake/FindLibCommuni.cmake
@@ -0,0 +1,28 @@
+find_path(IrcCore_INCLUDE_DIR irc.h PATH_SUFFIXES IrcCore)
+find_library(IrcCore_LIBRARY Core)
+
+find_path(IrcModel_INCLUDE_DIR ircmodel.h PATH_SUFFIXES IrcModel)
+find_library(IrcModel_LIBRARY Model)
+
+find_path(IrcUtil_INCLUDE_DIR ircutil.h PATH_SUFFIXES IrcUtil)
+find_library(IrcUtil_LIBRARY Util)
+
+set(LibCommuni_INCLUDE_DIRS ${IrcCore_INCLUDE_DIR} ${IrcModel_INCLUDE_DIR} ${IrcUtil_INCLUDE_DIR})
+set(LibCommuni_LIBRARIES ${IrcCore_LIBRARY} ${IrcModel_LIBRARY} ${IrcUtil_LIBRARY})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LibCommuni
+ DEFAULT_MSG IrcCore_LIBRARY IrcModel_LIBRARY IrcUtil_LIBRARY IrcCore_INCLUDE_DIR IrcModel_INCLUDE_DIR IrcUtil_INCLUDE_DIR
+ )
+
+if (LibCommuni_FOUND)
+ add_library(LibCommuni::LibCommuni INTERFACE IMPORTED)
+ set_target_properties(LibCommuni::LibCommuni PROPERTIES
+ INTERFACE_LINK_LIBRARIES "${LibCommuni_LIBRARIES}"
+ INTERFACE_INCLUDE_DIRECTORIES "${LibCommuni_INCLUDE_DIRS}"
+ )
+endif ()
+
+mark_as_advanced(LibCommuni_INCLUDE_DIRS LibCommuni_LIBRARIES
+ IrcCore_LIBRARY IrcModel_LIBRARY IrcUtil_LIBRARY
+ IrcCore_INCLUDE_DIR IrcModel_INCLUDE_DIR IrcUtil_INCLUDE_DIR)
diff --git a/cmake/FindPajladaSerialize.cmake b/cmake/FindPajladaSerialize.cmake
new file mode 100644
index 000000000..4671874ce
--- /dev/null
+++ b/cmake/FindPajladaSerialize.cmake
@@ -0,0 +1,14 @@
+include(FindPackageHandleStandardArgs)
+
+find_path(PajladaSerialize_INCLUDE_DIR pajlada/serialize.hpp HINTS ${CMAKE_SOURCE_DIR}/lib/serialize/include)
+
+find_package_handle_standard_args(PajladaSerialize DEFAULT_MSG PajladaSerialize_INCLUDE_DIR)
+
+if (PajladaSerialize_FOUND)
+ add_library(Pajlada::Serialize INTERFACE IMPORTED)
+ set_target_properties(Pajlada::Serialize PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${PajladaSerialize_INCLUDE_DIR}"
+ )
+endif ()
+
+mark_as_advanced(PajladaSerialize_INCLUDE_DIR)
diff --git a/cmake/FindPajladaSettings.cmake b/cmake/FindPajladaSettings.cmake
new file mode 100644
index 000000000..d0d256bbb
--- /dev/null
+++ b/cmake/FindPajladaSettings.cmake
@@ -0,0 +1,16 @@
+include(FindPackageHandleStandardArgs)
+
+find_path(PajladaSettings_INCLUDE_DIR pajlada/settings.hpp)
+find_library(PajladaSettings_LIBRARY PajladaSettings)
+
+find_package_handle_standard_args(PajladaSettings DEFAULT_MSG PajladaSettings_INCLUDE_DIR PajladaSettings_LIBRARY)
+
+if (PajladaSettings_FOUND)
+ add_library(Pajlada::Settings INTERFACE IMPORTED)
+ set_target_properties(Pajlada::Settings PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${PajladaSettings_INCLUDE_DIR}"
+ INTERFACE_LINK_LIBRARIES "${PajladaSettings_LIBRARY}"
+ )
+endif ()
+
+mark_as_advanced(PajladaSettings_INCLUDE_DIR PajladaSettings_LIBRARY)
diff --git a/cmake/FindPajladaSignals.cmake b/cmake/FindPajladaSignals.cmake
new file mode 100644
index 000000000..f4c964ecb
--- /dev/null
+++ b/cmake/FindPajladaSignals.cmake
@@ -0,0 +1,14 @@
+include(FindPackageHandleStandardArgs)
+
+find_path(PajladaSignals_INCLUDE_DIR pajlada/signals/signal.hpp HINTS ${CMAKE_SOURCE_DIR}/lib/signals/include)
+
+find_package_handle_standard_args(PajladaSignals DEFAULT_MSG PajladaSignals_INCLUDE_DIR)
+
+if (PajladaSignals_FOUND)
+ add_library(Pajlada::Signals INTERFACE IMPORTED)
+ set_target_properties(Pajlada::Signals PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${PajladaSignals_INCLUDE_DIR}"
+ )
+endif ()
+
+mark_as_advanced(PajladaSignals_INCLUDE_DIR)
diff --git a/cmake/FindRapidJSON.cmake b/cmake/FindRapidJSON.cmake
new file mode 100644
index 000000000..9c58df19e
--- /dev/null
+++ b/cmake/FindRapidJSON.cmake
@@ -0,0 +1,14 @@
+include(FindPackageHandleStandardArgs)
+
+find_path(RapidJSON_INCLUDE_DIRS rapidjson/rapidjson.h HINTS ${CMAKE_SOURCE_DIR}/lib/rapidjson/include)
+
+find_package_handle_standard_args(RapidJSON DEFAULT_MSG RapidJSON_INCLUDE_DIRS)
+
+if (RapidJSON_FOUND)
+ add_library(RapidJSON::RapidJSON INTERFACE IMPORTED)
+ set_target_properties(RapidJSON::RapidJSON PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${RapidJSON_INCLUDE_DIRS}"
+ )
+endif ()
+
+mark_as_advanced(RapidJSON_INCLUDE_DIRS)
diff --git a/cmake/FindWebsocketpp.cmake b/cmake/FindWebsocketpp.cmake
new file mode 100644
index 000000000..47e68edb4
--- /dev/null
+++ b/cmake/FindWebsocketpp.cmake
@@ -0,0 +1,14 @@
+include(FindPackageHandleStandardArgs)
+
+find_path(Websocketpp_INCLUDE_DIRS websocketpp/version.hpp HINTS ${CMAKE_SOURCE_DIR}/lib/websocketpp)
+
+find_package_handle_standard_args(Websocketpp DEFAULT_MSG Websocketpp_INCLUDE_DIRS)
+
+if (Websocketpp_FOUND)
+ add_library(websocketpp::websocketpp INTERFACE IMPORTED)
+ set_target_properties(websocketpp::websocketpp PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${Websocketpp_INCLUDE_DIRS}"
+ )
+endif ()
+
+mark_as_advanced(Websocketpp_INCLUDE_DIRS)
diff --git a/cmake/FindWinToast.cmake b/cmake/FindWinToast.cmake
new file mode 100644
index 000000000..3b767fb19
--- /dev/null
+++ b/cmake/FindWinToast.cmake
@@ -0,0 +1,12 @@
+if (EXISTS ${CMAKE_SOURCE_DIR}/lib/WinToast/src/wintoastlib.cpp)
+ set(WinToast_FOUND TRUE)
+ add_library(WinToast ${CMAKE_SOURCE_DIR}/lib/WinToast/src/wintoastlib.cpp)
+ target_include_directories(WinToast PUBLIC "${CMAKE_SOURCE_DIR}/lib/WinToast/src/")
+else ()
+ set(WinToast_FOUND FALSE)
+ message("WinToast submodule not found!")
+endif ()
+
+
+
+
diff --git a/cmake/GIT.cmake b/cmake/GIT.cmake
new file mode 100644
index 000000000..50ff54ec4
--- /dev/null
+++ b/cmake/GIT.cmake
@@ -0,0 +1,65 @@
+# This script will set the following variables:
+# GIT_HASH
+# If the git binary is found and the git work tree is intact, GIT_HASH is worked out using the `git rev-parse --short HEAD` command
+# The value of GIT_HASH can be overriden by defining the GIT_HASH environment variable
+# GIT_COMMIT
+# If the git binary is found and the git work tree is intact, GIT_COMMIT is worked out using the `git rev-parse HEAD` command
+# The value of GIT_COMMIT can be overriden by defining the GIT_COMMIT environment variable
+# GIT_RELEASE
+# If the git binary is found and the git work tree is intact, GIT_RELEASE is worked out using the `git describe` command
+# The value of GIT_RELEASE can be overriden by defining the GIT_RELEASE environment variable
+
+find_package(Git)
+
+set(GIT_HASH "GIT-REPOSITORY-NOT-FOUND")
+set(GIT_COMMIT "GIT-REPOSITORY-NOT-FOUND")
+set(GIT_RELEASE "${PROJECT_VERSION}")
+
+if (GIT_EXECUTABLE)
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} rev-parse --is-inside-work-tree
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ RESULT_VARIABLE GIT_REPOSITORY_NOT_FOUND
+ ERROR_QUIET
+ )
+ if (GIT_REPOSITORY_NOT_FOUND)
+ set(GIT_REPOSITORY_FOUND 0)
+ else ()
+ set(GIT_REPOSITORY_FOUND 1)
+ endif()
+
+ if (GIT_REPOSITORY_FOUND)
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ OUTPUT_VARIABLE GIT_HASH
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ OUTPUT_VARIABLE GIT_COMMIT
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} describe
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ OUTPUT_VARIABLE GIT_RELEASE
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ endif (GIT_REPOSITORY_FOUND)
+endif (GIT_EXECUTABLE)
+
+if (DEFINED ENV{GIT_HASH})
+ set(GIT_HASH "$ENV{GIT_HASH}")
+endif ()
+if (DEFINED ENV{GIT_COMMIT})
+ set(GIT_COMMIT "$ENV{GIT_COMMIT}")
+endif ()
+if (DEFINED ENV{GIT_RELEASE})
+ set(GIT_RELEASE "$ENV{GIT_RELEASE}")
+endif ()
+
+message(STATUS "Injected git values: ${GIT_COMMIT} (${GIT_RELEASE}) ${GIT_HASH}")
diff --git a/cmake/MacOSXBundleInfo.plist.in b/cmake/MacOSXBundleInfo.plist.in
new file mode 100644
index 000000000..ae08eb0d9
--- /dev/null
+++ b/cmake/MacOSXBundleInfo.plist.in
@@ -0,0 +1,36 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ English
+ CFBundleExecutable
+ ${MACOSX_BUNDLE_EXECUTABLE_NAME}
+ CFBundleGetInfoString
+ ${MACOSX_BUNDLE_INFO_STRING}
+ CFBundleIconFile
+ ${MACOSX_BUNDLE_ICON_FILE}
+ CFBundleIdentifier
+ ${MACOSX_BUNDLE_GUI_IDENTIFIER}
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleLongVersionString
+ ${MACOSX_BUNDLE_LONG_VERSION_STRING}
+ CFBundleName
+ ${MACOSX_BUNDLE_BUNDLE_NAME}
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ ${MACOSX_BUNDLE_SHORT_VERSION_STRING}
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ ${MACOSX_BUNDLE_BUNDLE_VERSION}
+ CSResourcesFileMapped
+
+ NSHumanReadableCopyright
+ ${MACOSX_BUNDLE_COPYRIGHT}
+ NSPrincipalClass
+ NSApplication
+
+
diff --git a/cmake/SourceFileUtils.cmake b/cmake/SourceFileUtils.cmake
new file mode 100644
index 000000000..e898e385b
--- /dev/null
+++ b/cmake/SourceFileUtils.cmake
@@ -0,0 +1,80 @@
+# The MIT License (MIT)
+#
+# Copyright (c) 2016 Fabian Killus
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+# associated documentation files (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge, publish, distribute,
+# sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all copies or
+# substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+# ================================================================================================ #
+# GENERATE_SOURCE_GROUPS( SOURCE_FILES ) #
+# #
+# In CMake the source_group() command can be used to provide guidance for IDEs such as Visual
+# Studio or XCode how to organize source files.
+# This function takes a list of source files and creates sensible source groups based on the
+# path provided for each file. In addition header and source files are sorted into separate super
+# groups. For example:
+#
+# path/to/file.cpp
+# path/to/file.h
+#
+# might be displayed in an IDE somewhat like this
+#
+# |-Header Files
+# ||-path
+# | |-to
+# | |-file.h
+# |-Source Files
+# ||-path
+# | |-to
+# | |-file.cpp
+#
+
+function(generate_source_groups)
+
+ set(SOURCES_GROUP "Source Files")
+ set(HEADERS_GROUP "Header Files")
+
+ foreach (f IN LISTS ARGN)
+ # Split filename into its components
+ get_filename_component(filename ${f} NAME)
+ get_filename_component(filedir ${f} DIRECTORY)
+
+ # Extract group name from directory path
+ if (filedir AND NOT ARG_FLAT_STRUCTURE)
+ string(REPLACE "${CMAKE_SOURCE_DIR}/" "" tmp_dir ${filedir})
+ string(REPLACE "/" "\\\\" groupdir ${tmp_dir})
+ else ()
+ set(groupdir "")
+ endif ()
+ list(APPEND GROUPDIRS ${groupdir})
+
+ # sort according to filetype
+ if (${filename} MATCHES ".*\\.(c|cc|cpp|cxx)")
+ list(APPEND ${groupdir}_SOURCES ${f})
+ elseif (${filename} MATCHES ".*\\.(h|hpp|hxx|txx)")
+ list(APPEND ${groupdir}_HEADERS ${f})
+ endif ()
+ endforeach ()
+
+ list(REMOVE_DUPLICATES GROUPDIRS)
+
+ foreach (groupdir IN LISTS GROUPDIRS)
+ source_group("${SOURCES_GROUP}\\${groupdir}" FILES ${${groupdir}_SOURCES})
+ source_group("${HEADERS_GROUP}\\${groupdir}" FILES ${${groupdir}_HEADERS})
+ endforeach ()
+
+endfunction()
+
diff --git a/conanfile.txt b/conanfile.txt
index 55ac46616..57d42da73 100644
--- a/conanfile.txt
+++ b/conanfile.txt
@@ -1,12 +1,15 @@
[requires]
openssl/1.1.1d
-boost/1.71.0
+boost/1.75.0
[generators]
qmake
+cmake
[options]
openssl:shared=True
[imports]
+bin, *.dll -> ./bin @ keep_path=False
bin, *.dll -> ./Chatterino2 @ keep_path=False
+lib, *.so* -> ./bin @ keep_path=False
diff --git a/docs/make-release.md b/docs/make-release.md
new file mode 100644
index 000000000..27008ea5c
--- /dev/null
+++ b/docs/make-release.md
@@ -0,0 +1,4 @@
+# Checklist for making a release
+
+- [ ] Updated version code in `src/common/Version.hpp`
+- [ ] Updated version code in `CMakeLists.txt`
diff --git a/lib/libcommuni b/lib/libcommuni
index 28e798a64..05e929254 160000
--- a/lib/libcommuni
+++ b/lib/libcommuni
@@ -1 +1 @@
-Subproject commit 28e798a642e0916e5b94b1698c9fd3c8a3c7a126
+Subproject commit 05e929254b43a464b2345066fc1ff007e40077ff
diff --git a/lib/qtkeychain b/lib/qtkeychain
index ee12141b7..de9546273 160000
--- a/lib/qtkeychain
+++ b/lib/qtkeychain
@@ -1 +1 @@
-Subproject commit ee12141b793e7189716ede02dee407f2df76f6c5
+Subproject commit de954627363b0b4bff9a2616f1a409b7e14d5df9
diff --git a/lib/settings b/lib/settings
index 66841d98a..6a71d6c39 160000
--- a/lib/settings
+++ b/lib/settings
@@ -1 +1 @@
-Subproject commit 66841d98ac1befba280a892914b521cac1ff92cb
+Subproject commit 6a71d6c395af2134ff56c50a5d056866ac4f3134
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 000000000..35ef09fbe
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,625 @@
+include(SourceFileUtils)
+
+set(SOURCE_FILES main.cpp
+ Application.cpp
+ Application.hpp
+ BaseSettings.cpp
+ BaseSettings.hpp
+ BaseTheme.cpp
+ BaseTheme.hpp
+ BrowserExtension.cpp
+ BrowserExtension.hpp
+ RunGui.cpp
+ RunGui.hpp
+
+ common/Args.cpp
+ common/Args.hpp
+ common/Channel.cpp
+ common/Channel.hpp
+ common/ChannelChatters.cpp
+ common/ChannelChatters.hpp
+ common/ChatterinoSetting.cpp
+ common/ChatterinoSetting.hpp
+ common/CompletionModel.cpp
+ common/CompletionModel.hpp
+ common/Credentials.cpp
+ common/Credentials.hpp
+ common/DownloadManager.cpp
+ common/DownloadManager.hpp
+ common/Env.cpp
+ common/Env.hpp
+ common/LinkParser.cpp
+ common/LinkParser.hpp
+ common/Modes.cpp
+ common/Modes.hpp
+ common/NetworkManager.cpp
+ common/NetworkManager.hpp
+ common/NetworkPrivate.cpp
+ common/NetworkPrivate.hpp
+ common/NetworkRequest.cpp
+ common/NetworkRequest.hpp
+ common/NetworkResult.cpp
+ common/NetworkResult.hpp
+ common/QLogging.cpp
+ common/QLogging.hpp
+ common/UsernameSet.cpp
+ common/UsernameSet.hpp
+ common/Version.cpp
+ common/Version.hpp
+ common/WindowDescriptors.cpp
+ common/WindowDescriptors.hpp
+
+ controllers/accounts/Account.cpp
+ controllers/accounts/Account.hpp
+ controllers/accounts/AccountController.cpp
+ controllers/accounts/AccountController.hpp
+ controllers/accounts/AccountModel.cpp
+ controllers/accounts/AccountModel.hpp
+
+ controllers/commands/Command.cpp
+ controllers/commands/Command.hpp
+ controllers/commands/CommandController.cpp
+ controllers/commands/CommandController.hpp
+ controllers/commands/CommandModel.cpp
+ controllers/commands/CommandModel.hpp
+
+ controllers/filters/FilterModel.cpp
+ controllers/filters/FilterModel.hpp
+ controllers/filters/parser/FilterParser.cpp
+ controllers/filters/parser/FilterParser.hpp
+ controllers/filters/parser/Tokenizer.cpp
+ controllers/filters/parser/Tokenizer.hpp
+ controllers/filters/parser/Types.cpp
+ controllers/filters/parser/Types.hpp
+
+ controllers/highlights/HighlightBlacklistModel.cpp
+ controllers/highlights/HighlightBlacklistModel.hpp
+ controllers/highlights/HighlightModel.cpp
+ controllers/highlights/HighlightModel.hpp
+ controllers/highlights/HighlightPhrase.cpp
+ controllers/highlights/HighlightPhrase.hpp
+ controllers/highlights/UserHighlightModel.cpp
+ controllers/highlights/UserHighlightModel.hpp
+
+ controllers/ignores/IgnoreModel.cpp
+ controllers/ignores/IgnoreModel.hpp
+
+ controllers/moderationactions/ModerationAction.cpp
+ controllers/moderationactions/ModerationAction.hpp
+ controllers/moderationactions/ModerationActionModel.cpp
+ controllers/moderationactions/ModerationActionModel.hpp
+
+ controllers/notifications/NotificationController.cpp
+ controllers/notifications/NotificationController.hpp
+ controllers/notifications/NotificationModel.cpp
+ controllers/notifications/NotificationModel.hpp
+
+ controllers/pings/MutedChannelModel.cpp
+ controllers/pings/MutedChannelModel.hpp
+
+ controllers/taggedusers/TaggedUser.cpp
+ controllers/taggedusers/TaggedUser.hpp
+ controllers/taggedusers/TaggedUsersModel.cpp
+ controllers/taggedusers/TaggedUsersModel.hpp
+
+ debug/Benchmark.cpp
+ debug/Benchmark.hpp
+
+ messages/Emote.cpp
+ messages/Emote.hpp
+ messages/Image.cpp
+ messages/Image.hpp
+ messages/ImageSet.cpp
+ messages/ImageSet.hpp
+ messages/Link.cpp
+ messages/Link.hpp
+ messages/Message.cpp
+ messages/Message.hpp
+ messages/MessageBuilder.cpp
+ messages/MessageBuilder.hpp
+ messages/MessageColor.cpp
+ messages/MessageColor.hpp
+ messages/MessageContainer.cpp
+ messages/MessageContainer.hpp
+ messages/MessageElement.cpp
+ messages/MessageElement.hpp
+
+ messages/SharedMessageBuilder.cpp
+ messages/SharedMessageBuilder.hpp
+
+ messages/layouts/MessageLayout.cpp
+ messages/layouts/MessageLayout.hpp
+ messages/layouts/MessageLayoutContainer.cpp
+ messages/layouts/MessageLayoutContainer.hpp
+ messages/layouts/MessageLayoutElement.cpp
+ messages/layouts/MessageLayoutElement.hpp
+ messages/search/AuthorPredicate.cpp
+ messages/search/AuthorPredicate.hpp
+ messages/search/LinkPredicate.cpp
+ messages/search/LinkPredicate.hpp
+ messages/search/SubstringPredicate.cpp
+ messages/search/SubstringPredicate.hpp
+
+ providers/IvrApi.cpp
+ providers/IvrApi.hpp
+ providers/LinkResolver.cpp
+ providers/LinkResolver.hpp
+
+ providers/bttv/BttvEmotes.cpp
+ providers/bttv/BttvEmotes.hpp
+ providers/bttv/LoadBttvChannelEmote.cpp
+ providers/bttv/LoadBttvChannelEmote.hpp
+
+ providers/chatterino/ChatterinoBadges.cpp
+ providers/chatterino/ChatterinoBadges.hpp
+
+ providers/colors/ColorProvider.cpp
+ providers/colors/ColorProvider.hpp
+
+ providers/emoji/Emojis.cpp
+ providers/emoji/Emojis.hpp
+
+ providers/ffz/FfzBadges.cpp
+ providers/ffz/FfzBadges.hpp
+ providers/ffz/FfzEmotes.cpp
+ providers/ffz/FfzEmotes.hpp
+
+ providers/irc/AbstractIrcServer.cpp
+ providers/irc/AbstractIrcServer.hpp
+ providers/irc/Irc2.cpp
+ providers/irc/Irc2.hpp
+ providers/irc/IrcAccount.cpp
+ providers/irc/IrcAccount.hpp
+ providers/irc/IrcChannel2.cpp
+ providers/irc/IrcChannel2.hpp
+ providers/irc/IrcCommands.cpp
+ providers/irc/IrcCommands.hpp
+ providers/irc/IrcConnection2.cpp
+ providers/irc/IrcConnection2.hpp
+ providers/irc/IrcMessageBuilder.cpp
+ providers/irc/IrcMessageBuilder.hpp
+ providers/irc/IrcServer.cpp
+ providers/irc/IrcServer.hpp
+
+ providers/twitch/ChannelPointReward.cpp
+ providers/twitch/ChannelPointReward.hpp
+ providers/twitch/IrcMessageHandler.cpp
+ providers/twitch/IrcMessageHandler.hpp
+ providers/twitch/PubsubActions.cpp
+ providers/twitch/PubsubActions.hpp
+ providers/twitch/PubsubClient.cpp
+ providers/twitch/PubsubClient.hpp
+ providers/twitch/PubsubHelpers.cpp
+ providers/twitch/PubsubHelpers.hpp
+ providers/twitch/TwitchAccount.cpp
+ providers/twitch/TwitchAccount.hpp
+ providers/twitch/TwitchAccountManager.cpp
+ providers/twitch/TwitchAccountManager.hpp
+ providers/twitch/TwitchBadge.cpp
+ providers/twitch/TwitchBadge.hpp
+ providers/twitch/TwitchBadges.cpp
+ providers/twitch/TwitchBadges.hpp
+ providers/twitch/TwitchChannel.cpp
+ providers/twitch/TwitchChannel.hpp
+ providers/twitch/TwitchEmotes.cpp
+ providers/twitch/TwitchEmotes.hpp
+ providers/twitch/TwitchHelpers.cpp
+ providers/twitch/TwitchHelpers.hpp
+ providers/twitch/TwitchIrcServer.cpp
+ providers/twitch/TwitchIrcServer.hpp
+ providers/twitch/TwitchMessageBuilder.cpp
+ providers/twitch/TwitchMessageBuilder.hpp
+ providers/twitch/TwitchParseCheerEmotes.cpp
+ providers/twitch/TwitchParseCheerEmotes.hpp
+ providers/twitch/TwitchUser.cpp
+ providers/twitch/TwitchUser.hpp
+
+ providers/twitch/api/Helix.cpp
+ providers/twitch/api/Helix.hpp
+ providers/twitch/api/Kraken.cpp
+ providers/twitch/api/Kraken.hpp
+
+ singletons/Badges.cpp
+ singletons/Badges.hpp
+ singletons/Emotes.cpp
+ singletons/Emotes.hpp
+ singletons/Fonts.cpp
+ singletons/Fonts.hpp
+ singletons/Logging.cpp
+ singletons/Logging.hpp
+ singletons/NativeMessaging.cpp
+ singletons/NativeMessaging.hpp
+ singletons/Paths.cpp
+ singletons/Paths.hpp
+ singletons/Resources.cpp
+ singletons/Resources.hpp
+ singletons/Settings.cpp
+ singletons/Settings.hpp
+ singletons/Theme.cpp
+ singletons/Theme.hpp
+ singletons/Toasts.cpp
+ singletons/Toasts.hpp
+ singletons/TooltipPreviewImage.cpp
+ singletons/TooltipPreviewImage.hpp
+ singletons/Updates.cpp
+ singletons/Updates.hpp
+ singletons/WindowManager.cpp
+ singletons/WindowManager.hpp
+
+ singletons/helper/GifTimer.cpp
+ singletons/helper/GifTimer.hpp
+ singletons/helper/LoggingChannel.cpp
+ singletons/helper/LoggingChannel.hpp
+
+ util/AttachToConsole.cpp
+ util/AttachToConsole.hpp
+ util/Clipboard.cpp
+ util/Clipboard.hpp
+ util/DebugCount.cpp
+ util/DebugCount.hpp
+ util/FormatTime.cpp
+ util/FormatTime.hpp
+ util/FunctionEventFilter.cpp
+ util/FunctionEventFilter.hpp
+ util/FuzzyConvert.cpp
+ util/FuzzyConvert.hpp
+ util/Helpers.cpp
+ util/Helpers.hpp
+ util/IncognitoBrowser.cpp
+ util/IncognitoBrowser.hpp
+ util/InitUpdateButton.cpp
+ util/InitUpdateButton.hpp
+ util/JsonQuery.cpp
+ util/JsonQuery.hpp
+ util/LayoutHelper.cpp
+ util/LayoutHelper.hpp
+ util/NuulsUploader.cpp
+ util/NuulsUploader.hpp
+ util/RapidjsonHelpers.cpp
+ util/RapidjsonHelpers.hpp
+ util/SplitCommand.cpp
+ util/SplitCommand.hpp
+ util/StreamLink.cpp
+ util/StreamLink.hpp
+ util/StreamerMode.cpp
+ util/StreamerMode.hpp
+ util/Twitch.cpp
+ util/Twitch.hpp
+ util/WindowsHelper.cpp
+ util/WindowsHelper.hpp
+
+ widgets/AccountSwitchPopup.cpp
+ widgets/AccountSwitchPopup.hpp
+ widgets/AccountSwitchWidget.cpp
+ widgets/AccountSwitchWidget.hpp
+ widgets/AttachedWindow.cpp
+ widgets/AttachedWindow.hpp
+ widgets/BasePopup.cpp
+ widgets/BasePopup.hpp
+ widgets/BaseWidget.cpp
+ widgets/BaseWidget.hpp
+ widgets/BaseWindow.cpp
+ widgets/BaseWindow.hpp
+ widgets/Label.cpp
+ widgets/Label.hpp
+ widgets/Notebook.cpp
+ widgets/Notebook.hpp
+ widgets/Scrollbar.cpp
+ widgets/Scrollbar.hpp
+ widgets/StreamView.cpp
+ widgets/StreamView.hpp
+ widgets/TooltipWidget.cpp
+ widgets/TooltipWidget.hpp
+ widgets/Window.cpp
+ widgets/Window.hpp
+
+ widgets/dialogs/ChannelFilterEditorDialog.cpp
+ widgets/dialogs/ChannelFilterEditorDialog.hpp
+ widgets/dialogs/ColorPickerDialog.cpp
+ widgets/dialogs/ColorPickerDialog.hpp
+ widgets/dialogs/EmotePopup.cpp
+ widgets/dialogs/EmotePopup.hpp
+ widgets/dialogs/IrcConnectionEditor.cpp
+ widgets/dialogs/IrcConnectionEditor.hpp
+ widgets/dialogs/IrcConnectionEditor.ui
+ widgets/dialogs/LastRunCrashDialog.cpp
+ widgets/dialogs/LastRunCrashDialog.hpp
+ widgets/dialogs/LoginDialog.cpp
+ widgets/dialogs/LoginDialog.hpp
+ widgets/dialogs/NotificationPopup.cpp
+ widgets/dialogs/NotificationPopup.hpp
+ widgets/dialogs/QualityPopup.cpp
+ widgets/dialogs/QualityPopup.hpp
+ widgets/dialogs/SelectChannelDialog.cpp
+ widgets/dialogs/SelectChannelDialog.hpp
+ widgets/dialogs/SelectChannelFiltersDialog.cpp
+ widgets/dialogs/SelectChannelFiltersDialog.hpp
+ widgets/dialogs/SettingsDialog.cpp
+ widgets/dialogs/SettingsDialog.hpp
+ widgets/dialogs/TextInputDialog.cpp
+ widgets/dialogs/TextInputDialog.hpp
+ widgets/dialogs/UpdateDialog.cpp
+ widgets/dialogs/UpdateDialog.hpp
+ widgets/dialogs/UserInfoPopup.cpp
+ widgets/dialogs/UserInfoPopup.hpp
+ widgets/dialogs/WelcomeDialog.cpp
+ widgets/dialogs/WelcomeDialog.hpp
+ widgets/dialogs/switcher/NewTabItem.cpp
+ widgets/dialogs/switcher/NewTabItem.hpp
+ widgets/dialogs/switcher/QuickSwitcherModel.cpp
+ widgets/dialogs/switcher/QuickSwitcherModel.hpp
+ widgets/dialogs/switcher/QuickSwitcherPopup.cpp
+ widgets/dialogs/switcher/QuickSwitcherPopup.hpp
+ widgets/dialogs/switcher/SwitchSplitItem.cpp
+ widgets/dialogs/switcher/SwitchSplitItem.hpp
+
+ widgets/helper/Button.cpp
+ widgets/helper/Button.hpp
+ widgets/helper/ChannelView.cpp
+ widgets/helper/ChannelView.hpp
+ widgets/helper/ColorButton.cpp
+ widgets/helper/ColorButton.hpp
+ widgets/helper/ComboBoxItemDelegate.cpp
+ widgets/helper/ComboBoxItemDelegate.hpp
+ widgets/helper/DebugPopup.cpp
+ widgets/helper/DebugPopup.hpp
+ widgets/helper/EditableModelView.cpp
+ widgets/helper/EditableModelView.hpp
+ widgets/helper/EffectLabel.cpp
+ widgets/helper/EffectLabel.hpp
+ widgets/helper/NotebookButton.cpp
+ widgets/helper/NotebookButton.hpp
+ widgets/helper/NotebookTab.cpp
+ widgets/helper/NotebookTab.hpp
+ widgets/helper/QColorPicker.cpp
+ widgets/helper/QColorPicker.hpp
+ widgets/helper/ResizingTextEdit.cpp
+ widgets/helper/ResizingTextEdit.hpp
+ widgets/helper/ScrollbarHighlight.cpp
+ widgets/helper/ScrollbarHighlight.hpp
+ widgets/helper/SearchPopup.cpp
+ widgets/helper/SearchPopup.hpp
+ widgets/helper/SettingsDialogTab.cpp
+ widgets/helper/SettingsDialogTab.hpp
+ widgets/helper/SignalLabel.cpp
+ widgets/helper/SignalLabel.hpp
+ widgets/helper/TitlebarButton.cpp
+ widgets/helper/TitlebarButton.hpp
+
+ widgets/listview/GenericItemDelegate.cpp
+ widgets/listview/GenericItemDelegate.hpp
+ widgets/listview/GenericListItem.cpp
+ widgets/listview/GenericListItem.hpp
+ widgets/listview/GenericListModel.cpp
+ widgets/listview/GenericListModel.hpp
+ widgets/listview/GenericListView.cpp
+ widgets/listview/GenericListView.hpp
+
+ widgets/settingspages/AboutPage.cpp
+ widgets/settingspages/AboutPage.hpp
+ widgets/settingspages/AccountsPage.cpp
+ widgets/settingspages/AccountsPage.hpp
+ widgets/settingspages/CommandPage.cpp
+ widgets/settingspages/CommandPage.hpp
+ widgets/settingspages/ExternalToolsPage.cpp
+ widgets/settingspages/ExternalToolsPage.hpp
+ widgets/settingspages/FiltersPage.cpp
+ widgets/settingspages/FiltersPage.hpp
+ widgets/settingspages/GeneralPage.cpp
+ widgets/settingspages/GeneralPage.hpp
+ widgets/settingspages/GeneralPageView.cpp
+ widgets/settingspages/GeneralPageView.hpp
+ widgets/settingspages/HighlightingPage.cpp
+ widgets/settingspages/HighlightingPage.hpp
+ widgets/settingspages/IgnoresPage.cpp
+ widgets/settingspages/IgnoresPage.hpp
+ widgets/settingspages/KeyboardSettingsPage.cpp
+ widgets/settingspages/KeyboardSettingsPage.hpp
+ widgets/settingspages/ModerationPage.cpp
+ widgets/settingspages/ModerationPage.hpp
+ widgets/settingspages/NotificationPage.cpp
+ widgets/settingspages/NotificationPage.hpp
+ widgets/settingspages/SettingsPage.cpp
+ widgets/settingspages/SettingsPage.hpp
+
+ widgets/splits/ClosedSplits.cpp
+ widgets/splits/ClosedSplits.hpp
+ widgets/splits/EmoteInputItem.cpp
+ widgets/splits/EmoteInputItem.hpp
+ widgets/splits/EmoteInputPopup.cpp
+ widgets/splits/EmoteInputPopup.hpp
+ widgets/splits/Split.cpp
+ widgets/splits/Split.hpp
+ widgets/splits/SplitContainer.cpp
+ widgets/splits/SplitContainer.hpp
+ widgets/splits/SplitHeader.cpp
+ widgets/splits/SplitHeader.hpp
+ widgets/splits/SplitInput.cpp
+ widgets/splits/SplitInput.hpp
+ widgets/splits/SplitOverlay.cpp
+ widgets/splits/SplitOverlay.hpp
+
+ autogenerated/ResourcesAutogen.cpp
+ autogenerated/ResourcesAutogen.hpp
+
+ ${CMAKE_SOURCE_DIR}/resources/resources.qrc
+ ${CMAKE_SOURCE_DIR}/resources/resources_autogenerated.qrc
+ )
+
+if (WIN32)
+ # clang-cl doesn't support resource files
+ if (NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ list(APPEND SOURCE_FILES "${CMAKE_SOURCE_DIR}/resources/windows.rc")
+ endif ()
+
+elseif (APPLE)
+ set(MACOS_BUNDLE_ICON_FILE "${CMAKE_SOURCE_DIR}/resources/chatterino.icns")
+ list(APPEND SOURCE_FILES "${MACOS_BUNDLE_ICON_FILE}")
+ set_source_files_properties(${MACOS_BUNDLE_ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
+endif ()
+
+# Generate source groups for use in IDEs
+generate_source_groups(${SOURCE_FILES})
+
+add_executable(${PROJECT_NAME} ${SOURCE_FILES})
+
+target_precompile_headers(${PROJECT_NAME} PRIVATE PrecompiledHeader.hpp)
+
+# Enable autogeneration of Qts MOC/RCC/UIC
+set_target_properties(${PROJECT_NAME}
+ PROPERTIES
+ AUTOMOC ON
+ AUTORCC ON
+ AUTOUIC ON
+ )
+
+target_compile_definitions(${PROJECT_NAME} PRIVATE
+ CHATTERINO
+ UNICODE
+ AB_CUSTOM_THEME
+ AB_CUSTOM_SETTINGS
+ IRC_STATIC
+ IRC_NAMESPACE=Communi
+ )
+if (USE_SYSTEM_QT5KEYCHAIN)
+ target_compile_definitions(${PROJECT_NAME} PRIVATE
+ CMAKE_BUILD
+ )
+endif ()
+target_compile_definitions(${PROJECT_NAME} PRIVATE
+ CHATTERINO_GIT_HASH=\"${GIT_HASH}\"
+ CHATTERINO_GIT_RELEASE=\"${GIT_RELEASE}\"
+ CHATTERINO_GIT_COMMIT=\"${GIT_COMMIT}\"
+ )
+if (WIN32)
+ target_compile_definitions(${PROJECT_NAME} PRIVATE
+ USEWINSDK
+ )
+ set_target_properties(${PROJECT_NAME} PROPERTIES WIN32_EXECUTABLE TRUE)
+endif ()
+
+if (MSVC)
+ target_compile_options(${PROJECT_NAME} PRIVATE /EHsc)
+endif ()
+
+if (APPLE)
+ set_target_properties(${PROJECT_NAME} PROPERTIES MACOSX_BUNDLE TRUE)
+ set_target_properties(${PROJECT_NAME}
+ PROPERTIES
+ MACOSX_BUNDLE_BUNDLE_NAME "Chatterino"
+ MACOSX_BUNDLE_GUI_IDENTIFIER "com.chatterino"
+ MACOSX_BUNDLE_INFO_STRING "Chat client for Twitch"
+ MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_VERSION}"
+ MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}"
+ MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_VERSION}"
+ MACOSX_BUNDLE_ICON_FILE chatterino.icns
+ )
+endif ()
+
+target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+
+target_link_libraries(${PROJECT_NAME}
+ PRIVATE
+ Qt5::Core
+ Qt5::Widgets
+ Qt5::Gui
+ Qt5::Network
+ Qt5::Multimedia
+ Qt5::Svg
+ Qt5::Concurrent
+ )
+
+if (WinToast_FOUND)
+ target_link_libraries(${PROJECT_NAME}
+ PRIVATE
+ WinToast)
+endif ()
+
+if (USE_CONAN AND TARGET CONAN_PKG::boost)
+ target_link_libraries(${PROJECT_NAME}
+ PRIVATE
+ CONAN_PKG::boost
+ )
+else ()
+ target_link_libraries(${PROJECT_NAME}
+ PRIVATE
+ Boost::boost
+ )
+endif ()
+
+if (USE_CONAN AND TARGET CONAN_PKG::openssl)
+ target_link_libraries(${PROJECT_NAME}
+ PRIVATE
+ CONAN_PKG::openssl
+ )
+else ()
+ target_link_libraries(${PROJECT_NAME}
+ PRIVATE
+ OpenSSL::SSL
+ OpenSSL::Crypto
+ )
+endif ()
+
+target_include_directories(${PROJECT_NAME} PRIVATE ${RapidJSON_INCLUDE_DIRS})
+target_link_libraries(${PROJECT_NAME}
+ PRIVATE
+ LibCommuni::LibCommuni
+ qt5keychain
+ Pajlada::Serialize
+ Pajlada::Settings
+ Pajlada::Signals
+ websocketpp::websocketpp
+ Threads::Threads
+ RapidJSON::RapidJSON
+ LRUCache
+ )
+if (LIBRT)
+ target_link_libraries(${PROJECT_NAME}
+ PRIVATE
+ ${LIBRT}
+ )
+endif ()
+
+set_target_properties(${PROJECT_NAME}
+ PROPERTIES
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
+ RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/bin"
+ RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/bin"
+ RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_BINARY_DIR}/bin"
+ )
+
+if (MSVC)
+ get_target_property(Qt5_Core_Location Qt5::Core LOCATION)
+ get_filename_component(QT_BIN_DIR ${Qt5_Core_Location} DIRECTORY)
+ set(WINDEPLOYQT_COMMAND "${QT_BIN_DIR}/windeployqt.exe" $ --release --no-compiler-runtime --no-translations --no-opengl-sw)
+
+ install(TARGETS ${PROJECT_NAME}
+ RUNTIME DESTINATION .
+ )
+
+ install(CODE "execute_process(COMMAND ${WINDEPLOYQT_COMMAND} --dir \${CMAKE_INSTALL_PREFIX})")
+elseif (APPLE)
+ install(TARGETS ${PROJECT_NAME}
+ RUNTIME DESTINATION bin
+ BUNDLE DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib/static
+ )
+else ()
+ install(TARGETS ${PROJECT_NAME}
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib/static
+ )
+
+ install(FILES ${CMAKE_SOURCE_DIR}/resources/com.chatterino.chatterino.desktop
+ DESTINATION share/applications
+ )
+
+ install(FILES ${CMAKE_SOURCE_DIR}/resources/icon.png
+ RENAME com.chatterino.chatterino.png
+ DESTINATION share/icons/hicolor/256x256/apps
+ )
+endif ()
diff --git a/src/common/Credentials.cpp b/src/common/Credentials.cpp
index 9bf3266e0..28ac985c4 100644
--- a/src/common/Credentials.cpp
+++ b/src/common/Credentials.cpp
@@ -1,12 +1,16 @@
#include "Credentials.hpp"
#include "debug/AssertInGuiThread.hpp"
-#include "keychain.h"
#include "singletons/Paths.hpp"
#include "singletons/Settings.hpp"
#include "util/CombinePath.hpp"
#include "util/Overloaded.hpp"
+#ifdef CMAKE_BUILD
+# include "qt5keychain/keychain.h"
+#else
+# include "keychain.h"
+#endif
#include
#include
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644
index 000000000..dc47bea95
--- /dev/null
+++ b/tests/CMakeLists.txt
@@ -0,0 +1,104 @@
+project(chatterino-test)
+
+set(main_dir ${CMAKE_SOURCE_DIR}/src)
+
+include_directories(${main_dir})
+
+set(chatterino_SOURCES
+ ${CMAKE_SOURCE_DIR}/src/BaseSettings.cpp
+
+ ${CMAKE_SOURCE_DIR}/src/common/ChatterinoSetting.cpp
+ ${CMAKE_SOURCE_DIR}/src/common/Modes.cpp
+ ${CMAKE_SOURCE_DIR}/src/common/NetworkManager.cpp
+ ${CMAKE_SOURCE_DIR}/src/common/NetworkPrivate.cpp
+ ${CMAKE_SOURCE_DIR}/src/common/NetworkRequest.cpp
+ ${CMAKE_SOURCE_DIR}/src/common/NetworkResult.cpp
+ ${CMAKE_SOURCE_DIR}/src/common/QLogging.cpp
+ ${CMAKE_SOURCE_DIR}/src/common/UsernameSet.cpp
+
+ ${CMAKE_SOURCE_DIR}/src/controllers/highlights/HighlightPhrase.cpp
+
+ ${CMAKE_SOURCE_DIR}/src/messages/Emote.cpp
+ ${CMAKE_SOURCE_DIR}/src/messages/Image.cpp
+ ${CMAKE_SOURCE_DIR}/src/messages/ImageSet.cpp
+
+ ${CMAKE_SOURCE_DIR}/src/providers/emoji/Emojis.cpp
+
+ ${CMAKE_SOURCE_DIR}/src/singletons/Paths.cpp
+
+ ${CMAKE_SOURCE_DIR}/src/util/DebugCount.cpp
+ ${CMAKE_SOURCE_DIR}/src/util/RapidjsonHelpers.cpp
+
+ ${CMAKE_SOURCE_DIR}/resources/resources.qrc
+ ${CMAKE_SOURCE_DIR}/resources/resources_autogenerated.qrc
+ )
+
+set(test_SOURCES
+ ${CMAKE_CURRENT_LIST_DIR}/src/main.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/src/NetworkRequest.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/src/UsernameSet.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/src/HighlightPhrase.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/src/Emojis.cpp
+ )
+
+add_executable(${PROJECT_NAME}
+ ${chatterino_SOURCES}
+ ${test_SOURCES}
+ )
+
+# Enable autogeneration of Qts MOC/RCC/UIC
+set_target_properties(${PROJECT_NAME}
+ PROPERTIES
+ AUTOMOC ON
+ AUTORCC ON
+ AUTOUIC ON
+ )
+
+target_link_libraries(${PROJECT_NAME} PRIVATE
+ Qt5::Core
+ Qt5::Widgets
+ Qt5::Network
+ Qt5::Concurrent
+ gtest gtest_main
+ Pajlada::Serialize
+ Pajlada::Settings
+ Pajlada::Signals
+ Threads::Threads
+ )
+
+target_compile_definitions(${PROJECT_NAME} PRIVATE
+ CHATTERINO
+ CHATTERINO_TEST
+ UNICODE
+ AB_CUSTOM_THEME
+ AB_CUSTOM_SETTINGS
+ IRC_STATIC
+ IRC_NAMESPACE=Communi
+ CHATTERINO_GIT_HASH=\"${GIT_HASH}\"
+ CHATTERINO_GIT_RELEASE=\"${GIT_RELEASE}\"
+ CHATTERINO_GIT_COMMIT=\"${GIT_COMMIT}\"
+ )
+
+if (WIN32)
+ target_compile_definitions(${PROJECT_NAME} PRIVATE
+ USEWINSDK
+ )
+endif ()
+
+set_target_properties(${PROJECT_NAME}
+ PROPERTIES
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
+ RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/bin"
+ RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/bin"
+ RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_BINARY_DIR}/bin"
+ )
+
+# gtest_add_tests manages to discover the tests because it looks through the source files
+# HOWEVER, it fails to run, because we have some bug that causes the QApplication exit to stall when no network requests have been made.
+# ctest runs each test individually, so for now we require that testers just run the ./bin/chatterino-test binary without any filters applied
+# gtest_add_tests(
+# TARGET ${PROJECT_NAME}
+# SOURCES ${test_SOURCES}
+# )