From fd663cc02183f430c53e95d5a2a788afc97a8b68 Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Sat, 22 Jun 2024 13:37:53 +0200 Subject: [PATCH 1/2] [plugins] Remove dependency on pyuic Eases plugin development and deployment --- CMakeLists.txt | 1 - cmake/PyQtMacros.cmake | 98 ------------------- python/console/CMakeLists.txt | 12 ++- python/console/console_compile_apis.py | 5 +- python/console/console_settings.py | 6 +- python/plugins/db_manager/CMakeLists.txt | 2 +- .../postgis/plugins/versioning/CMakeLists.txt | 3 +- .../plugins/versioning/dlg_versioning.py | 7 +- python/pyplugin_installer/CMakeLists.txt | 11 +-- .../qgsplugindependenciesdialog.py | 7 +- .../qgsplugininstallerfetchingdialog.py | 5 +- .../qgsplugininstallerinstallingdialog.py | 6 +- .../qgsplugininstallerpluginerrordialog.py | 6 +- .../qgsplugininstallerrepositorydialog.py | 5 +- 14 files changed, 50 insertions(+), 124 deletions(-) delete mode 100644 cmake/PyQtMacros.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index c9953597a6b..f90c6b733cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1103,7 +1103,6 @@ if (WITH_CORE AND WITH_BINDINGS) find_package(Qsci REQUIRED) include(PythonMacros) - include(PyQtMacros) include(SIPMacros) set(SIP_INCLUDES ${PYQT_SIP_DIR} ${CMAKE_SOURCE_DIR}/python) diff --git a/cmake/PyQtMacros.cmake b/cmake/PyQtMacros.cmake deleted file mode 100644 index 9a2fe0df7c8..00000000000 --- a/cmake/PyQtMacros.cmake +++ /dev/null @@ -1,98 +0,0 @@ -# Macros for PyQt -# ~~~~~~~~~~~~~~~~ -# Copyright (c) 2009, Juergen E. Fischer -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -IF(BUILD_WITH_QT6) - SET(PYUIC_PROG_NAME pyuic6) - SET(PYUIC_PROG_NAMES pyuic6) -ELSE() - SET(PYUIC_PROG_NAME pyuic5) - SET(PYUIC_PROG_NAMES pyuic5) - SET(PYRCC_PROG_NAME pyrcc5) -ENDIF() - -IF(NOT PYUIC_PROGRAM) - FIND_PROGRAM(PYUIC_PROGRAM NAMES ${PYUIC_PROG_NAMES} PATHS $ENV{LIB_DIR}/bin) - IF (NOT PYUIC_PROGRAM) - MESSAGE(FATAL_ERROR "pyuic5 not found - aborting") - ENDIF (NOT PYUIC_PROGRAM) -ENDIF(NOT PYUIC_PROGRAM) - -# Adapted from QT4_WRAP_UI -MACRO(PYQT_WRAP_UI outfiles ) - SET(PYUIC_WRAPPER_OUTPUT_DIRECTORY "${PYTHON_OUTPUT_DIRECTORY}") - SET(PYUIC_WRAPPER_PYTHON_EXECUTABLE "${Python_EXECUTABLE}") - IF(CMAKE_HOST_WIN32) - IF(USING_NINJA OR USING_NMAKE) - SET(PYUIC_WRAPPER "${CMAKE_SOURCE_DIR}/scripts/pyuic_wrapper.bat") - SET(PYUIC_WRAPPER_PATH "${QGIS_OUTPUT_DIRECTORY}/bin") - ELSE(USING_NINJA OR USING_NMAKE) - SET(PYUIC_WRAPPER "${CMAKE_SOURCE_DIR}/scripts/pyuic_wrapper.bat") - SET(PYUIC_WRAPPER_PATH "${QGIS_OUTPUT_DIRECTORY}/bin/${CMAKE_BUILD_TYPE}") - ENDIF(USING_NINJA OR USING_NMAKE) - ELSEIF(MINGW) - # Clear all variables to invoke PYUIC_PROGRAM directly - SET(PYUIC_WRAPPER_OUTPUT_DIRECTORY "") - SET(PYUIC_WRAPPER_PYTHON_EXECUTABLE "") - ELSE() - # TODO osx - SET(PYUIC_WRAPPER "${CMAKE_SOURCE_DIR}/scripts/pyuic_wrapper.sh") - SET(PYUIC_WRAPPER_PATH "${QGIS_OUTPUT_DIRECTORY}/lib${LIB_SUFFIX}") - ENDIF() - - FOREACH(it ${ARGN}) - GET_FILENAME_COMPONENT(outfile ${it} NAME_WE) - GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE) - SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/ui_${outfile}.py) - ADD_CUSTOM_COMMAND(OUTPUT ${outfile} - COMMAND ${PYUIC_WRAPPER} "${PYUIC_PROGRAM}" "${PYUIC_WRAPPER_PATH}" "${PYUIC_WRAPPER_OUTPUT_DIRECTORY}" "${PYUIC_WRAPPER_PYTHON_EXECUTABLE}" ${infile} -o ${outfile} - MAIN_DEPENDENCY ${infile} - DEPENDS pygui pycore pyqtcompat - ) - SET(${outfiles} ${${outfiles}} ${outfile}) - ENDFOREACH(it) -ENDMACRO(PYQT_WRAP_UI) - -IF(NOT PYRCC_PROGRAM AND NOT BUILD_WITH_QT6) - FIND_PROGRAM(PYRCC_PROGRAM NAMES ${PYRCC_PROG_NAME} PATHS $ENV{LIB_DIR}/bin) - IF (NOT PYRCC_PROGRAM) - MESSAGE(FATAL_ERROR "pyrcc5 not found - aborting") - ENDIF (NOT PYRCC_PROGRAM) -ENDIF(NOT PYRCC_PROGRAM AND NOT BUILD_WITH_QT6) - -# Adapted from QT4_ADD_RESOURCES -MACRO (PYQT_ADD_RESOURCES outfiles ) - FOREACH (it ${ARGN}) - GET_FILENAME_COMPONENT(outfile ${it} NAME_WE) - GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE) - GET_FILENAME_COMPONENT(rc_path ${infile} PATH) - SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/${outfile}_rc.py) - # parse file for dependencies - # all files are absolute paths or relative to the location of the qrc file - FILE(READ "${infile}" _RC_FILE_CONTENTS) - STRING(REGEX MATCHALL "]*>" "" _RC_FILE "${_RC_FILE}") - STRING(REGEX MATCH "^/|([A-Za-z]:/)" _ABS_PATH_INDICATOR "${_RC_FILE}") - IF(NOT _ABS_PATH_INDICATOR) - SET(_RC_FILE "${rc_path}/${_RC_FILE}") - ENDIF(NOT _ABS_PATH_INDICATOR) - SET(_RC_DEPENDS ${_RC_DEPENDS} "${_RC_FILE}") - ENDFOREACH(_RC_FILE) - IF (BUILD_WITH_QT6) - ADD_CUSTOM_COMMAND(OUTPUT ${outfile} - COMMAND Qt6::rcc -g python -o ${outfile} ${infile} - MAIN_DEPENDENCY ${infile} - DEPENDS ${_RC_DEPENDS}) - ELSE() - ADD_CUSTOM_COMMAND(OUTPUT ${outfile} - COMMAND ${PYRCC_PROGRAM} ${_name_opt} -o ${outfile} ${infile} - MAIN_DEPENDENCY ${infile} - DEPENDS ${_RC_DEPENDS}) - ENDIF() - SET(${outfiles} ${${outfiles}} ${outfile}) - ENDFOREACH (it) -ENDMACRO (PYQT_ADD_RESOURCES) diff --git a/python/console/CMakeLists.txt b/python/console/CMakeLists.txt index 365b4b1d6d4..5cfd44bb89d 100644 --- a/python/console/CMakeLists.txt +++ b/python/console/CMakeLists.txt @@ -11,11 +11,13 @@ set(PY_CONSOLE_FILES __init__.py ) -file(GLOB UI_FILES *.ui) -PYQT_WRAP_UI(PYUI_FILES ${UI_FILES}) -add_custom_target(pyconsole ALL DEPENDS ${PYUI_FILES}) +set(UI_FILES + console_compile_apis.ui + console_settings.ui) -foreach(pyfile ${PY_CONSOLE_FILES} ${PYUI_FILES}) +add_custom_target(pyconsole ALL) + +foreach(pyfile ${PY_CONSOLE_FILES}) add_custom_command(TARGET pyconsole POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${PYTHON_OUTPUT_DIRECTORY}/console @@ -26,5 +28,5 @@ foreach(pyfile ${PY_CONSOLE_FILES} ${PYUI_FILES}) endforeach(pyfile) PY_COMPILE(pyconsole "${PYTHON_OUTPUT_DIRECTORY}/console") -install(FILES ${PY_CONSOLE_FILES} ${PYUI_FILES} DESTINATION "${QGIS_CONSOLE_DIR}") +install(FILES ${PY_CONSOLE_FILES} ${UI_FILES} DESTINATION "${QGIS_CONSOLE_DIR}") diff --git a/python/console/console_compile_apis.py b/python/console/console_compile_apis.py index 32204bb4ebc..9ea869646b3 100644 --- a/python/console/console_compile_apis.py +++ b/python/console/console_compile_apis.py @@ -20,11 +20,14 @@ Portions of this file contain code from Eric4 APIsManager module. import os +from pathlib import Path + +from qgis.PyQt import uic from qgis.PyQt.Qsci import QsciAPIs, QsciLexerPython from qgis.PyQt.QtWidgets import QDialog, QDialogButtonBox from qgis.PyQt.QtCore import QCoreApplication -from .ui_console_compile_apis import Ui_APIsDialogPythonConsole +Ui_APIsDialogPythonConsole, _ = uic.loadUiType(Path(__file__).parent / 'console_compile_apis.ui') class PrepareAPIDialog(QDialog): diff --git a/python/console/console_settings.py b/python/console/console_settings.py index 5c9e2b08e7e..1f1533be77b 100644 --- a/python/console/console_settings.py +++ b/python/console/console_settings.py @@ -18,6 +18,9 @@ email : lrssvtml (at) gmail (dot) com Some portions of code were taken from https://code.google.com/p/pydee/ """ +from pathlib import Path + +from qgis.PyQt import uic from qgis.PyQt.QtCore import QCoreApplication, QUrl from qgis.PyQt.QtWidgets import QWidget, QFileDialog, QMessageBox, QTableWidgetItem, QHBoxLayout from qgis.PyQt.QtGui import QIcon, QDesktopServices @@ -26,7 +29,8 @@ from qgis.core import QgsSettings, QgsApplication, QgsSettingsTree from qgis.gui import QgsOptionsPageWidget, QgsOptionsWidgetFactory from .console_compile_apis import PrepareAPIDialog -from .ui_console_settings import Ui_SettingsDialogPythonConsole + +Ui_SettingsDialogPythonConsole, _ = uic.loadUiType(Path(__file__).parent / 'console_settings.ui') class ConsoleOptionsFactory(QgsOptionsWidgetFactory): diff --git a/python/plugins/db_manager/CMakeLists.txt b/python/plugins/db_manager/CMakeLists.txt index 88bcb3ba26d..b586a9c2bed 100644 --- a/python/plugins/db_manager/CMakeLists.txt +++ b/python/plugins/db_manager/CMakeLists.txt @@ -6,5 +6,5 @@ file(GLOB PY_FILES *.py) file(GLOB UI_FILES ui/*.ui) -PLUGIN_INSTALL(db_manager . ${OTHER_FILES} ${PY_FILES} ${PYRC_FILES} metadata.txt) +PLUGIN_INSTALL(db_manager . ${OTHER_FILES} ${PY_FILES} metadata.txt) PLUGIN_INSTALL(db_manager ui ${UI_FILES}) diff --git a/python/plugins/db_manager/db_plugins/postgis/plugins/versioning/CMakeLists.txt b/python/plugins/db_manager/db_plugins/postgis/plugins/versioning/CMakeLists.txt index 5008de62c76..eeecf9c2514 100644 --- a/python/plugins/db_manager/db_plugins/postgis/plugins/versioning/CMakeLists.txt +++ b/python/plugins/db_manager/db_plugins/postgis/plugins/versioning/CMakeLists.txt @@ -1,4 +1,3 @@ file(GLOB PY_FILES *.py) file(GLOB UI_FILES *.ui) -PYQT_WRAP_UI(PYUI_FILES ${UI_FILES}) -PLUGIN_INSTALL(db_manager db_plugins/postgis/plugins/versioning ${PY_FILES} ${PYUI_FILES}) +PLUGIN_INSTALL(db_manager db_plugins/postgis/plugins/versioning ${PY_FILES} ${UI_FILES}) diff --git a/python/plugins/db_manager/db_plugins/postgis/plugins/versioning/dlg_versioning.py b/python/plugins/db_manager/db_plugins/postgis/plugins/versioning/dlg_versioning.py index 34962af3ce6..41813bcb35a 100644 --- a/python/plugins/db_manager/db_plugins/postgis/plugins/versioning/dlg_versioning.py +++ b/python/plugins/db_manager/db_plugins/postgis/plugins/versioning/dlg_versioning.py @@ -19,14 +19,17 @@ Based on PG_Manager by Martin Dobias (GPLv2 license) ***************************************************************************/ """ +from pathlib import Path + +from qgis.PyQt import uic from qgis.PyQt.QtCore import Qt from qgis.PyQt.QtWidgets import QDialog, QDialogButtonBox, QMessageBox, QApplication -from .ui_DlgVersioning import Ui_DlgVersioning - from .....dlg_db_error import DlgDbError from ....plugin import BaseError, Table +Ui_DlgVersioning, _ = uic.loadUiType(Path(__file__).parent / 'DlgVersioining.ui') + class DlgVersioning(QDialog, Ui_DlgVersioning): diff --git a/python/pyplugin_installer/CMakeLists.txt b/python/pyplugin_installer/CMakeLists.txt index 2dafd1b4c5b..e12b77959dc 100644 --- a/python/pyplugin_installer/CMakeLists.txt +++ b/python/pyplugin_installer/CMakeLists.txt @@ -14,10 +14,7 @@ set(PY_PLUGININSTALLER_FILES version_compare.py ) -# file(GLOB UI_FILES *.ui) -# PYQT_WRAP_UI(PYUI_FILES ${UI_FILES}) - -PYQT_WRAP_UI(PYUI_FILES +set(UI_FILES qgsplugininstallerfetchingbase.ui qgsplugininstallerinstallingbase.ui qgsplugininstallerpluginerrorbase.ui @@ -25,7 +22,7 @@ PYQT_WRAP_UI(PYUI_FILES qgsplugindependenciesdialogbase.ui ) -add_custom_target(pyplugin-installer ALL DEPENDS ${PYUI_FILES}) +add_custom_target(pyplugin-installer ALL) add_custom_command(TARGET pyplugin-installer POST_BUILD @@ -33,7 +30,7 @@ add_custom_command(TARGET pyplugin-installer WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) -foreach(pyfile ${PY_PLUGININSTALLER_FILES} ${PYUI_FILES}) +foreach(pyfile ${PY_PLUGININSTALLER_FILES}) add_custom_command(TARGET pyplugin-installer POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${pyfile} ${PYTHON_OUTPUT_DIRECTORY}/pyplugin_installer @@ -43,4 +40,4 @@ foreach(pyfile ${PY_PLUGININSTALLER_FILES} ${PYUI_FILES}) endforeach(pyfile) PY_COMPILE(pyplugin-installer "${PYTHON_OUTPUT_DIRECTORY}/pyplugin_installer") -install(FILES ${PY_PLUGININSTALLER_FILES} ${PYUI_FILES} DESTINATION "${QGIS_PLUGININSTALLER_DIR}") +install(FILES ${PY_PLUGININSTALLER_FILES} ${UI_FILES} DESTINATION "${QGIS_PLUGININSTALLER_DIR}") diff --git a/python/pyplugin_installer/qgsplugindependenciesdialog.py b/python/pyplugin_installer/qgsplugindependenciesdialog.py index fc5fa75ef20..ff13fbdeebd 100644 --- a/python/pyplugin_installer/qgsplugindependenciesdialog.py +++ b/python/pyplugin_installer/qgsplugindependenciesdialog.py @@ -12,13 +12,16 @@ __author__ = 'elpaso@itopen.it' __date__ = '2018-09-19' __copyright__ = 'Copyright 2018, GISCE-TI S.L.' - import os +from pathlib import Path + +from qgis.PyQt import uic from qgis.PyQt import QtWidgets, QtCore -from .ui_qgsplugindependenciesdialogbase import Ui_QgsPluginDependenciesDialogBase from qgis.utils import iface +Ui_QgsPluginDependenciesDialogBase, _ = uic.loadUiType(Path(__file__).parent / 'qgsplugindependenciesdialogbase.ui') + class QgsPluginDependenciesDialog(QtWidgets.QDialog, Ui_QgsPluginDependenciesDialogBase): """A dialog that shows plugin dependencies and offers a way to install or upgrade the diff --git a/python/pyplugin_installer/qgsplugininstallerfetchingdialog.py b/python/pyplugin_installer/qgsplugininstallerfetchingdialog.py index c904db94239..c38e15b64cf 100644 --- a/python/pyplugin_installer/qgsplugininstallerfetchingdialog.py +++ b/python/pyplugin_installer/qgsplugininstallerfetchingdialog.py @@ -24,13 +24,16 @@ ***************************************************************************/ """ +from pathlib import Path + +from qgis.PyQt import uic from qgis.PyQt.QtCore import Qt, QCoreApplication from qgis.PyQt.QtWidgets import QDialog, QTreeWidgetItem -from .ui_qgsplugininstallerfetchingbase import Ui_QgsPluginInstallerFetchingDialogBase from .installer_data import repositories from qgis.gui import QgsGui +Ui_QgsPluginInstallerFetchingDialogBase, _ = uic.loadUiType(Path(__file__).parent / 'qgsplugininstallerfetchingbase.ui') class QgsPluginInstallerFetchingDialog(QDialog, Ui_QgsPluginInstallerFetchingDialogBase): diff --git a/python/pyplugin_installer/qgsplugininstallerinstallingdialog.py b/python/pyplugin_installer/qgsplugininstallerinstallingdialog.py index fd741981983..d82c26d29dc 100644 --- a/python/pyplugin_installer/qgsplugininstallerinstallingdialog.py +++ b/python/pyplugin_installer/qgsplugininstallerinstallingdialog.py @@ -25,6 +25,9 @@ """ from builtins import str +from pathlib import Path + +from qgis.PyQt import uic from qgis.PyQt.QtCore import QDir, QUrl, QFile, QCoreApplication from qgis.PyQt.QtWidgets import QDialog from qgis.PyQt.QtNetwork import QNetworkRequest, QNetworkReply @@ -32,10 +35,11 @@ from qgis.PyQt.QtNetwork import QNetworkRequest, QNetworkReply from qgis.core import QgsNetworkAccessManager, QgsApplication, QgsNetworkRequestParameters from qgis.utils import HOME_PLUGIN_PATH -from .ui_qgsplugininstallerinstallingbase import Ui_QgsPluginInstallerInstallingDialogBase from .installer_data import removeDir, repositories from .unzip import unzip +Ui_QgsPluginInstallerInstallingDialogBase, _ = uic.loadUiType(Path(__file__).parent / 'qgsplugininstallerinstallingbase.ui') + class QgsPluginInstallerInstallingDialog(QDialog, Ui_QgsPluginInstallerInstallingDialogBase): # ----------------------------------------- # diff --git a/python/pyplugin_installer/qgsplugininstallerpluginerrordialog.py b/python/pyplugin_installer/qgsplugininstallerpluginerrordialog.py index 011d9c3442f..76f635969ba 100644 --- a/python/pyplugin_installer/qgsplugininstallerpluginerrordialog.py +++ b/python/pyplugin_installer/qgsplugininstallerpluginerrordialog.py @@ -26,7 +26,11 @@ from qgis.PyQt.QtWidgets import QDialog -from .ui_qgsplugininstallerpluginerrorbase import Ui_QgsPluginInstallerPluginErrorDialogBase +from pathlib import Path + +from qgis.PyQt import uic + +Ui_QgsPluginInstallerPluginErrorDialogBase, _ = uic.loadUiType(Path(__file__).parent / 'qgsplugininstallerpluginerrorbase.ui') class QgsPluginInstallerPluginErrorDialog(QDialog, Ui_QgsPluginInstallerPluginErrorDialogBase): diff --git a/python/pyplugin_installer/qgsplugininstallerrepositorydialog.py b/python/pyplugin_installer/qgsplugininstallerrepositorydialog.py index a0e13a84325..80edeb84bab 100644 --- a/python/pyplugin_installer/qgsplugininstallerrepositorydialog.py +++ b/python/pyplugin_installer/qgsplugininstallerrepositorydialog.py @@ -24,11 +24,14 @@ ***************************************************************************/ """ +from pathlib import Path + +from qgis.PyQt import uic from qgis.gui import QgsAuthConfigSelect from qgis.PyQt.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout from qgis.PyQt.QtCore import Qt -from .ui_qgsplugininstallerrepositorybase import Ui_QgsPluginInstallerRepositoryDetailsDialogBase +Ui_QgsPluginInstallerRepositoryDetailsDialogBase, _ = uic.loadUiType(Path(__file__).parent / 'qgsplugininstallerrepositorybase.ui') class QgsPluginInstallerRepositoryDialog(QDialog, Ui_QgsPluginInstallerRepositoryDetailsDialogBase): From 305cd6059333f3b426822b55c565ef42c3dbaa76 Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Sun, 30 Jun 2024 07:41:33 +0200 Subject: [PATCH 2/2] Copy ui files to output folder to fix run from build dir --- python/console/CMakeLists.txt | 12 +++++++++++- python/pyplugin_installer/CMakeLists.txt | 6 ++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/python/console/CMakeLists.txt b/python/console/CMakeLists.txt index 5cfd44bb89d..acc73efef53 100644 --- a/python/console/CMakeLists.txt +++ b/python/console/CMakeLists.txt @@ -17,10 +17,20 @@ set(UI_FILES add_custom_target(pyconsole ALL) +add_custom_command(TARGET pyconsole + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${PYTHON_OUTPUT_DIRECTORY}/console + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) +add_custom_command(TARGET pyconsole + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${UI_FILES} ${PYTHON_OUTPUT_DIRECTORY}/console + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ${UI_FILES} +) foreach(pyfile ${PY_CONSOLE_FILES}) add_custom_command(TARGET pyconsole POST_BUILD - COMMAND ${CMAKE_COMMAND} -E make_directory ${PYTHON_OUTPUT_DIRECTORY}/console COMMAND ${CMAKE_COMMAND} -E copy ${pyfile} ${PYTHON_OUTPUT_DIRECTORY}/console WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${pyfile} diff --git a/python/pyplugin_installer/CMakeLists.txt b/python/pyplugin_installer/CMakeLists.txt index e12b77959dc..310ed51b3e9 100644 --- a/python/pyplugin_installer/CMakeLists.txt +++ b/python/pyplugin_installer/CMakeLists.txt @@ -29,6 +29,12 @@ add_custom_command(TARGET pyplugin-installer COMMAND ${CMAKE_COMMAND} -E make_directory ${PYTHON_OUTPUT_DIRECTORY}/pyplugin_installer WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) +add_custom_command(TARGET pyplugin-installer + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${UI_FILES} ${PYTHON_OUTPUT_DIRECTORY}/pyplugin_installer + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ${UI_FILES} +) foreach(pyfile ${PY_PLUGININSTALLER_FILES}) add_custom_command(TARGET pyplugin-installer