CMakeLists.txt 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. #############################################################
  2. # CMake settings
  3. cmake_minimum_required(VERSION 3.5)
  4. cmake_policy(SET CMP0071 NEW)
  5. cmake_policy(SET CMP0074 NEW)
  6. cmake_policy(SET CMP0077 NEW)
  7. cmake_policy(SET CMP0087 NEW)
  8. set(QML_IMPORT_PATH ${CMAKE_SOURCE_DIR}/src/qml/imports CACHE PATH "QML import path for Qt Creator to detect custom modules properly")
  9. set(CMAKE_COLOR_MAKEFILE ON)
  10. set(APP_NAME "VRA Helper" CACHE STRING "Application Name")
  11. set(APK_VERSION_CODE "1" CACHE STRING "Apk Version Code (Example: 1)")
  12. set(APP_VERSION "" CACHE STRING "Application Version (Example: 1.0.0)")
  13. set(APP_VERSION_STR "local - dev" CACHE STRING "Application Version Name (Example: 1.0.0 - Homerun)")
  14. set(APP_PACKAGE_NAME "vrahelper" CACHE STRING "Package name suffix. E.g. qfield --> ch.opengis.qfield")
  15. string(REGEX REPLACE "v" "" CLEAN_APP_VERSION "${APP_VERSION}")
  16. set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
  17. include(GetGitRevisionDescription)
  18. set(VCPKG_APPLOCAL_DEPS ON)
  19. set(X_VCPKG_APPLOCAL_DEPS_INSTALL ON)
  20. project(${APP_NAME}
  21. VERSION ${CLEAN_APP_VERSION}
  22. )
  23. GET_GIT_HEAD_REVISION(GIT_REFSPEC GIT_REV)
  24. add_definitions(-DAPP_NAME="${APP_NAME}")
  25. add_definitions(-DAPP_VERSION="${APP_VERSION}")
  26. add_definitions(-DAPP_VERSION_STR="${APP_VERSION_STR}")
  27. add_definitions(-DGIT_REV="${GIT_REV}")
  28. set(DEFAULT_BIN_SUBDIR bin)
  29. set(DEFAULT_CGIBIN_SUBDIR bin)
  30. set(DEFAULT_LIB_SUBDIR lib${LIB_SUFFIX})
  31. set(DEFAULT_INCLUDE_SUBDIR include/qfield)
  32. set(QFIELD_BIN_SUBDIR ${DEFAULT_BIN_SUBDIR} CACHE STRING "Subdirectory where executables will be installed")
  33. set(QFIELD_LIB_SUBDIR ${DEFAULT_LIB_SUBDIR} CACHE STRING "Subdirectory where libraries will be installed")
  34. set(QFIELD_INCLUDE_SUBDIR ${DEFAULT_INCLUDE_SUBDIR} CACHE STRING "Subdirectory where header files will be installed")
  35. set(WITH_VCPKG OFF CACHE BOOL "Build with vcpkg packaging layout")
  36. set(USE_MAC_BUNDLING NOT ${WITH_VCPKG} CACHE BOOL "Use mac bundling")
  37. set(RELATIVE_PREFIX_PATH ${WITH_VCPKG} CACHE BOOL "Use a prefix path relative to the application itself rather than hard coding the path while compiling")
  38. if(RELATIVE_PREFIX_PATH)
  39. add_definitions(-DRELATIVE_PREFIX_PATH)
  40. endif()
  41. mark_as_advanced (QFIELD_INCLUDE_SUBDIR QFIELD_BIN_SUBDIR QFIELD_LIB_SUBDIR WITH_VCPKG USE_MAC_BUNDLING)
  42. set(QFIELD_BIN_DIR ${QFIELD_BIN_SUBDIR})
  43. set(QFIELD_LIB_DIR ${QFIELD_LIB_SUBDIR})
  44. set(QFIELD_INCLUDE_DIR ${QFIELD_INCLUDE_SUBDIR})
  45. set(QT_ANDROID_APPLICATION_BINARY "qfield")
  46. # set the default locations where the targets (executables, libraries) will land when compiled
  47. # this is to allow running QField directly from the build directory.
  48. if (ANDROID)
  49. set(QFIELD_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/android-build)
  50. else()
  51. set(QFIELD_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output)
  52. endif()
  53. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${QFIELD_OUTPUT_DIRECTORY}/${QFIELD_BIN_SUBDIR}/$<0:>)
  54. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${QFIELD_OUTPUT_DIRECTORY}/${QFIELD_LIB_SUBDIR}/$<0:>)
  55. install(DIRECTORY ${CMAKE_SOURCE_DIR}/resources DESTINATION share/qfield)
  56. set(WITH_SPIX FALSE CACHE STRING "Compile with Spix for testing")
  57. if (WITH_SPIX)
  58. find_package(Spix)
  59. endif ()
  60. if (ANDROID)
  61. # This is necessary in order for CMake to be able to detect libraries in OSGeo4A
  62. list(APPEND CMAKE_FIND_ROOT_PATH /)
  63. add_definitions(-DQGIS_INSTALL_DIR="") # TODO: do we need osgeo4a/[lib]/files here? see qgis.pri
  64. # Android SDK stuff
  65. set(ANDROID_TARGET_PLATFORM CACHE INT "Target Android platform SDK version")
  66. set(ANDROID_PLATFORM 21 CACHE INT "Minimum Android platform SDK version")
  67. set(ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_SOURCE_DIR}/android)
  68. # Paths relevant to OSGeo4A
  69. set(OSGEO4A_STAGE_DIR NONE CACHE PATH "OSGeo4A stage path (base path without architecture)")
  70. set(OSGEO4A_LIB_DIR ${OSGEO4A_STAGE_DIR}/${ANDROID_ABI}/lib)
  71. # Extra libraries to be copied after building
  72. list(APPEND ANDROID_EXTRA_LIBS
  73. ${OSGEO4A_LIB_DIR}/libssl_1_1.so
  74. ${OSGEO4A_LIB_DIR}/libcrypto_1_1.so
  75. ${OSGEO4A_LIB_DIR}/libexpat.so
  76. ${OSGEO4A_LIB_DIR}/libgeos.so
  77. ${OSGEO4A_LIB_DIR}/libgeos_c.so
  78. ${OSGEO4A_LIB_DIR}/libgslcblas.so
  79. ${OSGEO4A_LIB_DIR}/libsqlite3.so
  80. ${OSGEO4A_LIB_DIR}/libcharset.so
  81. ${OSGEO4A_LIB_DIR}/libexiv2.so
  82. ${OSGEO4A_LIB_DIR}/libiconv.so
  83. ${OSGEO4A_LIB_DIR}/libopenjp2.so
  84. ${OSGEO4A_LIB_DIR}/libfreexl.so
  85. ${OSGEO4A_LIB_DIR}/libtiff.so
  86. ${OSGEO4A_LIB_DIR}/libpng16.so
  87. ${OSGEO4A_LIB_DIR}/libgdal.so
  88. ${OSGEO4A_LIB_DIR}/libproj.so
  89. ${OSGEO4A_LIB_DIR}/libspatialindex.so
  90. ${OSGEO4A_LIB_DIR}/libpq.so
  91. ${OSGEO4A_LIB_DIR}/libspatialite.so
  92. ${OSGEO4A_LIB_DIR}/libgsl.so
  93. ${OSGEO4A_LIB_DIR}/libgslcblas.so
  94. ${OSGEO4A_LIB_DIR}/libqca-qt5_${ANDROID_ABI}.so
  95. ${OSGEO4A_LIB_DIR}/libqgis_core_${ANDROID_ABI}.so
  96. ${OSGEO4A_LIB_DIR}/libqgis_analysis_${ANDROID_ABI}.so
  97. ${OSGEO4A_LIB_DIR}/libqgis_native_${ANDROID_ABI}.so
  98. ${OSGEO4A_LIB_DIR}/libqt5keychain_${ANDROID_ABI}.so
  99. ${OSGEO4A_LIB_DIR}/libzip.so
  100. ${OSGEO4A_LIB_DIR}/libzstd.so
  101. ${OSGEO4A_LIB_DIR}/libpoppler_${ANDROID_ABI}.so
  102. ${OSGEO4A_LIB_DIR}/libfreetype.so
  103. )
  104. find_package(Qt5 COMPONENTS AndroidExtras REQUIRED)
  105. configure_file(cmake/generated.xml.in ${CMAKE_SOURCE_DIR}/android/res/values/generated.xml @ONLY)
  106. configure_file(cmake/AndroidManifest.xml.in ${CMAKE_SOURCE_DIR}/android/AndroidManifest.xml @ONLY)
  107. include(CreateZip)
  108. file(GLOB PLUGINS_QGIS_PROVIDERS
  109. ${OSGEO4A_LIB_DIR}/*provider*.so
  110. )
  111. file(GLOB PLUGINS_QGIS_AUTHMETHODS
  112. ${OSGEO4A_LIB_DIR}/*authmethod*.so
  113. )
  114. set(SHARE_PATH "${CMAKE_CURRENT_BINARY_DIR}/android-build/assets/share")
  115. file(COPY ${PLUGINS_QGIS_PROVIDERS} DESTINATION "${SHARE_PATH}/plugins/")
  116. file(COPY ${PLUGINS_QGIS_AUTHMETHODS} DESTINATION "${SHARE_PATH}/plugins/")
  117. file(COPY "${OSGEO4A_LIB_DIR}/qca-qt5/crypto/" DESTINATION "${SHARE_PATH}/plugins/crypto/")
  118. file(COPY "${OSGEO4A_STAGE_DIR}/${ANDROID_ABI}/share/proj/" DESTINATION "${SHARE_PATH}/proj/")
  119. file(COPY "${OSGEO4A_STAGE_DIR}/${ANDROID_ABI}/files/share/svg/" DESTINATION "${SHARE_PATH}/qgis/svg/")
  120. file(COPY "${OSGEO4A_STAGE_DIR}/${ANDROID_ABI}/files/share/resources/" DESTINATION "${SHARE_PATH}/qgis/resources/")
  121. # Strip libs to save space
  122. file(GLOB_RECURSE PLUGINS_LIBS
  123. ${SHARE_PATH}/plugins/*.so
  124. )
  125. foreach(PLUGINS_LIB IN LISTS PLUGINS_LIBS)
  126. if(ANDROID_ABI STREQUAL "x86")
  127. EXECUTE_PROCESS(COMMAND "${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android-strip" "${PLUGINS_LIB}")
  128. elseif(ANDROID_ABI STREQUAL "x86_64")
  129. EXECUTE_PROCESS(COMMAND "${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android-strip" "${PLUGINS_LIB}")
  130. elseif(ANDROID_ABI STREQUAL "armeabi-v7a")
  131. EXECUTE_PROCESS(COMMAND "${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/arm-linux-android-strip" "${PLUGINS_LIB}")
  132. elseif(ANDROID_ABI STREQUAL "arm64-v8a")
  133. EXECUTE_PROCESS(COMMAND "${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-strip" "${PLUGINS_LIB}")
  134. endif()
  135. endforeach()
  136. # Remove world map to keep apk size a bit smaller
  137. file(REMOVE "${SHARE_PATH}/qgis/resources/data/world_map.gpkg")
  138. file(COPY resources/ DESTINATION "${SHARE_PATH}/qfield/")
  139. # We use GDAL in OSGeo4A instead
  140. set(ENV{GDAL_ROOT} ${OSGEO4A_STAGE_DIR}/${ANDROID_ABI})
  141. # Don't do tests when building for Android
  142. set(ENABLE_TESTS FALSE)
  143. endif()
  144. set(QT_MIN_VERSION 5.14.0)
  145. find_package(Qt5 COMPONENTS Concurrent Core Qml Gui Xml Positioning Widgets Network Quick Svg OpenGL Sql Sensors WebView Bluetooth Multimedia REQUIRED)
  146. # PrintSupport isn't required, because it doesn't exist for ios
  147. # qgis will deal with it an define a public 'QT_NO_PRINTER'
  148. find_package(Qt5 COMPONENTS PrintSupport QUIET)
  149. find_package(QGIS REQUIRED)
  150. if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "iOS")
  151. find_package(Proj)
  152. find_package(GDAL)
  153. endif()
  154. find_package(QCA)
  155. find_package(QtKeychain)
  156. if (${CMAKE_SYSTEM_NAME} STREQUAL "iOS")
  157. add_definitions(-DQT_NO_PRINTER)
  158. set(SHARE_PATH "${CMAKE_CURRENT_BINARY_DIR}/share")
  159. # keep trailing slash for QField to rename the directory (instead of copying in subdir)
  160. file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/resources/ DESTINATION ${SHARE_PATH}/qfield)
  161. file(COPY ${QGIS_APPLE_RESOURCES_DIR}/resources DESTINATION ${SHARE_PATH}/qgis)
  162. file(COPY ${QGIS_APPLE_RESOURCES_DIR}/svg DESTINATION ${SHARE_PATH}/qgis)
  163. file(COPY ${QFIELD_PROJ_DIR} DESTINATION ${SHARE_PATH})
  164. # Remove world map to keep apk size a bit smaller
  165. file(REMOVE "${SHARE_PATH}/qgis/resources/data/world_map.gpkg")
  166. set(QFIELD_RESOURCE_FILES ${SHARE_PATH})
  167. endif()
  168. set(ENABLE_TESTS CACHE BOOL "Build unit tests")
  169. if(MSVC)
  170. find_package(Qt5 COMPONENTS Charts REQUIRED) # vcpkg doesn't include QtCharts.dll as dep of the qml module otherwise
  171. add_definitions(-D_USE_MATH_DEFINES)
  172. add_definitions(-DNOMINMAX)
  173. add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
  174. endif()
  175. add_subdirectory(3rdparty/tessellate)
  176. add_subdirectory(src/core)
  177. add_subdirectory(src/app)
  178. if (ENABLE_TESTS)
  179. find_package(Qt5 COMPONENTS Test QuickTest)
  180. enable_testing()
  181. add_subdirectory(test)
  182. endif()
  183. if(WITH_VCPKG)
  184. SET(VCPKG_BASE_DIR "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}")
  185. if(MSVC)
  186. SET(QGIS_PLUGIN_DIR "${VCPKG_BASE_DIR}/tools/qgis/plugins")
  187. file(GLOB PROVIDER_LIBS
  188. "${QGIS_PLUGIN_DIR}/*provider*.dll"
  189. )
  190. file(GLOB AUTHMETHODS_LIBS
  191. "${QGIS_PLUGIN_DIR}/*authmethod*.dll"
  192. )
  193. # From QGIS CMakeLists.txt
  194. set(QGIS_PLUGIN_INSTALL_PREFIX "plugins")
  195. else()
  196. SET(QGIS_PLUGIN_DIR "${VCPKG_BASE_DIR}/lib/qgis/plugins")
  197. file(GLOB PROVIDER_LIBS
  198. "${QGIS_PLUGIN_DIR}/*provider*.so"
  199. )
  200. file(GLOB AUTHMETHODS_LIBS
  201. "${QGIS_PLUGIN_DIR}/*authmethod*.so"
  202. )
  203. # From QGIS CMakeLists.txt
  204. set(QGIS_PLUGIN_INSTALL_PREFIX "lib${LIB_SUFFIX}/qgis/plugins")
  205. endif()
  206. add_custom_target(deploy)
  207. add_custom_command(TARGET deploy
  208. POST_BUILD
  209. COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/output/bin/qgis/plugins"
  210. )
  211. foreach(LIB ${PROVIDER_LIBS})
  212. add_custom_command(TARGET deploy
  213. POST_BUILD
  214. COMMAND ${CMAKE_COMMAND} -E copy_if_different "${LIB}" "${CMAKE_BINARY_DIR}/output/bin/qgis/plugins"
  215. )
  216. install(FILES "${LIB}" DESTINATION "${QGIS_PLUGIN_INSTALL_PREFIX}")
  217. endforeach()
  218. foreach(LIB ${AUTHMETHODS_LIBS})
  219. add_custom_command(TARGET deploy
  220. POST_BUILD
  221. COMMAND ${CMAKE_COMMAND} -E copy_if_different "${LIB}" "${CMAKE_BINARY_DIR}/output/bin/qgis/plugins"
  222. )
  223. endforeach()
  224. add_custom_command(TARGET deploy
  225. POST_BUILD
  226. COMMAND ${CMAKE_COMMAND} -E copy_directory "${VCPKG_BASE_DIR}/share/qgis/resources" "${CMAKE_BINARY_DIR}/output/bin/qgis/resources"
  227. )
  228. add_custom_command(TARGET deploy
  229. POST_BUILD
  230. COMMAND ${CMAKE_COMMAND} -E copy_directory "${VCPKG_BASE_DIR}/share/proj4" "${CMAKE_BINARY_DIR}/output/bin/proj"
  231. )
  232. add_custom_command(TARGET deploy
  233. POST_BUILD
  234. COMMAND ${CMAKE_COMMAND} -E copy_directory "${VCPKG_BASE_DIR}/share/gdal" "${CMAKE_BINARY_DIR}/output/bin/gdal"
  235. )
  236. install(DIRECTORY "${VCPKG_BASE_DIR}/share/qgis/resources/" DESTINATION "share/qgis/resources")
  237. install(DIRECTORY "${VCPKG_BASE_DIR}/share/proj4/" DESTINATION "share/proj")
  238. install(DIRECTORY "${VCPKG_BASE_DIR}/share/gdal/" DESTINATION "share/gdal")
  239. if(EXISTS ${VCPKG_BASE_DIR}/plugins/mediaservice)
  240. add_custom_command(TARGET deploy
  241. POST_BUILD
  242. COMMAND ${CMAKE_COMMAND} -E copy_directory "${VCPKG_BASE_DIR}/plugins/mediaservice" "${CMAKE_BINARY_DIR}/output/bin/plugins/mediaservice"
  243. )
  244. install(DIRECTORY "${VCPKG_BASE_DIR}/plugins/mediaservice/" DESTINATION "bin/plugins/mediaservice")
  245. endif()
  246. add_dependencies(qfield deploy)
  247. endif()
  248. if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
  249. install(FILES ${CMAKE_SOURCE_DIR}/images/icons/qfield_logo.svg DESTINATION share/icons RENAME qfield.svg)
  250. install(FILES ${CMAKE_SOURCE_DIR}/platform/linux/qfield.desktop DESTINATION share/qfield)
  251. endif()
  252. include(Package)