From 32b2e24fb6a8aedec244f15255fc40c922f3b478 Mon Sep 17 00:00:00 2001
From: Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
Date: Wed, 12 Oct 2022 22:54:03 +0200
Subject: [PATCH] src/CMakeLists.txt: Support building as shared library (as
 one would need for packaging a DEB package).

Signed-off-by: Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
---
 src/CMakeLists.txt | 69 ++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 61 insertions(+), 8 deletions(-)

--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,6 +1,30 @@
 cmake_minimum_required(VERSION 3.3)
 project(QZXing)
 
+option(BUILD_SHARED "Build as shared library" OFF)
+
+if(BUILD_SHARED)
+    SET(SOVERSION_MAJOR 3)
+    SET(SOVERSION_MINOR 3)
+    SET(SOVERSION_PATCH 0)
+
+    OPTION(QZXING_MULTIMEDIA "" OFF)
+    OPTION(QZXING_USE_QML "" OFF)
+    OPTION(QZXING_USE_ENCODER "" OFF)
+    OPTION(QZXING_MULTIMEDIA "" OFF)
+    OPTION(QZXING_USE_QML "" OFF)
+    OPTION(QZXING_USE_ENCODER "" OFF)
+    OPTION(QZXING_USE_DECODER_QR_CODE "" OFF)
+    OPTION(QZXING_USE_DECODER_1D_BARCODES "" OFF)
+    OPTION(QZXING_USE_DECODER_DATA_MATRIX "" OFF)
+    OPTION(QZXING_USE_DECODER_AZTEC "" OFF)
+    OPTION(QZXING_USE_DECODER_PDF17 "" OFF)
+    OPTION(QZXING_USE_DECODER_1D_BARCODES "" OFF)
+
+    include (GNUInstallDirs)
+
+endif()
+
 find_package(Qt5 COMPONENTS Core REQUIRED)
 find_package(Qt5 COMPONENTS Gui REQUIRED)
 find_package(Qt5 COMPONENTS Multimedia )
@@ -13,6 +37,11 @@
 set(CMAKE_AUTOMOC ON)
 set(CMAKE_WARN_ON)
 
+set(PUBLIC_HEADERS
+    QZXing.h
+    QZXing_global.h
+)
+
 set(SOURCES
 
     CameraImageWrapper.cpp
@@ -20,13 +49,13 @@
     ImageHandler.cpp
     ImageHandler.h
     QZXing.cpp
-    QZXing.h
-    QZXing_global.h
+    ${PUBLIC_HEADERS}
     )
 
 if(QZXING_MULTIMEDIA)
 
     LIST(APPEND SOURCES QZXingFilter.cpp QZXingFilter.h)
+    LIST(APPEND PUBLIC_HEADERS QZXingFilter.h)
     add_definitions(-DQZXING_MULTIMEDIA)
 
     SET(QZXING_USE_QML ON)
@@ -35,6 +64,7 @@
 
 if(QZXING_USE_QML)
     LIST(APPEND SOURCES QZXingImageProvider.cpp QZXingImageProvider.h)
+    LIST(APPEND PUBLIC_HEADERS QZXingImageProvider.h)
     add_definitions(-DQZXING_QML)
 endif(QZXING_USE_QML)
 
@@ -42,7 +72,16 @@
     add_definitions(-DENABLE_ENCODER_GENERIC -DENABLE_ENCODER_QR_CODE)
 endif(QZXING_USE_ENCODER)
 
-add_library(qzxing "" ${SOURCES})
+if(BUILD_SHARED)
+    add_library(qzxing SHARED ${SOURCES})
+    set_target_properties(qzxing
+        PROPERTIES
+        VERSION ${SOVERSION_MAJOR}.${SOVERSION_MINOR}.${SOVERSION_PATCH}
+        SOVERSION ${SOVERSION_MAJOR}
+)
+else()
+    add_library(qzxing "" ${SOURCES})
+endif()
 
 if(WIN32)
     add_subdirectory(zxing/win32)
@@ -78,6 +117,15 @@
         Qt5::Quick
         Qt5::QuickControls2)
     target_compile_definitions(qzxing PUBLIC -DQZXING_QML)
+
+    if(BUILD_SHARED)
+        # copy qmldir file to build dir so QML unit tests can use it to import the plugin
+        configure_file(
+            qmldir.in
+            qmldir
+        )
+    endif()
+
 endif(QZXING_USE_QML)
 
 if(QZXING_USE_ENCODER)
@@ -108,9 +156,10 @@
     target_compile_definitions(qzxing PRIVATE -DENABLE_DECODER_1D_BARCODES)
 endif()
 
-
-# Change Global Definitions depending on how you want to use the library
-target_compile_definitions(qzxing PUBLIC DISABLE_LIBRARY_FEATURES)
+if(!BUILD_SHARED)
+    # Change Global Definitions depending on how you want to use the library
+    target_compile_definitions(qzxing PUBLIC DISABLE_LIBRARY_FEATURES)
+endif()
 
 # Target includes
 target_include_directories(qzxing
@@ -120,7 +169,39 @@
         zxing/win32/zxing
         zxing/zxing
         zxing/bigint
-    PUBLIC
-    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+  PUBLIC
+        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
 )
 
+if(BUILD_SHARED)
+
+    set(QZXING_INSTALL_TARGETS qzxing)
+
+    install (
+        TARGETS ${QZXING_INSTALL_TARGETS} EXPORT QZXingTargets
+        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    )
+
+    install (
+        FILES ${PUBLIC_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/qzxing"
+    )
+
+    # Qt5's cmake does not export QT_IMPORTS_DIR, lets query qmake on our own for now
+    get_target_property(QMAKE_EXECUTABLE Qt5::qmake LOCATION)
+    function(QUERY_QMAKE VAR RESULT)
+      exec_program(${QMAKE_EXECUTABLE} ARGS "-query ${VAR}" RETURN_VALUE return_code OUTPUT_VARIABLE output )
+      if(NOT return_code)
+        file(TO_CMAKE_PATH "${output}" output)
+        set(${RESULT} ${output} PARENT_SCOPE)
+      endif(NOT return_code)
+    endfunction(QUERY_QMAKE)
+    query_qmake(QT_INSTALL_QML QT_IMPORTS_DIR)
+
+    if(QZXING_USE_QML)
+        set(PLUGIN_DIR ${QT_IMPORTS_DIR}/QZXing)
+        install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qmldir DESTINATION ${PLUGIN_DIR})
+    endif()
+
+endif()
--- /dev/null
+++ b/src/qmldir.in
@@ -0,0 +1,2 @@
+module QZXing
+plugin qzxing @CMAKE_INSTALL_FULL_LIBDIR@
