From 81465e1eec5f469f5e95649c50d0cc0e3f68d79e Mon Sep 17 00:00:00 2001
From: Hennadii Chernyshchyk <genaloner@gmail.com>
Date: Fri, 11 Oct 2019 16:30:11 +0300
Subject: [PATCH] Add CMake support (#66)

* Add CMake support

* Remove unused 'tr()'

* Add option to specify a class for inheritance

* Use modern syntax

* Rework CMakeLists.txt
Thanks to @akallabeth

* Add CMake build rules for examples
---
 .gitignore                                |  1 +
 CMakeLists.txt                            | 43 +++++++++++++++++
 README.md                                 | 18 ++++++--
 examples/basic/CMakeLists.txt             | 15 ++++++
 examples/calculator/CMakeLists.txt        | 20 ++++++++
 examples/calculator/calculator.cpp        | 56 +++++++++++------------
 examples/sending_arguments/CMakeLists.txt | 19 ++++++++
 7 files changed, 141 insertions(+), 31 deletions(-)
 create mode 100644 CMakeLists.txt
 create mode 100644 examples/basic/CMakeLists.txt
 create mode 100644 examples/calculator/CMakeLists.txt
 create mode 100644 examples/sending_arguments/CMakeLists.txt

diff --git a/.gitignore b/.gitignore
index 3adfcc5..ad39075 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@
 /examples/basic/basic
 /examples/calculator/calculator
 /examples/sending_arguments/sending_arguments
+CMakeLists.txt.user
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..d619230
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,43 @@
+cmake_minimum_required(VERSION 3.1.0)
+
+project(SingleApplication)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+set(CMAKE_AUTOMOC ON)
+
+# SingleApplication base class
+set(QAPPLICATION_CLASS QCoreApplication CACHE STRING "Inheritance class for SingleApplication")
+set_property(CACHE QAPPLICATION_CLASS PROPERTY STRINGS QApplication QGuiApplication QCoreApplication)
+
+# Libary target
+add_library(${PROJECT_NAME} STATIC
+    singleapplication.cpp
+    singleapplication_p.cpp
+    )
+
+# Find dependencies
+find_package(Qt5Network)
+if(QAPPLICATION_CLASS STREQUAL QApplication)
+    find_package(Qt5 COMPONENTS Widgets REQUIRED)
+elseif(QAPPLICATION_CLASS STREQUAL QGuiApplication)
+    find_package(Qt5 COMPONENTS Gui REQUIRED)
+else()
+    find_package(Qt5 COMPONENTS Core REQUIRED)
+endif()
+add_compile_definitions(QAPPLICATION_CLASS=${QAPPLICATION_CLASS})
+
+# Link dependencies
+target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Network)
+if(QAPPLICATION_CLASS STREQUAL QApplication)
+    target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Widgets)
+elseif(QAPPLICATION_CLASS STREQUAL QGuiApplication)
+    target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Gui)
+else()
+    target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core)
+endif()
+
+if(WIN32)
+    target_link_libraries(${PROJECT_NAME} PRIVATE advapi32)
+endif()
+
+target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/README.md b/README.md
index 0b1a355..5d60986 100644
--- a/README.md
+++ b/README.md
@@ -50,15 +50,27 @@ how:
 git submodule add git@github.com:itay-grudev/SingleApplication.git singleapplication
 ```
 
-Then include the `singleapplication.pri` file in your `.pro` project file. Also
-don't forget to specify which `QCoreApplication` class your app is using if it
-is not `QCoreApplication`.
+**Qmake:**
+
+Then include the `singleapplication.pri` file in your `.pro` project file.
 
 ```qmake
 include(singleapplication/singleapplication.pri)
 DEFINES += QAPPLICATION_CLASS=QApplication
 ```
 
+**CMake:**
+
+Then include the subdirectory in your `CMakeLists.txt` project file.
+
+```cmake
+set(QAPPLICATION_CLASS QApplication CACHE STRING "Inheritance class for SingleApplication")
+add_subdirectory(src/third-party/singleapplication)
+```
+
+Also don't forget to specify which `QCoreApplication` class your app is using if it
+is not `QCoreApplication` as in examples above.
+
 The `Instance Started` signal
 ------------------------
 
diff --git a/examples/basic/CMakeLists.txt b/examples/basic/CMakeLists.txt
new file mode 100644
index 0000000..4f1902b
--- /dev/null
+++ b/examples/basic/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.1.0)
+
+project(basic)
+
+# SingleApplication base class
+set(QAPPLICATION_CLASS QCoreApplication CACHE STRING "Inheritance class for SingleApplication")
+
+add_executable(basic
+    main.cpp
+    )
+
+find_package(Qt5 COMPONENTS Core REQUIRED)
+add_subdirectory(../.. SingleApplication)
+target_link_libraries(${PROJECT_NAME} Qt5::Core SingleApplication)
+
diff --git a/examples/calculator/CMakeLists.txt b/examples/calculator/CMakeLists.txt
new file mode 100644
index 0000000..c90257a
--- /dev/null
+++ b/examples/calculator/CMakeLists.txt
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 3.1.0)
+
+project(calculator)
+
+set(CMAKE_AUTOMOC ON)
+
+# SingleApplication base class
+set(QAPPLICATION_CLASS QApplication CACHE STRING "Inheritance class for SingleApplication")
+
+add_executable(${PROJECT_NAME}
+    button.h
+    calculator.h
+    button.cpp
+    calculator.cpp
+    main.cpp
+    )
+
+find_package(Qt5 COMPONENTS Widgets REQUIRED)
+add_subdirectory(../.. SingleApplication)
+target_link_libraries(${PROJECT_NAME} Qt5::Widgets SingleApplication)
diff --git a/examples/calculator/calculator.cpp b/examples/calculator/calculator.cpp
index c02b560..3d34c2a 100644
--- a/examples/calculator/calculator.cpp
+++ b/examples/calculator/calculator.cpp
@@ -82,27 +82,27 @@ Calculator::Calculator(QWidget *parent)
         digitButtons[i] = createButton(QString::number(i), SLOT(digitClicked()));
     }
 
-    Button *pointButton = createButton(tr("."), SLOT(pointClicked()));
-    Button *changeSignButton = createButton(tr("\302\261"), SLOT(changeSignClicked()));
+    Button *pointButton = createButton(".", SLOT(pointClicked()));
+    Button *changeSignButton = createButton("\302\261", SLOT(changeSignClicked()));
 
-    Button *backspaceButton = createButton(tr("Backspace"), SLOT(backspaceClicked()));
-    Button *clearButton = createButton(tr("Clear"), SLOT(clear()));
-    Button *clearAllButton = createButton(tr("Clear All"), SLOT(clearAll()));
+    Button *backspaceButton = createButton("Backspace", SLOT(backspaceClicked()));
+    Button *clearButton = createButton("Clear", SLOT(clear()));
+    Button *clearAllButton = createButton("Clear All", SLOT(clearAll()));
 
-    Button *clearMemoryButton = createButton(tr("MC"), SLOT(clearMemory()));
-    Button *readMemoryButton = createButton(tr("MR"), SLOT(readMemory()));
-    Button *setMemoryButton = createButton(tr("MS"), SLOT(setMemory()));
-    Button *addToMemoryButton = createButton(tr("M+"), SLOT(addToMemory()));
+    Button *clearMemoryButton = createButton("MC", SLOT(clearMemory()));
+    Button *readMemoryButton = createButton("MR", SLOT(readMemory()));
+    Button *setMemoryButton = createButton("MS", SLOT(setMemory()));
+    Button *addToMemoryButton = createButton("M+", SLOT(addToMemory()));
 
-    Button *divisionButton = createButton(tr("\303\267"), SLOT(multiplicativeOperatorClicked()));
-    Button *timesButton = createButton(tr("\303\227"), SLOT(multiplicativeOperatorClicked()));
-    Button *minusButton = createButton(tr("-"), SLOT(additiveOperatorClicked()));
-    Button *plusButton = createButton(tr("+"), SLOT(additiveOperatorClicked()));
+    Button *divisionButton = createButton("\303\267", SLOT(multiplicativeOperatorClicked()));
+    Button *timesButton = createButton("\303\227", SLOT(multiplicativeOperatorClicked()));
+    Button *minusButton = createButton("-", SLOT(additiveOperatorClicked()));
+    Button *plusButton = createButton("+", SLOT(additiveOperatorClicked()));
 
-    Button *squareRootButton = createButton(tr("Sqrt"), SLOT(unaryOperatorClicked()));
-    Button *powerButton = createButton(tr("x\302\262"), SLOT(unaryOperatorClicked()));
-    Button *reciprocalButton = createButton(tr("1/x"), SLOT(unaryOperatorClicked()));
-    Button *equalButton = createButton(tr("="), SLOT(equalClicked()));
+    Button *squareRootButton = createButton("Sqrt", SLOT(unaryOperatorClicked()));
+    Button *powerButton = createButton("x\302\262", SLOT(unaryOperatorClicked()));
+    Button *reciprocalButton = createButton("1/x", SLOT(unaryOperatorClicked()));
+    Button *equalButton = createButton("=", SLOT(equalClicked()));
 //! [4]
 
 //! [5]
@@ -140,7 +140,7 @@ Calculator::Calculator(QWidget *parent)
     mainLayout->addWidget(equalButton, 5, 5);
     setLayout(mainLayout);
 
-    setWindowTitle(tr("Calculator"));
+    setWindowTitle("Calculator");
 }
 //! [6]
 
@@ -169,15 +169,15 @@ void Calculator::unaryOperatorClicked()
     double operand = display->text().toDouble();
     double result = 0.0;
 
-    if (clickedOperator == tr("Sqrt")) {
+    if (clickedOperator == "Sqrt") {
         if (operand < 0.0) {
             abortOperation();
             return;
         }
         result = std::sqrt(operand);
-    } else if (clickedOperator == tr("x\302\262")) {
+    } else if (clickedOperator == "x\302\262") {
         result = std::pow(operand, 2.0);
-    } else if (clickedOperator == tr("1/x")) {
+    } else if (clickedOperator == "1/x") {
         if (operand == 0.0) {
             abortOperation();
             return;
@@ -287,7 +287,7 @@ void Calculator::pointClicked()
     if (waitingForOperand)
         display->setText("0");
     if (!display->text().contains('.'))
-        display->setText(display->text() + tr("."));
+        display->setText(display->text() + ".");
     waitingForOperand = false;
 }
 //! [22]
@@ -299,7 +299,7 @@ void Calculator::changeSignClicked()
     double value = text.toDouble();
 
     if (value > 0.0) {
-        text.prepend(tr("-"));
+        text.prepend("-");
     } else if (value < 0.0) {
         text.remove(0, 1);
     }
@@ -383,20 +383,20 @@ Button *Calculator::createButton(const QString &text, const char *member)
 void Calculator::abortOperation()
 {
     clearAll();
-    display->setText(tr("####"));
+    display->setText("####");
 }
 //! [36]
 
 //! [38]
 bool Calculator::calculate(double rightOperand, const QString &pendingOperator)
 {
-    if (pendingOperator == tr("+")) {
+    if (pendingOperator == "+") {
         sumSoFar += rightOperand;
-    } else if (pendingOperator == tr("-")) {
+    } else if (pendingOperator == "-") {
         sumSoFar -= rightOperand;
-    } else if (pendingOperator == tr("\303\227")) {
+    } else if (pendingOperator == "\303\227") {
         factorSoFar *= rightOperand;
-    } else if (pendingOperator == tr("\303\267")) {
+    } else if (pendingOperator == "\303\267") {
         if (rightOperand == 0.0)
             return false;
         factorSoFar /= rightOperand;
diff --git a/examples/sending_arguments/CMakeLists.txt b/examples/sending_arguments/CMakeLists.txt
new file mode 100644
index 0000000..bfdc5cc
--- /dev/null
+++ b/examples/sending_arguments/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.1.0)
+
+project(sending_arguments)
+
+set(CMAKE_AUTOMOC ON)
+
+# SingleApplication base class
+set(QAPPLICATION_CLASS QCoreApplication CACHE STRING "Inheritance class for SingleApplication")
+
+add_executable(${PROJECT_NAME}
+    main.cpp
+    messagereceiver.cpp
+    messagereceiver.h
+    main.cpp
+    )
+
+find_package(Qt5 COMPONENTS Core REQUIRED)
+add_subdirectory(../.. SingleApplication)
+target_link_libraries(${PROJECT_NAME} Qt5::Core SingleApplication)