Compare commits
	
		
			10 Commits
		
	
	
		
			v1.0.0-rc.
			...
			v1.1.0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | c3483a42db | ||
|  | d68797cebb | ||
|  | ef221d4574 | ||
|  | 3fa2e3fa3c | ||
|  | bda1bc0df6 | ||
|  | cb0f084d42 | ||
|  | 674ac146f2 | ||
|  | 1ab00ee774 | ||
|  | 38bcc30ed4 | ||
|  | 204439af94 | 
| @@ -1,11 +1,16 @@ | |||||||
| cmake_minimum_required(VERSION 3.0) | cmake_minimum_required(VERSION 3.0) | ||||||
| project(discord-screenaudio) | project(discord-screenaudio) | ||||||
|  |  | ||||||
|  | include(version.cmake) | ||||||
|  | determine_version("${CMAKE_CURRENT_SOURCE_DIR}" DISCORD_SCEENAUDIO) | ||||||
|  | add_definitions( -DDISCORD_SCEENAUDIO_VERSION_FULL="${DISCORD_SCEENAUDIO_VERSION_FULL}" ) | ||||||
|  |  | ||||||
| set(CMAKE_CXX_STANDARD 17) | set(CMAKE_CXX_STANDARD 17) | ||||||
| set(CMAKE_INCLUDE_CURRENT_DIR ON) | set(CMAKE_INCLUDE_CURRENT_DIR ON) | ||||||
| set(CMAKE_AUTOMOC ON) | set(CMAKE_AUTOMOC ON) | ||||||
| set(CMAKE_AUTORCC ON) | set(CMAKE_AUTORCC ON) | ||||||
| set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") | ||||||
|  | string(TIMESTAMP TIMESTAMP %s) | ||||||
| # set(CMAKE_AUTOUIC ON) | # set(CMAKE_AUTOUIC ON) | ||||||
|  |  | ||||||
| find_package(Qt5 CONFIG REQUIRED COMPONENTS  | find_package(Qt5 CONFIG REQUIRED COMPONENTS  | ||||||
| @@ -13,6 +18,12 @@ find_package(Qt5 CONFIG REQUIRED COMPONENTS | |||||||
|   WebEngineWidgets |   WebEngineWidgets | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | option(KF5NOTIFICATIONS "Use KF5Notifications for enhanced system notifications" ON) | ||||||
|  | if(KF5NOTIFICATIONS) | ||||||
|  |   add_definitions( -DKF5NOTIFICATIONS ) | ||||||
|  |   find_package(KF5Notifications) | ||||||
|  | endif() | ||||||
|  |  | ||||||
| set(discord-screenaudio_SRC | set(discord-screenaudio_SRC | ||||||
|   src/main.cpp |   src/main.cpp | ||||||
|   src/mainwindow.cpp |   src/mainwindow.cpp | ||||||
| @@ -47,7 +58,13 @@ add_executable(discord-screenaudio ${discord-screenaudio_SRC}) | |||||||
|  |  | ||||||
| target_link_libraries(discord-screenaudio Qt5::Widgets Qt5::WebEngineWidgets rohrkabel) | target_link_libraries(discord-screenaudio Qt5::Widgets Qt5::WebEngineWidgets rohrkabel) | ||||||
|  |  | ||||||
|  | if(KF5NOTIFICATIONS) | ||||||
|  |   target_link_libraries(discord-screenaudio KF5::Notifications) | ||||||
|  |   install(FILES assets/discord-screenaudio.notifyrc DESTINATION ${CMAKE_INSTALL_PREFIX}/share/knotifications5) | ||||||
|  | endif() | ||||||
|  |  | ||||||
| install(TARGETS discord-screenaudio DESTINATION bin) | install(TARGETS discord-screenaudio DESTINATION bin) | ||||||
| install(PROGRAMS assets/de.shorsh.discord-screenaudio.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/256x256/apps) | install(FILES assets/de.shorsh.discord-screenaudio.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/256x256/apps) | ||||||
| install(PROGRAMS assets/de.shorsh.discord-screenaudio.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) | install(PROGRAMS assets/de.shorsh.discord-screenaudio.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) | ||||||
| install(PROGRAMS assets/de.shorsh.discord-screenaudio.metainfo.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo) | configure_file(assets/de.shorsh.discord-screenaudio.metainfo.xml.in de.shorsh.discord-screenaudio.metainfo.xml) | ||||||
|  | install(FILES ${CMAKE_BINARY_DIR}/de.shorsh.discord-screenaudio.metainfo.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo) | ||||||
|   | |||||||
							
								
								
									
										23
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								README.md
									
									
									
									
									
								
							| @@ -15,6 +15,11 @@ case you want to stream something, maybe used with a second account. For | |||||||
| anything else, this client has way too many things that work less well than in | anything else, this client has way too many things that work less well than in | ||||||
| the original client. | the original client. | ||||||
|  |  | ||||||
|  | Technically this could be against | ||||||
|  | [Discord's TOS](https://discord.com/terms#software-in-discord%E2%80%99s-services), | ||||||
|  | so be warned. Discord probably won't ban you for using this, but if they do I | ||||||
|  | told you and it's not my fault. | ||||||
|  |  | ||||||
| ## Known Issues | ## Known Issues | ||||||
|  |  | ||||||
| - Only works with **PipeWire** | - Only works with **PipeWire** | ||||||
| @@ -24,9 +29,17 @@ the original client. | |||||||
|  |  | ||||||
| ## Installation | ## Installation | ||||||
|  |  | ||||||
| If you are using Arch, you can build and install | You have multiple options: | ||||||
| [from the AUR](https://aur.archlinux.org/packages/discord-screenaudio). If you |  | ||||||
| aren't, you will have to [build it yourself](#building-from-source). | - Install the Flatpak (recommended): | ||||||
|  |   `flatpak install de.shorsh.discord-screenaudio` | ||||||
|  | - If you are on Arch, you can build and install | ||||||
|  |   [`discord-screenaudio`](https://aur.archlinux.org/packages/discord-screenaudio) | ||||||
|  |   from the AUR | ||||||
|  | - If you are on openSUSE, you can use the | ||||||
|  |   [Open Build Service package](https://software.opensuse.org/download.html?project=home%3AVortexAcherontic&package=discord-screenaudio) | ||||||
|  |   by [@VortexAcherontic](https://github.com/VortexAcherontic) | ||||||
|  | - You can [build it yourself](#building-from-source) | ||||||
|  |  | ||||||
| ## Building from Source | ## Building from Source | ||||||
|  |  | ||||||
| @@ -34,12 +47,12 @@ aren't, you will have to [build it yourself](#building-from-source). | |||||||
|  |  | ||||||
| - Basic building tools | - Basic building tools | ||||||
| - CMake | - CMake | ||||||
| - Qt5 and QtWebEngine | - Qt5, QtWebEngine and Kf5Notifications | ||||||
| - **PipeWire** (it currently doesn't work with PulseAudio) | - **PipeWire** (it currently doesn't work with PulseAudio) | ||||||
| - Git | - Git | ||||||
|  |  | ||||||
| On Debian: | On Debian: | ||||||
| `apt install -y build-essential cmake qtbase5-dev qtwebengine5-dev pkg-config libpipewire-0.3-dev git` | `apt install -y build-essential cmake qtbase5-dev qtwebengine5-dev libkf5notifications-dev pkg-config libpipewire-0.3-dev git` | ||||||
|  |  | ||||||
| ### Building | ### Building | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,13 +5,10 @@ | |||||||
|   <project_license>GPL-3.0+</project_license> |   <project_license>GPL-3.0+</project_license> | ||||||
|   <name>discord-screenaudio</name> |   <name>discord-screenaudio</name> | ||||||
|   <releases> |   <releases> | ||||||
|     <release version="v1.0.0-rc.11" /> |     <release version="${DISCORD_SCEENAUDIO_VERSION_FULL}" timestamp="${TIMESTAMP}" /> | ||||||
|   </releases> |   </releases> | ||||||
| 
 | 
 | ||||||
|   <summary> |   <summary>A very WIP custom discord client that supports streaming with audio on Linux</summary> | ||||||
|     A very WIP custom discord client that supports streaming with audio on |  | ||||||
|     Linux. |  | ||||||
|   </summary> |  | ||||||
| 
 | 
 | ||||||
|   <description> |   <description> | ||||||
|     <p>A very WIP custom discord client that supports streaming with audio on Linux, made possible by the great work of @edisionnano and the Rohrkabel library by @Curve.</p> |     <p>A very WIP custom discord client that supports streaming with audio on Linux, made possible by the great work of @edisionnano and the Rohrkabel library by @Curve.</p> | ||||||
| @@ -19,7 +16,7 @@ | |||||||
|   </description> |   </description> | ||||||
| 
 | 
 | ||||||
|   <launchable type="desktop-id"> |   <launchable type="desktop-id"> | ||||||
|     discord-screenaudio.desktop |     de.shorsh.discord-screenaudio.desktop | ||||||
|   </launchable> |   </launchable> | ||||||
| 
 | 
 | ||||||
|   <screenshots> |   <screenshots> | ||||||
| @@ -35,4 +32,12 @@ | |||||||
|   <provides> |   <provides> | ||||||
|     <binary>discord-screenaudio</binary> |     <binary>discord-screenaudio</binary> | ||||||
|   </provides> |   </provides> | ||||||
|  | 
 | ||||||
|  |   <content_rating type="oars-1.0"> | ||||||
|  |     <content_attribute id="social-chat">intense</content_attribute> | ||||||
|  |     <content_attribute id="social-info">intense</content_attribute> | ||||||
|  |     <content_attribute id="social-audio">intense</content_attribute> | ||||||
|  |     <content_attribute id="social-contacts">intense</content_attribute> | ||||||
|  |     <content_attribute id="money-purchasing">mild</content_attribute> | ||||||
|  |   </content_rating> | ||||||
| </component> | </component> | ||||||
							
								
								
									
										8
									
								
								assets/discord-screenaudio.notifyrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								assets/discord-screenaudio.notifyrc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | [Global] | ||||||
|  | IconName=de.shorsh.discord-screenaudio | ||||||
|  | Name=discord-screenaudio | ||||||
|  | DesktopEntry=de.shorsh.discord-screenaudio.desktop | ||||||
|  |  | ||||||
|  | [Event/discordNotification] | ||||||
|  | Name=Discord Notification | ||||||
|  | Action=Popup | ||||||
| @@ -122,9 +122,10 @@ setInterval(() => { | |||||||
|   ) { |   ) { | ||||||
|     for (const el of document.getElementsByClassName("info-3pQQBb")) { |     for (const el of document.getElementsByClassName("info-3pQQBb")) { | ||||||
|       const aboutEl = document.createElement("div"); |       const aboutEl = document.createElement("div"); | ||||||
|       aboutEl.innerText = "discord-screenaudio v1.0.0-rc.11"; |       aboutEl.innerText = `discord-screenaudio ${window.discordScreenaudioVersion}`; | ||||||
|       aboutEl.style.fontSize = "12px"; |       aboutEl.style.fontSize = "12px"; | ||||||
|       aboutEl.style.color = "var(--text-muted)"; |       aboutEl.style.color = "var(--text-muted)"; | ||||||
|  |       aboutEl.style.textTransform = "none"; | ||||||
|       aboutEl.classList.add("dirscordScreenaudioAboutText"); |       aboutEl.classList.add("dirscordScreenaudioAboutText"); | ||||||
|       el.appendChild(aboutEl); |       el.appendChild(aboutEl); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -2,5 +2,6 @@ | |||||||
| <RCC> | <RCC> | ||||||
|   <qresource> |   <qresource> | ||||||
|     <file>assets/userscript.js</file> |     <file>assets/userscript.js</file> | ||||||
|  |     <file>assets/de.shorsh.discord-screenaudio.png</file> | ||||||
|   </qresource> |   </qresource> | ||||||
| </RCC> | </RCC> | ||||||
| @@ -17,6 +17,11 @@ DiscordPage::DiscordPage(QWidget *parent) : QWebEnginePage(parent) { | |||||||
|   connect(this, &QWebEnginePage::featurePermissionRequested, this, |   connect(this, &QWebEnginePage::featurePermissionRequested, this, | ||||||
|           &DiscordPage::featurePermissionRequested); |           &DiscordPage::featurePermissionRequested); | ||||||
|  |  | ||||||
|  |   connect(this, &QWebEnginePage::loadStarted, [=]() { | ||||||
|  |     runJavaScript(QString("window.discordScreenaudioVersion = '%1';") | ||||||
|  |                       .arg(QApplication::applicationVersion())); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|   settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true); |   settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true); | ||||||
|   settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true); |   settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true); | ||||||
|   settings()->setAttribute(QWebEngineSettings::AllowRunningInsecureContent, |   settings()->setAttribute(QWebEngineSettings::AllowRunningInsecureContent, | ||||||
| @@ -31,6 +36,7 @@ DiscordPage::DiscordPage(QWidget *parent) : QWebEnginePage(parent) { | |||||||
|   setUrl(QUrl("https://discord.com/app")); |   setUrl(QUrl("https://discord.com/app")); | ||||||
|  |  | ||||||
|   injectScript(":/assets/userscript.js"); |   injectScript(":/assets/userscript.js"); | ||||||
|  |   injectVersion(QApplication::applicationVersion()); | ||||||
|  |  | ||||||
|   connect(&m_streamDialog, &StreamDialog::requestedStreamStart, this, |   connect(&m_streamDialog, &StreamDialog::requestedStreamStart, this, | ||||||
|           &DiscordPage::startStream); |           &DiscordPage::startStream); | ||||||
| @@ -59,6 +65,20 @@ void DiscordPage::injectScript(QString source) { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void DiscordPage::injectVersion(QString version) { | ||||||
|  |   QWebEngineScript script; | ||||||
|  |  | ||||||
|  |   auto code = QString("window.discordScreenaudioVersion = '%1';").arg(version); | ||||||
|  |  | ||||||
|  |   script.setSourceCode(code); | ||||||
|  |   script.setName("version.js"); | ||||||
|  |   script.setWorldId(QWebEngineScript::MainWorld); | ||||||
|  |   script.setInjectionPoint(QWebEngineScript::DocumentCreation); | ||||||
|  |   script.setRunsOnSubFrames(false); | ||||||
|  |  | ||||||
|  |   scripts().insert(script); | ||||||
|  | } | ||||||
|  |  | ||||||
| void DiscordPage::featurePermissionRequested(const QUrl &securityOrigin, | void DiscordPage::featurePermissionRequested(const QUrl &securityOrigin, | ||||||
|                                              QWebEnginePage::Feature feature) { |                                              QWebEnginePage::Feature feature) { | ||||||
|   // Allow every permission asked |   // Allow every permission asked | ||||||
| @@ -78,7 +98,6 @@ void DiscordPage::featurePermissionRequested(const QUrl &securityOrigin, | |||||||
| bool DiscordPage::acceptNavigationRequest(const QUrl &url, | bool DiscordPage::acceptNavigationRequest(const QUrl &url, | ||||||
|                                           QWebEnginePage::NavigationType type, |                                           QWebEnginePage::NavigationType type, | ||||||
|                                           bool isMainFrame) { |                                           bool isMainFrame) { | ||||||
|   qDebug() << url; |  | ||||||
|   if (type == QWebEnginePage::NavigationTypeLinkClicked) { |   if (type == QWebEnginePage::NavigationTypeLinkClicked) { | ||||||
|     QDesktopServices::openUrl(url); |     QDesktopServices::openUrl(url); | ||||||
|     return false; |     return false; | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ private: | |||||||
|                            const QString &message, int lineNumber, |                            const QString &message, int lineNumber, | ||||||
|                            const QString &sourceID) override; |                            const QString &sourceID) override; | ||||||
|   void injectScript(QString source); |   void injectScript(QString source); | ||||||
|  |   void injectVersion(QString version); | ||||||
|   void stopVirtmic(); |   void stopVirtmic(); | ||||||
|   void startVirtmic(QString target); |   void startVirtmic(QString target); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,7 +7,10 @@ | |||||||
| int main(int argc, char *argv[]) { | int main(int argc, char *argv[]) { | ||||||
|   QApplication app(argc, argv); |   QApplication app(argc, argv); | ||||||
|   QApplication::setApplicationName("discord-screenaudio"); |   QApplication::setApplicationName("discord-screenaudio"); | ||||||
|   QApplication::setApplicationVersion("1.0.0-rc.11"); |   QApplication::setWindowIcon( | ||||||
|  |       QIcon(":assets/de.shorsh.discord-screenaudio.png")); | ||||||
|  |   QApplication::setApplicationVersion(DISCORD_SCEENAUDIO_VERSION_FULL); | ||||||
|  |   QApplication::setDesktopFileName("de.shorsh.discord-screenaudio"); | ||||||
|  |  | ||||||
|   QCommandLineParser parser; |   QCommandLineParser parser; | ||||||
|   parser.setApplicationDescription( |   parser.setApplicationDescription( | ||||||
|   | |||||||
| @@ -1,6 +1,10 @@ | |||||||
| #include "mainwindow.h" | #include "mainwindow.h" | ||||||
| #include "virtmic.h" | #include "virtmic.h" | ||||||
|  |  | ||||||
|  | #ifdef KF5NOTIFICATIONS | ||||||
|  | #include <KNotification> | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #include <QApplication> | #include <QApplication> | ||||||
| #include <QColor> | #include <QColor> | ||||||
| #include <QComboBox> | #include <QComboBox> | ||||||
| @@ -11,6 +15,8 @@ | |||||||
| #include <QSpacerItem> | #include <QSpacerItem> | ||||||
| #include <QThread> | #include <QThread> | ||||||
| #include <QUrl> | #include <QUrl> | ||||||
|  | #include <QWebEngineNotification> | ||||||
|  | #include <QWebEngineProfile> | ||||||
| #include <QWebEngineScript> | #include <QWebEngineScript> | ||||||
| #include <QWebEngineScriptCollection> | #include <QWebEngineScriptCollection> | ||||||
| #include <QWebEngineSettings> | #include <QWebEngineSettings> | ||||||
| @@ -30,6 +36,23 @@ void MainWindow::setupWebView() { | |||||||
|   m_webView = new QWebEngineView(this); |   m_webView = new QWebEngineView(this); | ||||||
|   m_webView->setPage(page); |   m_webView->setPage(page); | ||||||
|  |  | ||||||
|  | #ifdef KF5NOTIFICATIONS | ||||||
|  |   QWebEngineProfile::defaultProfile()->setNotificationPresenter( | ||||||
|  |       [&](std::unique_ptr<QWebEngineNotification> notificationInfo) { | ||||||
|  |         KNotification *notification = new KNotification("discordNotification"); | ||||||
|  |         notification->setTitle(notificationInfo->title()); | ||||||
|  |         notification->setText(notificationInfo->message()); | ||||||
|  |         notification->setPixmap(QPixmap::fromImage(notificationInfo->icon())); | ||||||
|  |         notification->setDefaultAction("View"); | ||||||
|  |         connect(notification, &KNotification::defaultActivated, | ||||||
|  |                 [&, notificationInfo = std::move(notificationInfo)]() { | ||||||
|  |                   notificationInfo->click(); | ||||||
|  |                   activateWindow(); | ||||||
|  |                 }); | ||||||
|  |         notification->sendEvent(); | ||||||
|  |       }); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|   setCentralWidget(m_webView); |   setCentralWidget(m_webView); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ StreamDialog::StreamDialog() : QWidget() { | |||||||
|   setAttribute(Qt::WA_QuitOnClose, false); |   setAttribute(Qt::WA_QuitOnClose, false); | ||||||
|  |  | ||||||
|   auto layout = new QVBoxLayout(this); |   auto layout = new QVBoxLayout(this); | ||||||
|  |   layout->setSizeConstraint(QLayout::SetFixedSize); | ||||||
|  |  | ||||||
|   auto targetLabel = new QLabel(this); |   auto targetLabel = new QLabel(this); | ||||||
|   targetLabel->setText("Which app do you want to stream sound from?"); |   targetLabel->setText("Which app do you want to stream sound from?"); | ||||||
| @@ -57,7 +58,6 @@ StreamDialog::StreamDialog() : QWidget() { | |||||||
|   setLayout(layout); |   setLayout(layout); | ||||||
|  |  | ||||||
|   setWindowTitle("discord-screenaudio Stream Dialog"); |   setWindowTitle("discord-screenaudio Stream Dialog"); | ||||||
|   setFixedSize(0, 0); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void StreamDialog::startStream() { | void StreamDialog::startStream() { | ||||||
|   | |||||||
							
								
								
									
										163
									
								
								version.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								version.cmake
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,163 @@ | |||||||
|  | # Copyright (c) 2018-2021 Ribose Inc. | ||||||
|  | # All rights reserved. | ||||||
|  | # | ||||||
|  | # Redistribution and use in source and binary forms, with or without | ||||||
|  | # modification, are permitted provided that the following conditions | ||||||
|  | # are met: | ||||||
|  | # 1. Redistributions of source code must retain the above copyright | ||||||
|  | #    notice, this list of conditions and the following disclaimer. | ||||||
|  | # 2. Redistributions in binary form must reproduce the above copyright | ||||||
|  | #    notice, this list of conditions and the following disclaimer in the | ||||||
|  | #    documentation and/or other materials provided with the distribution. | ||||||
|  | # | ||||||
|  | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||||
|  | # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||||||
|  | # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||||
|  | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS | ||||||
|  | # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||||||
|  | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||||||
|  | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||||||
|  | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||||||
|  | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||||||
|  | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||||
|  | # POSSIBILITY OF SUCH DAMAGE. | ||||||
|  |  | ||||||
|  | # desired length of commit hash | ||||||
|  | set(GIT_REV_LEN 7) | ||||||
|  |  | ||||||
|  | # call git, store output in var (can fail) | ||||||
|  | macro(_git var) | ||||||
|  |   execute_process( | ||||||
|  |     COMMAND "${GIT_EXECUTABLE}" ${ARGN} | ||||||
|  |     WORKING_DIRECTORY "${source_dir}" | ||||||
|  |     RESULT_VARIABLE _git_ec | ||||||
|  |     OUTPUT_VARIABLE ${var} | ||||||
|  |     OUTPUT_STRIP_TRAILING_WHITESPACE | ||||||
|  |     ERROR_QUIET | ||||||
|  |   ) | ||||||
|  | endmacro() | ||||||
|  |  | ||||||
|  | function(extract_version_info version var_prefix) | ||||||
|  |   # extract the main components | ||||||
|  |   #   v1.9.0-3-g5b92266+1546836556 | ||||||
|  |   #   v1.9.0-3-g5b92266-dirty+1546836556 | ||||||
|  |   string(REGEX MATCH "^v?([0-9]+\\.[0-9]+\\.[0-9]+)(-([0-9]+)-g([0-9a-f]+)(-dirty)?)?(\\+([0-9]+))?$" matches "${version}") | ||||||
|  |   if (NOT matches) | ||||||
|  |     message(FATAL_ERROR "Failed to extract version components from ${version}.") | ||||||
|  |   endif() | ||||||
|  |   set(${var_prefix}_VERSION "${CMAKE_MATCH_1}" PARENT_SCOPE) # 1.9.0 | ||||||
|  |   if (NOT CMAKE_MATCH_3) | ||||||
|  |     set(CMAKE_MATCH_3 "0") | ||||||
|  |   endif() | ||||||
|  |   set(${var_prefix}_VERSION_NCOMMITS "${CMAKE_MATCH_3}" PARENT_SCOPE) # 3 | ||||||
|  |   if (NOT CMAKE_MATCH_4) | ||||||
|  |     set(CMAKE_MATCH_4 "0") | ||||||
|  |   endif() | ||||||
|  |   set(${var_prefix}_VERSION_GIT_REV "${CMAKE_MATCH_4}" PARENT_SCOPE) # 5b92266 | ||||||
|  |   if (CMAKE_MATCH_5 STREQUAL "-dirty") | ||||||
|  |     set(${var_prefix}_VERSION_IS_DIRTY TRUE PARENT_SCOPE) | ||||||
|  |   else() | ||||||
|  |     set(${var_prefix}_VERSION_IS_DIRTY FALSE PARENT_SCOPE) | ||||||
|  |   endif() | ||||||
|  |   # timestamp is optional, default to 0 | ||||||
|  |   if (NOT CMAKE_MATCH_7) | ||||||
|  |     set(CMAKE_MATCH_7 "0") | ||||||
|  |   endif() | ||||||
|  |   set(${var_prefix}_VERSION_COMMIT_TIMESTAMP "${CMAKE_MATCH_7}" PARENT_SCOPE) # 1546836556 | ||||||
|  | endfunction() | ||||||
|  |  | ||||||
|  | function(determine_version source_dir var_prefix) | ||||||
|  |   set(has_release_tag NO) | ||||||
|  |   set(has_version_txt NO) | ||||||
|  |   set(local_prefix "_determine_ver") | ||||||
|  |   # find out base version via version.txt | ||||||
|  |   set(base_version "0.0.0") | ||||||
|  |   if (EXISTS "${source_dir}/version.txt") | ||||||
|  |     set(has_version_txt YES) | ||||||
|  |     file(STRINGS "${source_dir}/version.txt" version_file) | ||||||
|  |     extract_version_info("${version_file}" "${local_prefix}") | ||||||
|  |     set(base_version "${${local_prefix}_VERSION}") | ||||||
|  |     message(STATUS "Found version.txt with ${version_file}") | ||||||
|  |   else() | ||||||
|  |     message(STATUS "Found no version.txt.") | ||||||
|  |   endif() | ||||||
|  |   # for GIT_EXECUTABLE | ||||||
|  |   find_package(Git) | ||||||
|  |   # get a description of the version, something like: | ||||||
|  |   #   v1.9.1-0-g38ffe82        (a tagged release) | ||||||
|  |   #   v1.9.1-0-g38ffe82-dirty  (a tagged release with local modifications) | ||||||
|  |   #   v1.9.0-3-g5b92266        (post-release snapshot) | ||||||
|  |   #   v1.9.0-3-g5b92266-dirty  (post-release snapshot with local modifications) | ||||||
|  |   _git(version describe --abbrev=${GIT_REV_LEN} --match "v[0-9]*" --long --dirty) | ||||||
|  |   if (NOT _git_ec EQUAL 0) | ||||||
|  |     # no annotated tags, fake one | ||||||
|  |     message(STATUS "Found no annotated tags.") | ||||||
|  |     _git(revision rev-parse --short=${GIT_REV_LEN} --verify HEAD) | ||||||
|  |     if (_git_ec EQUAL 0) | ||||||
|  |       set(version "v${base_version}-0-g${revision}") | ||||||
|  |       # check if dirty (this won't detect untracked files, but should be ok) | ||||||
|  |       _git(changes diff-index --quiet HEAD --) | ||||||
|  |       if (NOT _git_ec EQUAL 0) | ||||||
|  |         string(APPEND version "-dirty") | ||||||
|  |       endif() | ||||||
|  |       # append the commit timestamp of the most recent commit (only | ||||||
|  |       # in non-release branches -- typically master) | ||||||
|  |       _git(commit_timestamp show -s --format=%ct) | ||||||
|  |       if (_git_ec EQUAL 0) | ||||||
|  |         string(APPEND version "+${commit_timestamp}") | ||||||
|  |       endif() | ||||||
|  |     elseif(has_version_txt) | ||||||
|  |       # Nothing to get from git - so use version.txt completely | ||||||
|  |       set(version "${version_file}") | ||||||
|  |     else() | ||||||
|  |       # Sad case - no git, no version.txt | ||||||
|  |       set(version "v${base_version}") | ||||||
|  |     endif() | ||||||
|  |   else() | ||||||
|  |     set(has_release_tag YES) | ||||||
|  |     message(STATUS "Found annotated tag ${version}") | ||||||
|  |   endif() | ||||||
|  |   extract_version_info("${version}" "${local_prefix}") | ||||||
|  |   if ("${has_version_txt}" AND NOT ${base_version} STREQUAL ${local_prefix}_VERSION) | ||||||
|  |     message(WARNING "Tagged version ${${local_prefix}_VERSION} doesn't match one from the version.txt: ${base_version}") | ||||||
|  |     if (${base_version} VERSION_GREATER ${local_prefix}_VERSION) | ||||||
|  |       set(${local_prefix}_VERSION ${base_version}) | ||||||
|  |     endif() | ||||||
|  |   endif() | ||||||
|  |   foreach(suffix VERSION VERSION_NCOMMITS VERSION_GIT_REV VERSION_IS_DIRTY VERSION_COMMIT_TIMESTAMP) | ||||||
|  |     if (NOT DEFINED ${local_prefix}_${suffix}) | ||||||
|  |       message(FATAL_ERROR "Unable to determine version.") | ||||||
|  |     endif() | ||||||
|  |     set(${var_prefix}_${suffix} "${${local_prefix}_${suffix}}" PARENT_SCOPE) | ||||||
|  |     message(STATUS "${var_prefix}_${suffix}: ${${local_prefix}_${suffix}}") | ||||||
|  |   endforeach() | ||||||
|  |   # Set VERSION_SUFFIX and VERSION_FULL. When making changes, be aware that | ||||||
|  |   # this is used in packaging as well and will affect ordering. | ||||||
|  |   # | state                 | version_full                | | ||||||
|  |   # |-----------------------------------------------------| | ||||||
|  |   # | exact tag             | 0.9.0                       | | ||||||
|  |   # | exact tag, dirty      | 0.9.0+git20180604           | | ||||||
|  |   # | after tag             | 0.9.0+git20180604.1.085039f | | ||||||
|  |   # | no tag, version.txt   | 0.9.0+git20180604.2ee02af   | | ||||||
|  |   # | no tag, no version.txt| 0.0.0+git20180604.2ee02af   | | ||||||
|  |   string(TIMESTAMP date "%Y%m%d" UTC) | ||||||
|  |   set(version_suffix "") | ||||||
|  |   if (NOT ${local_prefix}_VERSION_NCOMMITS EQUAL 0) | ||||||
|  |     # 0.9.0+git20150604.4.289818b | ||||||
|  |     string(APPEND version_suffix "+git${date}.${${local_prefix}_VERSION_NCOMMITS}.${${local_prefix}_VERSION_GIT_REV}") | ||||||
|  |   elseif ((NOT has_release_tag) AND ((NOT has_version_txt) OR ("${base_version}" STREQUAL "0.0.0") OR (NOT "${revision}" STREQUAL ""))) | ||||||
|  |     # 0.9.0+git20150604.289818b | ||||||
|  |     string(APPEND version_suffix "+git${date}.${${local_prefix}_VERSION_GIT_REV}") | ||||||
|  |   elseif(${local_prefix}_VERSION_IS_DIRTY) | ||||||
|  |     # 0.9.0+git20150604 | ||||||
|  |     string(APPEND version_suffix "+git${date}") | ||||||
|  |   endif() | ||||||
|  |   set(version_full "${${local_prefix}_VERSION}${version_suffix}") | ||||||
|  |   # set the results | ||||||
|  |   set(${var_prefix}_VERSION_SUFFIX "${version_suffix}" PARENT_SCOPE) | ||||||
|  |   set(${var_prefix}_VERSION_FULL "${version_full}" PARENT_SCOPE) | ||||||
|  |   # for informational purposes | ||||||
|  |   message(STATUS "${var_prefix}_VERSION_SUFFIX: ${version_suffix}") | ||||||
|  |   message(STATUS "${var_prefix}_VERSION_FULL: ${version_full}") | ||||||
|  | endfunction() | ||||||
|  |  | ||||||
		Reference in New Issue
	
	Block a user