1# Macros/functions for finding QCA's qcatool utility and qca-ossl plugin
2# ~~~~~~~~~~~~~~~~
3# When FIND_QCATOOL is run, will define:
4#
5#   QCATOOL_EXECUTABLE - Path to QCA's qcatool utility
6#
7# NOTE: FIND_QCAOSSL_PLUGIN_CPP requires Qt and QCA packages to be found
8#
9# Copyright (c) 2014, Larry Shaffer, <larrys (at) dakotacarto (dot) com>>
10# Redistribution and use is allowed according to the terms of the BSD license.
11# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
12
13function(FIND_QCAOSSL_PLUGIN_CPP PLUGIN_REQUIRED)
14
15  FIND_PACKAGE(Qt5Core QUIET)
16  # requires Qt and QCA packages to be found
17  if(Qt5Core_INCLUDE_DIRS AND Qt5Core_LIBRARIES
18     AND QCA_INCLUDE_DIR AND QCA_LIBRARY
19     AND NOT CMAKE_CROSSCOMPILING)
20
21    # NOTE: boolean result when compiled executable is run
22    set(CODE
23      "
24      #include <QtCrypto>
25      #include <QCoreApplication>
26
27      int main( int argc, char** argv )
28      {
29        QCA::Initializer init;
30        QCoreApplication app( argc, argv );
31        if ( !QCA::isSupported( \"cert\", \"qca-ossl\" ) )
32        {
33          return 0;
34        }
35        return 1;
36      }
37      "
38    )
39    set(TESTCPP "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/qcaossl.cpp")
40    file(WRITE ${TESTCPP} "${CODE}")
41
42    set(QCA_INCLUDE_DIRECTORIES "-DINCLUDE_DIRECTORIES:STRING=${Qt5Core_INCLUDE_DIRS};${QCA_INCLUDE_DIR}")
43    get_target_property(_QtCore_path Qt5::Core LOCATION)
44    set(QCA_LINK_LIBRARIES "-DLINK_LIBRARIES:STRING=${_QtCore_path};${QCA_LIBRARY}")
45
46    IF ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
47        # qtglobal.h with GCC doesn't like -fPIE added by CMAKE_POSITION_INDEPENDENT_CODE=ON
48        SET(CMAKE_CXX_FLAGS_BACKUP "${CMAKE_CXX_FLAGS}")
49        SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
50        try_run(RUN_RESULT COMPILE_RESULT
51                ${CMAKE_BINARY_DIR} ${TESTCPP}
52                CMAKE_FLAGS "-DCMAKE_CXX_STANDARD=11"
53                            "${QCA_INCLUDE_DIRECTORIES}"
54                            "${QCA_LINK_LIBRARIES}"
55                COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT
56        )
57        SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_BACKUP}")
58    ELSE()
59        try_run(RUN_RESULT COMPILE_RESULT
60            ${CMAKE_BINARY_DIR} ${TESTCPP}
61            CMAKE_FLAGS "-DCMAKE_CXX_STANDARD=11"
62                        "-DCMAKE_POSITION_INDEPENDENT_CODE=ON"
63                        "${QCA_INCLUDE_DIRECTORIES}"
64                        "${QCA_LINK_LIBRARIES}"
65            COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT
66        )
67    ENDIF()
68
69    set(_msg "QCA OpenSSL plugin not found (run-time/unit-test dependency)")
70
71    if(NOT COMPILE_RESULT)
72      message(STATUS "QCA OpenSSL plugin C++ check failed to compile")
73      if(${PLUGIN_REQUIRED})
74        message(STATUS "QCA OpenSSL plugin C++ check compile output:")
75        message(STATUS "${COMPILE_OUTPUT}")
76        message(FATAL_ERROR ${_msg})
77      else()
78        message(STATUS ${_msg})
79      endif()
80    else()
81      if(NOT RUN_RESULT)
82        if(${PLUGIN_REQUIRED})
83          message(FATAL_ERROR ${_msg})
84        else()
85          message(STATUS ${_msg})
86        endif()
87      else()
88        message(STATUS "Found QCA OpenSSL plugin")
89      endif()
90    endif()
91
92  else()
93    message(STATUS "QtCore/QCA include/lib variables missing or CMake is cross-compiling,")
94    message(STATUS "  skipping QCA OpenSSL plugin C++ check")
95  endif()
96
97endfunction(FIND_QCAOSSL_PLUGIN_CPP PLUGIN_REQUIRED)
98
99
100function(FIND_QCATOOL TOOL_REQUIRED)
101  if(NOT QCATOOL_EXECUTABLE)
102
103    if(MSVC)
104      find_program(QCATOOL_EXECUTABLE NAMES qcatool.exe qcatool2.exe
105        PATHS
106          $ENV{LIB_DIR}/bin
107          $ENV{OSGEO4W_ROOT}/bin
108      )
109    else()
110      find_program(QCATOOL_EXECUTABLE NAMES qcatool-qt5 qcatool2 qcatool)
111    endif()
112
113    if(NOT QCATOOL_EXECUTABLE)
114      set(_msg "QCA's qcatool utility not found - aborting")
115      if(${TOOL_REQUIRED})
116        message(FATAL_ERROR ${_msg})
117      else()
118        message(STATUS ${_msg})
119      endif()
120    endif()
121
122  else()
123
124    get_filename_component(_qcatool ${QCATOOL_EXECUTABLE} REALPATH)
125    if(NOT EXISTS "${_qcatool}")
126      set(_msg "QCA's qcatool utility not found at: ${QCATOOL_EXECUTABLE}")
127      if(${TOOL_REQUIRED})
128        message(FATAL_ERROR ${_msg})
129      else()
130        message(STATUS ${_msg})
131      endif()
132    endif()
133
134  endif(NOT QCATOOL_EXECUTABLE)
135
136endfunction(FIND_QCATOOL TOOL_REQUIRED)
137
138
139function(FIND_QCAOSSL_PLUGIN PLUGIN_REQUIRED)
140
141  get_filename_component(_qcatool ${QCATOOL_EXECUTABLE} REALPATH)
142
143  if(EXISTS "${_qcatool}")
144    execute_process(COMMAND "${_qcatool}" plugins OUTPUT_VARIABLE _qca_plugins)
145    # message(STATUS ${_qca_plugins})
146
147    if(NOT "${_qca_plugins}" MATCHES "qca-ossl")
148      set(_msg "QCA OpenSSL plugin not found (run-time/unit-test dependency)")
149      if(${PLUGIN_REQUIRED})
150        message(FATAL_ERROR ${_msg})
151      else()
152        message(STATUS ${_msg})
153      endif()
154    else()
155      message(STATUS "Found QCA OpenSSL plugin")
156    endif()
157  endif()
158
159endfunction(FIND_QCAOSSL_PLUGIN PLUGIN_REQUIRED)
160
161
162function(FIND_QCA_PLUGIN_DIR DIR_REQUIRED)
163
164  FIND_QCATOOL(1)
165  get_filename_component(_qcatool ${QCATOOL_EXECUTABLE} REALPATH)
166
167  if(EXISTS "${_qcatool}")
168    execute_process(COMMAND "${_qcatool}" plugins OUTPUT_VARIABLE _qca_plugins)
169    #message(STATUS ${_qca_plugins})
170    string(REGEX REPLACE "\n" ";" _qca_plugins_list "${_qca_plugins}")
171    #message(STATUS "_qca_plugins_list:  ${_qca_plugins_list}")
172
173    if(NOT "${_qca_plugins}" MATCHES "Available Providers")
174      set(_msg "QCA plugin directory not found")
175      if(${DIR_REQUIRED})
176        message(FATAL_ERROR ${_msg})
177      else()
178        message(STATUS ${_msg})
179      endif()
180    else()
181
182      set(QCA_PLUGIN_DIR)
183      foreach(_plugin_dir ${_qca_plugins_list})
184        string(STRIP "${_plugin_dir}" _plugin_dir)
185        if(EXISTS "${_plugin_dir}" AND IS_DIRECTORY "${_plugin_dir}" AND NOT QCA_PLUGIN_DIR)
186          file(GLOB qca_dylibs "${_plugin_dir}/crypto/libqca*")
187          if(qca_dylibs)
188            set(QCA_PLUGIN_DIR "${_plugin_dir}")
189          endif()
190        endif()
191      endforeach()
192
193      if(QCA_PLUGIN_DIR)
194        set(QCA_PLUGIN_DIR "${QCA_PLUGIN_DIR}" PARENT_SCOPE)
195        message(STATUS "Found QCA plugin directory: ${QCA_PLUGIN_DIR}")
196      else()
197        set(_msg "QCA plugin directory not found")
198        if(${DIR_REQUIRED})
199          message(FATAL_ERROR ${_msg})
200        else()
201          message(STATUS ${_msg})
202        endif()
203      endif()
204
205    endif()
206  endif()
207
208endfunction(FIND_QCA_PLUGIN_DIR DIR_REQUIRED)
209