Can't Install Toolkit in a CMake Project

304
3
Jump to solution
03-26-2024 10:44 AM
Labels (1)
Paige
by
New Contributor II

I am trying to install the ArcGIS Toolkit so that I can use Popups in my application. I have cloned the repo and am now trying to follow the instructions in uitools/README.md so that I can create a PopupStackView in QML.

However, my project uses CMake. The Toolkit only provides qmake files for installation (toolkitcpp.pri, toolkitqml.pri, toolkitwidgets.pri). If I add the suggested path for the Toolkit qmake file to my CMakeLists.txt:

include(uitools/toolkitcpp.pri)

Then I will receive an error when I build the application:

CMake Error at uitools/toolkitcpp.pri:16:
  Parse error.  Expected "(", got unquoted argument with text "+=".
Call Stack (most recent call first):
  src/CMakeLists.txt:72 (include)

This is because CMake is trying to parse the .pri file as if it is written in CMake, even though it is written in qmake. How do I work around this? I'd prefer not to manually rewrite the .pri file in CMake, because then any future changes to toolkitcpp.pri would have to be manually reflected in my personal rewritten file.

Also, are there any future plans to provide a CMake alternative to the .pri files in the Toolkit?

0 Kudos
1 Solution

Accepted Solutions
LucasDanzinger
Esri Frequent Contributor

@Paige - we don't have CMake support in the toolkit right now. Another request was logged here https://github.com/Esri/arcgis-maps-sdk-toolkit-qt/issues/602. We are looking at adding support in an upcoming release. In the meantime (it's admittedly not a great solution) but you might be able to build up your own CMakeLists.txt based on the existing qmake PRI. 

View solution in original post

3 Replies
LucasDanzinger
Esri Frequent Contributor

@Paige - we don't have CMake support in the toolkit right now. Another request was logged here https://github.com/Esri/arcgis-maps-sdk-toolkit-qt/issues/602. We are looking at adding support in an upcoming release. In the meantime (it's admittedly not a great solution) but you might be able to build up your own CMakeLists.txt based on the existing qmake PRI. 

Paige
by
New Contributor II

Ah, okay. I was afraid of that answer, but I'm not entirely surprised. Thanks for the link to the related question and the speedy response!

0 Kudos
Paige
by
New Contributor II


For anybody else who encounters this in the future, here's the CMakeLists.txt I created to clone the Toolkit repository and run the commands listed in toolkitcpp.pri:

# Install ArcGIS Qt Tookit
# https://github.com/Esri/arcgis-maps-sdk-toolkit-qt

cmake_minimum_required(VERSION 3.5)

include(ExternalProject)

# Clone ArcGISToolkit repository
# This command requires Git 1.6.5 or greater
ExternalProject_Add(ArcGISToolkit_Repo
  SOURCE_DIR ${CMAKE_SOURCE_DIR}/ArcGISToolkit
  GIT_REPOSITORY https://github.com/Esri/arcgis-maps-sdk-toolkit-qt.git
  GIT_TAG main
  GIT_SHALLOW ON # Avoids cloning all history; instead, just clones the most recent commit

  # Avoid performing any configuration, build, or installation commands
  CONFIGURE_COMMAND ""
  BUILD_COMMAND ""
  INSTALL_COMMAND ""
)


#[[
# The following is a line-by-line translation of toolkitcpp.pri (a qmake configuration file for the Toolkit's uitools directory)
# and common.pri (another qmake configuration file that toolkitcpp.pri depends on) into CMake
# https://github.com/Esri/arcgis-maps-sdk-toolkit-qt/blob/3a04ab203a930ac42364c3cc2e507fcd882b62c8/uitools/toolkitcpp.pri
# https://github.com/Esri/arcgis-maps-sdk-toolkit-qt/blob/3a04ab203a930ac42364c3cc2e507fcd882b62c8/uitools/common.pri
#
# This is necessary because ArcGIS currently only provides qmake configuration files for their toolkit,
# but CMake has no support for processing qmake files:
# https://community.esri.com/t5/qt-maps-sdk-questions/can-t-install-toolkit-in-a-cmake-project/m-p/1401031#M5187
#]]

    # ----- TOOLKITCPP.PRI -----
    set(PWD ${CMAKE_SOURCE_DIR}/ArcGISToolkit/uitools)

    #[[ QMAKE: include($$PWD/common.pri)]]
        # ----- COMMON.PRI -----

        #[[ QMAKE: CPPPATH = $$PWD/cpp/Esri/ArcGISRuntime/Toolkit]]
        set(CPPPATH ${PWD}/cpp/Esri/ArcGISRuntime/Toolkit)

        #[[ QMAKE: INCLUDEPATH += $$PWD/cpp $$CPPPATH]]
        include_directories(${PWD}/cpp ${CPPPATH})

        #[[ QMAKE: HEADERS += <all the header files>]]
        set(HEADERS ${CPPPATH}/AuthenticationController.h
            ${CPPPATH}/BasemapGalleryController.h
            ${CPPPATH}/BasemapGalleryItem.h
            ${CPPPATH}/BookmarksViewController.h
            ${CPPPATH}/BookmarkListItem.h
            ${CPPPATH}/CoordinateConversionConstants.h
            ${CPPPATH}/CoordinateConversionController.h
            ${CPPPATH}/CoordinateConversionOption.h
            ${CPPPATH}/CoordinateConversionResult.h
            ${CPPPATH}/CoordinateOptionDefaults.h
            ${CPPPATH}/FloorFilterController.h
            ${CPPPATH}/FloorFilterFacilityItem.h
            ${CPPPATH}/FloorFilterLevelItem.h
            ${CPPPATH}/FloorFilterSiteItem.h
            ${CPPPATH}/LocatorSearchSource.h
            ${CPPPATH}/Internal/BasemapGalleryImageProvider.h
            ${CPPPATH}/Internal/DisconnectOnSignal.h
            ${CPPPATH}/Internal/DoOnLoad.h
            ${CPPPATH}/Internal/GenericListModel.h
            ${CPPPATH}/Internal/GenericTableProxyModel.h
            ${CPPPATH}/Internal/GeoViews.h
            ${CPPPATH}/Internal/MetaElement.h
            ${CPPPATH}/Internal/SingleShotConnection.h
            ${CPPPATH}/NorthArrowController.h
            ${CPPPATH}/OverviewMapController.h
            ${CPPPATH}/PopupViewController.h
            ${CPPPATH}/ScalebarController.h
            ${CPPPATH}/SearchResult.h
            ${CPPPATH}/SearchSourceInterface.h
            ${CPPPATH}/SearchSuggestion.h
            ${CPPPATH}/SearchViewController.h
            ${CPPPATH}/SmartLocatorSearchSource.h
            ${CPPPATH}/TimeSliderController.h
            ${CPPPATH}/UtilityNetworkFunctionTraceResult.h
            ${CPPPATH}/UtilityNetworkFunctionTraceResultsModel.h
            ${CPPPATH}/UtilityNetworkListItem.h
            ${CPPPATH}/UtilityNetworkTraceController.h
            ${CPPPATH}/UtilityNetworkTraceStartingPoint.h
            ${CPPPATH}/UtilityNetworkTraceStartingPointsModel.h)

        #[[ QMAKE: SOURCES += <all the cpp files>]]
        set(SOURCES ${CPPPATH}/AuthenticationController.cpp
            ${CPPPATH}/BasemapGalleryController.cpp
            ${CPPPATH}/BasemapGalleryItem.cpp
            ${CPPPATH}/BookmarksViewController.cpp
            ${CPPPATH}/BookmarkListItem.cpp
            ${CPPPATH}/CoordinateConversionConstants.cpp
            ${CPPPATH}/CoordinateConversionController.cpp
            ${CPPPATH}/CoordinateConversionOption.cpp
            ${CPPPATH}/CoordinateConversionResult.cpp
            ${CPPPATH}/CoordinateOptionDefaults.cpp
            ${CPPPATH}/FloorFilterController.cpp
            ${CPPPATH}/FloorFilterFacilityItem.cpp
            ${CPPPATH}/FloorFilterLevelItem.cpp
            ${CPPPATH}/FloorFilterSiteItem.cpp
            ${CPPPATH}/LocatorSearchSource.cpp
            ${CPPPATH}/Internal/BasemapGalleryImageProvider.cpp
            ${CPPPATH}/Internal/GenericListModel.cpp
            ${CPPPATH}/Internal/GenericTableProxyModel.cpp
            ${CPPPATH}/Internal/MetaElement.cpp
            ${CPPPATH}/NorthArrowController.cpp
            ${CPPPATH}/OverviewMapController.cpp
            ${CPPPATH}/PopupViewController.cpp
            ${CPPPATH}/ScalebarController.cpp
            ${CPPPATH}/SearchResult.cpp
            ${CPPPATH}/SearchSourceInterface.cpp
            ${CPPPATH}/SearchSuggestion.cpp
            ${CPPPATH}/SearchViewController.cpp
            ${CPPPATH}/SmartLocatorSearchSource.cpp
            ${CPPPATH}/TimeSliderController.cpp
            ${CPPPATH}/UtilityNetworkFunctionTraceResult.cpp
            ${CPPPATH}/UtilityNetworkFunctionTraceResultsModel.cpp
            ${CPPPATH}/UtilityNetworkListItem.cpp
            ${CPPPATH}/UtilityNetworkTraceController.cpp
            ${CPPPATH}/UtilityNetworkTraceStartingPoint.cpp
            ${CPPPATH}/UtilityNetworkTraceStartingPointsModel.cpp)
        # ----- end of COMMON.PRI -----

    #[[ QMAKE: QT += quickcontrols2 webview svg]]
    find_package(Qt6 COMPONENTS QuickControls2 WebView Svg)

    #[[ QMAKE: REGISTERPATH = $$PWD/register/Esri/ArcGISRuntime/Toolkit]]
    set(REGISTERPATH ${PWD}/register/Esri/ArcGISRuntime/Toolkit)

    #[[ QMAKE: INCLUDEPATH += $$PWD/register $$REGISTERPATH]]
    include_directories(${PWD}/register ${REGISTERPATH})

    #[[ QMAKE: HEADERS += $$REGISTERPATH/register.h \
               $$REGISTERPATH/internal/register_cpp.h]]
    list(APPEND HEADERS ${REGISTERPATH}/register.h
        ${REGISTERPATH}/internal/register_cpp.h)

    #[[ QMAKE: SOURCES += $$REGISTERPATH/register.cpp \
               $$REGISTERPATH/internal/register_cpp.cpp]]
    list(APPEND HEADERS ${REGISTERPATH}/register.cpp
        ${REGISTERPATH}/internal/register_cpp.cpp)

    #[[ QMAKE: RESOURCES += \
      $$PWD/images/esri_arcgisruntime_toolkit_images.qrc \
      $$PWD/import/Esri/ArcGISRuntime/Toolkit/esri_arcgisruntime_toolkit_view.qrc]]
    set (RESOURCE_FILES
        ${PWD}/images/esri_arcgisruntime_toolkit_images.qrc
        ${PWD}/import/Esri/ArcGISRuntime/Toolkit/esri_arcgisruntime_toolkit_view.qrc
    )

    #[[ QMAKE: QML_IMPORT_PATH += $$PWD/import]]
    set(QML_IMPORT_PATH ${PWD}/import CACHE STRING "" FORCE)

    #[[ QMAKE: DEFINES += CPP_ARCGISRUNTIME_TOOLKIT]]
    add_definitions(-DCPP_ARCGISRUNTIME_TOOLKIT)

    # Expose the QML directory's path so that it can be added to the import path in src/main.cpp
    add_definitions(-DArcGISRuntime_Toolkit_Qml_DIR="${PWD}/import")

    # These commands are run implicitly as part of the qmake commands above
    qt_add_library(ArcGISToolkit STATIC ${HEADERS} ${SOURCES} ${RESOURCE_FILES})
    target_link_libraries(ArcGISToolkit PRIVATE
        Qt6::Quick
        Qt6::QuickControls2
        Qt6::WebView
        Qt6::Svg
        ArcGISRuntime::Cpp)

    # ----- end of TOOLKITCPP.PRI -----

Say I needed the Toolkit to be installed in dir1, and the above file's path is dir1/dir2/CMakeLists.txt Then I would just add an include() statement to dir1/CMakeLists.txt to run the above file:

include(dir2/CMakeLists.txt)
Tags (2)