1
votes

I want to compile Qt Qml Plugin using CMake (instead of QMake) and add this plugin to the some application. Plugin and application script should be in separate CMakeLists.txt.

File structure:

CMakeLists.txt
main.cpp
main.qml
qml.qrc
plugin/
    CMakeLists.txt
    MyItem.cpp
    MyItem.h
    Plugin.h
    qmldir

I have a script plugin/CMakeLists.txt that generates libmyplugin.dylib and qmldir and put it to the plugin/MyPlugin subfolder of plugin binary dir:

plugin/CMakeLists.txt:

cmake_minimum_required(VERSION 3.8)

add_library(myplugin SHARED
    Item.cpp
    Item.h
    Plugin.h
)

set_target_properties(myplugin PROPERTIES
    AUTOMOC TRUE
    LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/package/MyPlugin
)

# Copy qmldir file
add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/package/MyPlugin/qmldir
    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/qmldir
    COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/qmldir" "${CMAKE_CURRENT_BINARY_DIR}/package/MyPlugin/qmldir"
    COMMENT "Copy qmldir"
)
target_sources(myplugin PRIVATE
    ${CMAKE_CURRENT_BINARY_DIR}/package/MyPlugin/qmldir
)

find_package(Qt5 REQUIRED COMPONENTS Core Qml Quick)
target_link_libraries(viewWorld PUBLIC Qt5::Core Qt5::Qml Qt5::Quick)

Now I need to build myplugin target before/after app target and copy plugin files from <myplugin binary dir>/plugin into location of app target binary (in case of Windows and Linux) or into <app bundle>/Contents/PlugIns (in case of macOS):

CMakeLists.txt:

cmake_minimum_required(VERSION 3.8)

add_executable(app
    main.cpp
    qml.qrc
)

set_target_properties(app PROPERTIES
    AUTORCC TRUE
)

add_subdirectory(plugin)
add_dependencies(app plugin)
# Needs to copy plugin files...

find_package(Qt5 REQUIRED COMPONENTS Core Qml Quick)
target_link_libraries(viewWorld PUBLIC Qt5::Core Qt5::Qml Qt5::Quick)

I need to copy plugin files only if they changed. It would be great to write function that will take app target and plugin target and create appropriate dependencies.

1

1 Answers

2
votes

For my Qt projects and qml plugins I using next rules. It's actual for win platform, but I hope it will be helpfull for your macOS

Output directory is same for all projects:

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

So all sub_directories with CMakeLists and it's project targets will build into same directory. It's helpfull for project running and finnaly deploying.

Qml plugins I copy to directory

set_target_properties(targetProject PROPERTIES
   RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/$<CONFIG>/plugins/${QmlPluginName}/)

After build qml plugin I'm copy qmldir file to RUNTIME_OUTPUT_DIRECTORY

add_custom_command(TARGET ${targetProject} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy
    ${QML_DIR_FILE}
    ${CMAKE_BINARY_DIR}/bin/$<CONFIG>/plugins/${QmlPluginName}/qmldir)

After this steps I had hext directory structure:

/build_dir/bin/Debug/
           |application.exe
           |plugins/
           | |QmlPluginName/
           | | |qmldir
           | | |QmlPluginName.dll

So after this steps don't forget about:

QQmlApplicationEngine engine;
engine.addImportPath("./plugins");    

P.S. sorry for my English