From e017eaa3fdea94f1df55005c30ef6262be144fde Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 23 Aug 2021 15:29:28 +0200 Subject: [PATCH] Doc: Update information about Qt Creator plugin wizard After the switch to CMake. Extends 29f3be1a6e236a199514a4edeeddb07322d70df4 Change-Id: I626bc7393d290710d7e5d1f2907e6fa1f25a7d21 Reviewed-by: Leena Miettinen --- .../exampleplugin/.github/workflows/README.md | 41 +++ .../.github/workflows/build_cmake.yml | 322 ++++++++++++++++++ .../examples/exampleplugin/.gitignore | 73 ++++ .../examples/exampleplugin/CMakeLists.txt | 40 +++ .../examples/exampleplugin/Example.json.in | 11 +- .../examples/exampleplugin/README.md | 36 ++ .../{exampleplugin.cpp => example.cpp} | 8 +- .../{exampleplugin.h => example.h} | 0 .../examples/exampleplugin/example.pro | 59 ---- .../examples/exampleplugin/example_global.h | 31 +- .../examples/exampleplugin/exampleconstants.h | 28 +- doc/qtcreatordev/src/first-plugin.qdoc | 111 +++--- 12 files changed, 626 insertions(+), 134 deletions(-) create mode 100644 doc/qtcreatordev/examples/exampleplugin/.github/workflows/README.md create mode 100644 doc/qtcreatordev/examples/exampleplugin/.github/workflows/build_cmake.yml create mode 100644 doc/qtcreatordev/examples/exampleplugin/.gitignore create mode 100644 doc/qtcreatordev/examples/exampleplugin/CMakeLists.txt create mode 100644 doc/qtcreatordev/examples/exampleplugin/README.md rename doc/qtcreatordev/examples/exampleplugin/{exampleplugin.cpp => example.cpp} (92%) rename doc/qtcreatordev/examples/exampleplugin/{exampleplugin.h => example.h} (100%) delete mode 100644 doc/qtcreatordev/examples/exampleplugin/example.pro diff --git a/doc/qtcreatordev/examples/exampleplugin/.github/workflows/README.md b/doc/qtcreatordev/examples/exampleplugin/.github/workflows/README.md new file mode 100644 index 00000000000..107410c6ec3 --- /dev/null +++ b/doc/qtcreatordev/examples/exampleplugin/.github/workflows/README.md @@ -0,0 +1,41 @@ +# GitHub Actions & Workflows + +The `build_cmake.yml` in this directory adds a [GitHub action][1] and workflow that builds +your plugin anytime you push commits to GitHub on Windows, Linux and macOS. + +The build artifacts can be downloaded from GitHub and be installed into an existing Qt Creator +installation. + +When you push a tag, the workflow also creates a new release on GitHub. + +## Keeping it up to date + +Near the top of the file you find a section starting with `env:`. + +The value for `QT_VERSION` specifies the Qt version to use for building the plugin. + +The value for `QT_CREATOR_VERSION` specifies the Qt Creator version to use for building the plugin. + +The value for `QT_CREATOR_SNAPSHOT` can either be `NO` or `latest` or the build ID of a specific +snapshot build for the Qt Creator version that you specified. + +You need to keep these values updated for different versions of your plugin, and take care +that the Qt version and Qt Creator version you specify are compatible. + +## What it does + +The build job consists of several steps: + +* Install required packages on the build host +* Download, unpack and install the binary for the Qt version +* Download and unpack the binary for the Qt Creator version +* Build the plugin and upload the plugin libraries to GitHub +* If a tag is pushed, create a release on GitHub for the tag, including zipped plugin libraries + for download + +## Limitations + +If your plugin requires additional resources besides the plugin library, you need to adapt the +script accordingly. + +[1]: https://help.github.com/en/actions/automating-your-workflow-with-github-actions/about-github-actions diff --git a/doc/qtcreatordev/examples/exampleplugin/.github/workflows/build_cmake.yml b/doc/qtcreatordev/examples/exampleplugin/.github/workflows/build_cmake.yml new file mode 100644 index 00000000000..97471b308a9 --- /dev/null +++ b/doc/qtcreatordev/examples/exampleplugin/.github/workflows/build_cmake.yml @@ -0,0 +1,322 @@ +name: Build plugin + +on: [push] + +env: + PLUGIN_NAME: Example + QT_VERSION: 6.2.0 + QT_CREATOR_VERSION: 5.0.0 + QT_CREATOR_SNAPSHOT: NO + CMAKE_VERSION: 3.18.3 + NINJA_VERSION: 1.10.1 + +jobs: + build: + name: ${{ matrix.config.name }} + runs-on: ${{ matrix.config.os }} + strategy: + matrix: + config: + - { + name: "Windows Latest MSVC", artifact: "Windows-x64", + os: windows-latest, + cc: "cl", cxx: "cl", + environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat", + } + - { + name: "Ubuntu Latest GCC", artifact: "Linux-x64", + os: ubuntu-latest, + cc: "gcc", cxx: "g++" + } + - { + name: "macOS Latest Clang", artifact: "macOS-x64", + os: macos-latest, + cc: "clang", cxx: "clang++" + } + + steps: + - uses: actions/checkout@v1 + + - name: Download Ninja and CMake + shell: cmake -P {0} + run: | + set(cmake_version "$ENV{CMAKE_VERSION}") + set(ninja_version "$ENV{NINJA_VERSION}") + + if ("${{ runner.os }}" STREQUAL "Windows") + set(ninja_suffix "win.zip") + set(cmake_suffix "win64-x64.zip") + set(cmake_dir "cmake-${cmake_version}-win64-x64/bin") + elseif ("${{ runner.os }}" STREQUAL "Linux") + set(ninja_suffix "linux.zip") + set(cmake_suffix "Linux-x86_64.tar.gz") + set(cmake_dir "cmake-${cmake_version}-Linux-x86_64/bin") + elseif ("${{ runner.os }}" STREQUAL "macOS") + set(ninja_suffix "mac.zip") + set(cmake_suffix "Darwin-x86_64.tar.gz") + set(cmake_dir "cmake-${cmake_version}-Darwin-x86_64/CMake.app/Contents/bin") + endif() + + set(ninja_url "https://github.com/ninja-build/ninja/releases/download/v${ninja_version}/ninja-${ninja_suffix}") + file(DOWNLOAD "${ninja_url}" ./ninja.zip SHOW_PROGRESS) + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./ninja.zip) + + set(cmake_url "https://github.com/Kitware/CMake/releases/download/v${cmake_version}/cmake-${cmake_version}-${cmake_suffix}") + file(DOWNLOAD "${cmake_url}" ./cmake.zip SHOW_PROGRESS) + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./cmake.zip) + + # Add to PATH environment variable + file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/${cmake_dir}" cmake_dir) + set(path_separator ":") + if ("${{ runner.os }}" STREQUAL "Windows") + set(path_separator ";") + endif() + file(APPEND "$ENV{GITHUB_PATH}" "$ENV{GITHUB_WORKSPACE}${path_separator}${cmake_dir}") + + if (NOT "${{ runner.os }}" STREQUAL "Windows") + execute_process( + COMMAND chmod +x ninja + COMMAND chmod +x ${cmake_dir}/cmake + ) + endif() + + - name: Install system libs + shell: cmake -P {0} + run: | + if ("${{ runner.os }}" STREQUAL "Linux") + execute_process( + COMMAND sudo apt update + ) + execute_process( + COMMAND sudo apt install libgl1-mesa-dev + RESULT_VARIABLE result + ) + if (NOT result EQUAL 0) + message(FATAL_ERROR "Failed to install dependencies") + endif() + endif() + + - name: Download Qt + id: qt + shell: cmake -P {0} + run: | + set(qt_version "$ENV{QT_VERSION}") + + string(REPLACE "." "" qt_version_dotless "${qt_version}") + if ("${{ runner.os }}" STREQUAL "Windows") + set(url_os "windows_x86") + set(qt_package_arch_suffix "win64_msvc2019_64") + set(qt_dir_prefix "${qt_version}/msvc2019_64") + set(qt_package_suffix "-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86_64") + elseif ("${{ runner.os }}" STREQUAL "Linux") + set(url_os "linux_x64") + set(qt_package_arch_suffix "gcc_64") + set(qt_dir_prefix "${qt_version}/gcc_64") + set(qt_package_suffix "-Linux-RHEL_7_6-GCC-Linux-RHEL_7_6-X86_64") + elseif ("${{ runner.os }}" STREQUAL "macOS") + set(url_os "mac_x64") + set(qt_package_arch_suffix "clang_64") + set(qt_dir_prefix "${qt_version}/clang_64") + set(qt_package_suffix "-MacOS-MacOS_10_13-Clang-MacOS-MacOS_10_13-X86_64") + endif() + + set(qt_base_url "https://download.qt.io/online/qtsdkrepository/${url_os}/desktop/qt5_${qt_version_dotless}") + file(DOWNLOAD "${qt_base_url}/Updates.xml" ./Updates.xml SHOW_PROGRESS) + + file(READ ./Updates.xml updates_xml) + string(REGEX MATCH "qt.qt5.*([0-9+-.]+)" updates_xml_output "${updates_xml}") + set(qt_package_version ${CMAKE_MATCH_1}) + + file(MAKE_DIRECTORY qt5) + + # Save the path for other steps + file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/qt5/${qt_dir_prefix}" qt_dir) + message("::set-output name=qt_dir::${qt_dir}") + + message("Downloading Qt to ${qt_dir}") + function(downloadAndExtract url archive) + message("Downloading ${url}") + file(DOWNLOAD "${url}" ./${archive} SHOW_PROGRESS) + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ../${archive} WORKING_DIRECTORY qt5) + endfunction() + + foreach(package qtbase qtdeclarative) + downloadAndExtract( + "${qt_base_url}/qt.qt5.${qt_version_dotless}.${qt_package_arch_suffix}/${qt_package_version}${package}${qt_package_suffix}.7z" + ${package}.7z + ) + endforeach() + + # uic depends on libicu56.so + if ("${{ runner.os }}" STREQUAL "Linux") + downloadAndExtract( + "${qt_base_url}/qt.qt5.${qt_version_dotless}.${qt_package_arch_suffix}/${qt_package_version}icu-linux-Rhel7.2-x64.7z" + icu.7z + ) + endif() + + - name: Download Qt Creator + id: qt_creator + shell: cmake -P {0} + run: | + string(REGEX MATCH "([0-9]+.[0-9]+).[0-9]+" outvar "$ENV{QT_CREATOR_VERSION}") + + set(qtc_base_url "https://download.qt.io/official_releases/qtcreator/${CMAKE_MATCH_1}/$ENV{QT_CREATOR_VERSION}/installer_source") + set(qtc_snapshot "$ENV{QT_CREATOR_SNAPSHOT}") + if (qtc_snapshot) + set(qtc_base_url "https://download.qt.io/snapshots/qtcreator/${CMAKE_MATCH_1}/$ENV{QT_CREATOR_VERSION}/installer_source/${qtc_snapshot}") + endif() + + if ("${{ runner.os }}" STREQUAL "Windows") + set(qtc_platform "windows_x64") + elseif ("${{ runner.os }}" STREQUAL "Linux") + set(qtc_platform "linux_x64") + elseif ("${{ runner.os }}" STREQUAL "macOS") + set(qtc_platform "mac_x64") + endif() + + file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/qtcreator" qtc_dir) + # Save the path for other steps + message("::set-output name=qtc_dir::${qtc_dir}") + + file(MAKE_DIRECTORY qtcreator) + + message("Downloading Qt Creator from ${qtc_base_url}/${qtc_platform}") + + foreach(package qtcreator qtcreator_dev) + file(DOWNLOAD + "${qtc_base_url}/${qtc_platform}/${package}.7z" ./${package}.7z SHOW_PROGRESS) + execute_process(COMMAND + ${CMAKE_COMMAND} -E tar xvf ../${package}.7z WORKING_DIRECTORY qtcreator) + endforeach() + + - name: Build + shell: cmake -P {0} + run: | + set(ENV{CC} ${{ matrix.config.cc }}) + set(ENV{CXX} ${{ matrix.config.cxx }}) + set(ENV{MACOSX_DEPLOYMENT_TARGET} "10.13") + + if ("${{ runner.os }}" STREQUAL "Windows" AND NOT "x${{ matrix.config.environment_script }}" STREQUAL "x") + execute_process( + COMMAND "${{ matrix.config.environment_script }}" && set + OUTPUT_FILE environment_script_output.txt + ) + file(STRINGS environment_script_output.txt output_lines) + foreach(line IN LISTS output_lines) + if (line MATCHES "^([a-zA-Z0-9_-]+)=(.*)$") + set(ENV{${CMAKE_MATCH_1}} "${CMAKE_MATCH_2}") + endif() + endforeach() + endif() + + set(ENV{NINJA_STATUS} "[%f/%t %o/sec] ") + + set(build_plugin_py "scripts/build_plugin.py") + foreach(dir "share/qtcreator/scripts" "Qt Creator.app/Contents/Resources/scripts" "Contents/Resources/scripts") + if(EXISTS "${{ steps.qt_creator.outputs.qtc_dir }}/${dir}/build_plugin.py") + set(build_plugin_py "${dir}/build_plugin.py") + break() + endif() + endforeach() + + execute_process( + COMMAND python + -u + "${{ steps.qt_creator.outputs.qtc_dir }}/${build_plugin_py}" + --name "$ENV{PLUGIN_NAME}-$ENV{QT_CREATOR_VERSION}-${{ matrix.config.artifact }}" + --src . + --build build + --qt-path "${{ steps.qt.outputs.qt_dir }}" + --qtc-path "${{ steps.qt_creator.outputs.qtc_dir }}" + --output-path "$ENV{GITHUB_WORKSPACE}" + RESULT_VARIABLE result + ) + if (NOT result EQUAL 0) + string(REGEX MATCH "FAILED:.*$" error_message "${output}") + string(REPLACE "\n" "%0A" error_message "${error_message}") + message("::error::${error_message}") + message(FATAL_ERROR "Build failed") + endif() + + - uses: actions/upload-artifact@v2 + id: upload_artifact + with: + path: ./${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }}.7z + name: ${{ env.PLUGIN_NAME}}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }}.7z + + release: + if: contains(github.ref, 'tags/v') + runs-on: ubuntu-latest + needs: build + + steps: + - name: Create Release + id: create_release + uses: actions/create-release@v1.0.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + draft: false + prerelease: false + + - name: Store Release url + run: | + echo "${{ steps.create_release.outputs.upload_url }}" > ./upload_url + + - uses: actions/upload-artifact@v1 + with: + path: ./upload_url + name: upload_url + + publish: + if: contains(github.ref, 'tags/v') + + name: ${{ matrix.config.name }} + runs-on: ${{ matrix.config.os }} + strategy: + matrix: + config: + - { + name: "Windows Latest x64", artifact: "Windows-x64.7z", + os: ubuntu-latest + } + - { + name: "Linux Latest x64", artifact: "Linux-x64.7z", + os: ubuntu-latest + } + - { + name: "macOS Latest x64", artifact: "macOS-x64.7z", + os: macos-latest + } + needs: release + + steps: + - name: Download artifact + uses: actions/download-artifact@v1 + with: + name: ${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }} + path: ./ + + - name: Download URL + uses: actions/download-artifact@v1 + with: + name: upload_url + path: ./ + - id: set_upload_url + run: | + upload_url=`cat ./upload_url` + echo ::set-output name=upload_url::$upload_url + + - name: Upload to Release + id: upload_to_release + uses: actions/upload-release-asset@v1.0.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.set_upload_url.outputs.upload_url }} + asset_path: ./${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }} + asset_name: ${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }} + asset_content_type: application/x-7z-compressed diff --git a/doc/qtcreatordev/examples/exampleplugin/.gitignore b/doc/qtcreatordev/examples/exampleplugin/.gitignore new file mode 100644 index 00000000000..fab7372d796 --- /dev/null +++ b/doc/qtcreatordev/examples/exampleplugin/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/doc/qtcreatordev/examples/exampleplugin/CMakeLists.txt b/doc/qtcreatordev/examples/exampleplugin/CMakeLists.txt new file mode 100644 index 00000000000..69df3ec4da7 --- /dev/null +++ b/doc/qtcreatordev/examples/exampleplugin/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.10) + +#! [1] +# Remove when sharing with others. +list(APPEND CMAKE_PREFIX_PATH "/Users/example/qt-creator/build") +#! [1] + +#! [2] +project(Example) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_CXX_STANDARD 17) +#! [2] + +#! [3] +find_package(QtCreator COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets REQUIRED) +set(QtX Qt${QT_VERSION_MAJOR}) +#! [3] + +#! [4] +add_qtc_plugin(Example + PLUGIN_DEPENDS + QtCreator::Core + DEPENDS + ${QtX}::Widgets + QtCreator::ExtensionSystem + QtCreator::Utils + SOURCES + .github/workflows/build_cmake.yml + .github/workflows/README.md + README.md + example.cpp + example.h + example_global.h + exampleconstants.h +) +#! [4] diff --git a/doc/qtcreatordev/examples/exampleplugin/Example.json.in b/doc/qtcreatordev/examples/exampleplugin/Example.json.in index 12b8bc37a0e..3a52e318c55 100644 --- a/doc/qtcreatordev/examples/exampleplugin/Example.json.in +++ b/doc/qtcreatordev/examples/exampleplugin/Example.json.in @@ -5,12 +5,11 @@ \"CompatVersion\" : \"0.0.1\", //! [1] //! [2] - \"Vendor\" : \"My Company\", - \"Copyright\" : \"(C) My Company\", - \"License\" : \"BSD\", - \"Category\" : \"Examples\", - \"Description\" : \"Minimal plugin example.\", - \"Url\" : \"http://www.mycompany.com\", + \"Vendor\" : \"MyCompany\", + \"Copyright\" : \"(C) MyCompany\", + \"License\" : \"Put short license information here\", + \"Description\" : \"Put a short description of your plugin here\", + \"Url\" : \"https://www.mycompany.com\", //! [2] //! [3] $$dependencyList diff --git a/doc/qtcreatordev/examples/exampleplugin/README.md b/doc/qtcreatordev/examples/exampleplugin/README.md new file mode 100644 index 00000000000..bcb70958c7f --- /dev/null +++ b/doc/qtcreatordev/examples/exampleplugin/README.md @@ -0,0 +1,36 @@ +# Example + +## How to Build + +Create a build directory and run + + cmake -DCMAKE_PREFIX_PATH= -DCMAKE_BUILD_TYPE=RelWithDebInfo + cmake --build . + +where `` is the relative or absolute path to a Qt Creator build directory, or to a +combined binary and development package (Windows / Linux), or to the `Qt Creator.app/Contents/Resources/` +directory of a combined binary and development package (macOS), and `` is the +relative or absolute path to this plugin directory. + +## How to Run + +Run a compatible Qt Creator with the additional command line argument + + -pluginpath + +where `` is the path to the resulting plugin library in the build directory +(`/lib/qtcreator/plugins` on Windows and Linux, +`/Qt Creator.app/Contents/PlugIns` on macOS). + +You might want to add `-temporarycleansettings` (or `-tcs`) to ensure that the opened Qt Creator +instance cannot mess with your user-global Qt Creator settings. + +When building and running the plugin from Qt Creator, you can use + + -pluginpath "%{buildDir}/lib/qtcreator/plugins" -tcs + +on Windows and Linux, or + + -pluginpath "%{buildDir}/Qt Creator.app/Contents/PlugIns" -tcs + +for the `Command line arguments` field in the run settings. diff --git a/doc/qtcreatordev/examples/exampleplugin/exampleplugin.cpp b/doc/qtcreatordev/examples/exampleplugin/example.cpp similarity index 92% rename from doc/qtcreatordev/examples/exampleplugin/exampleplugin.cpp rename to doc/qtcreatordev/examples/exampleplugin/example.cpp index 5adc093c46d..f001fad5119 100644 --- a/doc/qtcreatordev/examples/exampleplugin/exampleplugin.cpp +++ b/doc/qtcreatordev/examples/exampleplugin/example.cpp @@ -1,4 +1,4 @@ -#include "exampleplugin.h" +#include "example.h" #include "exampleconstants.h" #include @@ -13,8 +13,6 @@ #include #include -#include - namespace Example { namespace Internal { @@ -42,9 +40,9 @@ bool ExamplePlugin::initialize(const QStringList &arguments, QString *errorStrin Q_UNUSED(errorString) //! [add action] - QAction *action = new QAction(tr("Example Action"), this); + auto action = new QAction(tr("Example Action"), this); Core::Command *cmd = Core::ActionManager::registerAction(action, Constants::ACTION_ID, - Core::Context(Core::Constants::C_GLOBAL)); + Core::Context(Core::Constants::C_GLOBAL)); cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Meta+A"))); connect(action, &QAction::triggered, this, &ExamplePlugin::triggerAction); //! [add action] diff --git a/doc/qtcreatordev/examples/exampleplugin/exampleplugin.h b/doc/qtcreatordev/examples/exampleplugin/example.h similarity index 100% rename from doc/qtcreatordev/examples/exampleplugin/exampleplugin.h rename to doc/qtcreatordev/examples/exampleplugin/example.h diff --git a/doc/qtcreatordev/examples/exampleplugin/example.pro b/doc/qtcreatordev/examples/exampleplugin/example.pro deleted file mode 100644 index c100894b7ba..00000000000 --- a/doc/qtcreatordev/examples/exampleplugin/example.pro +++ /dev/null @@ -1,59 +0,0 @@ -#! [1] -DEFINES += EXAMPLE_LIBRARY -#! [1] - -# Example files - -#! [2] -SOURCES += exampleplugin.cpp - -HEADERS += exampleplugin.h \ - example_global.h \ - exampleconstants.h -#! [2] - -# Qt Creator linking - -#! [3] -## set the QTC_SOURCE environment variable to override the setting here -QTCREATOR_SOURCES = $$(QTC_SOURCE) -isEmpty(QTCREATOR_SOURCES):QTCREATOR_SOURCES=/Users/example/qtcreator-src - -## set the QTC_BUILD environment variable to override the setting here -IDE_BUILD_TREE = $$(QTC_BUILD) -isEmpty(IDE_BUILD_TREE):IDE_BUILD_TREE=/Users/example/qtcreator-build -#! [3] - -#! [4] -## uncomment to build plugin into user config directory -## /plugins/ -## where is e.g. -## "%LOCALAPPDATA%\QtProject\qtcreator" on Windows Vista and later -## "$XDG_DATA_HOME/data/QtProject/qtcreator" or "~/.local/share/data/QtProject/qtcreator" on Linux -## "~/Library/Application Support/QtProject/Qt Creator" on Mac -# USE_USER_DESTDIR = yes -#! [4] - -#! [5] -###### If the plugin can be depended upon by other plugins, this code needs to be outsourced to -###### _dependencies.pri, where is the name of the directory containing the -###### plugin's sources. - -QTC_PLUGIN_NAME = Example -QTC_LIB_DEPENDS += \ - # nothing here at this time - -QTC_PLUGIN_DEPENDS += \ - coreplugin - -QTC_PLUGIN_RECOMMENDS += \ - # optional plugin dependencies. nothing here at this time - -###### End _dependencies.pri contents ###### -#! [5] - -#![6] -include($$QTCREATOR_SOURCES/src/qtcreatorplugin.pri) - -#![6] - diff --git a/doc/qtcreatordev/examples/exampleplugin/example_global.h b/doc/qtcreatordev/examples/exampleplugin/example_global.h index 00c77e6b162..a1bab3f9091 100644 --- a/doc/qtcreatordev/examples/exampleplugin/example_global.h +++ b/doc/qtcreatordev/examples/exampleplugin/example_global.h @@ -1,9 +1,32 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + #pragma once -#include - #if defined(EXAMPLE_LIBRARY) -# define EXAMPLESHARED_EXPORT Q_DECL_EXPORT +# define EXAMPLE_EXPORT Q_DECL_EXPORT #else -# define EXAMPLESHARED_EXPORT Q_DECL_IMPORT +# define EXAMPLE_EXPORT Q_DECL_IMPORT #endif diff --git a/doc/qtcreatordev/examples/exampleplugin/exampleconstants.h b/doc/qtcreatordev/examples/exampleplugin/exampleconstants.h index fced2e04295..c5068d94bb6 100644 --- a/doc/qtcreatordev/examples/exampleplugin/exampleconstants.h +++ b/doc/qtcreatordev/examples/exampleplugin/exampleconstants.h @@ -1,3 +1,28 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + #pragma once namespace Example { @@ -6,5 +31,6 @@ namespace Constants { const char ACTION_ID[] = "Example.Action"; const char MENU_ID[] = "Example.Menu"; -} // namespace Example } // namespace Constants +} // namespace Example + diff --git a/doc/qtcreatordev/src/first-plugin.qdoc b/doc/qtcreatordev/src/first-plugin.qdoc index 458d397a177..9b347facc35 100644 --- a/doc/qtcreatordev/src/first-plugin.qdoc +++ b/doc/qtcreatordev/src/first-plugin.qdoc @@ -155,6 +155,10 @@ \li File \li Role + \row + \li \c {README.md} + + \li Describes how to build and run the plugin. \row \li \c {Example.json.in} @@ -164,8 +168,7 @@ \row \li \c {CMakeLists.txt} - \li Project file, used by CMake to generate a Makefile that then is used to - build the plugin. + \li Project file, used by CMake to generate build files and build the plugin. \row \li \c {example_global.h} @@ -190,71 +193,61 @@ information, see \c {.github\workflow\README.md}. \endtable - \section1 qmake Project + \section1 CMake Project - The qmake project file \c {example.pro} defines how your plugin should be + The CMake project file \c {CMakeLists.txt} defines how your plugin should be compiled. \QC plugins need to have a specific setup there, in addition to - telling qmake which files need to be compiled (or handled by \c moc or + telling CMake which files need to be compiled (or handled by \c moc or \c uic). Let us have a look at what the project wizard generated for you in detail. - \snippet exampleplugin/example.pro 1 + \snippet exampleplugin/CMakeLists.txt 1 - The first section of the .pro file lets the compiler pass an - \c EXAMPLE_LIBRARY define to the compiled code, which is used in the - \c {example_global.h} header, but is not really of interest for now. You - should not need to change that section of the \c {.pro} file. + The \c{list(APPEND ...)} call tells CMake to include the \QC build path that + you specified in the wizard in its search path for dependencies. Since this + contains an absolute path on your local machine, you should remove this line + when sharing the project with others. - \snippet exampleplugin/example.pro 2 + Without this line, you need to explicitly add the path to the \QC + build to \c {CMAKE_PREFIX_PATH} when configuring your plugin with CMake. - This section tells qmake about the files of your project that it should let - compile or otherwise handle. You need to expand that section with any files - you add to the project. + \snippet exampleplugin/CMakeLists.txt 2 - \snippet exampleplugin/example.pro 3 + This section does some standard setup for Qt/CMake projects. Besides + setting a project name and a C++ standard to use, it turns on automatic + detection of files that need to be run through \c {moc}, \c {rcc} or \c + {uic}. - To compile and deploy your plugin, the project needs access to the \QC - sources and build. This section contains the logic that looks for the - information about the location of the sources and build in the - \c {QTC_SOURCE} and \c {QTC_BUILD} environment variables. If these are not - defined, it uses the defaults you set in the project wizard. + \snippet exampleplugin/CMakeLists.txt 3 - So, if someone else opens your plugin project on their machine, they do not - need to edit the .pro file, but instead they should set the \c {QTC_SOURCE} - and \c {QTC_BUILD} environment variables correctly for the plugin's build - environment. + This section tells CMake to locate \QC and Qt. If your plugin requires + additional Qt modules, you need to add them to the corresponding + \c {find_package} call in this section. - You should not need to change this section, except perhaps to adapt the - defaults. + To find \QC and Qt, the paths to the \QC and Qt installation must be + present in the \c {CMAKE_PREFIX_PATH} when you configure your plugin + with CMake. - \snippet exampleplugin/example.pro 4 + \snippet exampleplugin/CMakeLists.txt 4 - \QC plugins can either be installed into the \QC installation's plugin - directory (requires write access there), or to a user specific plugin - directory. The \c USE_USER_DESTDIR switch in the .pro file defines which - method is used for building the plugin (which is independent from what you - can later use for distributing your plugin to other users). + The \c {add_qtc_plugin} call creates a target for your plugin with the + specified name. - \snippet exampleplugin/example.pro 5 + In the \c {PLUGIN_DEPENDS} sub-section, you need to specify \QC plugins that + your plugin depends on. Valid values are a plugin's name prefixed with + \c {QtCreator::}. - This section defines the name and dependencies of your plugin. The - \c {QTC_PLUGIN_NAME} variable defines the name of your plugin, and the name - of the dynamic library that is created for it. The \c {QTC_LIB_DEPENDS} - variable is a list of library names of the \QC utility libraries that your - plugin depends on. Typical values would be \c aggregation, - \c extensionsystem and \c utils. The \c {QTC_PLUGIN_DEPENDS} variable - defines the \QC plugins that your plugin depends on. Almost all \QC plugins - will depend on the \c coreplugin. The \c {QTC_PLUGIN_RECOMMENDS} variable - defines the \QC plugins that your plugin optionally depends on. For more - information, see \l{Optional Dependencies}. + In the \c {DEPENDS} sub-section, you need to specify libraries that your + plugin depends on. Use a Qt module name prefixed with \c {$\{QtX\}::} + to link to additional Qt modules. To link against additional \QC libraries, + prefix their name with \c {QtCreator::}. In this subsection you also + specify other libraries that your plugin depends on. - \snippet exampleplugin/example.pro 6 - - The included file \c{qtcreatorplugin.pri} makes sure that you build a plugin - that is suitable for use in \QC, by using the information you gave above. - - For more information about qmake, and writing \c {.pro} files in general, - see the \l{qmake Manual}. + In the \c {SOURCES} sub-section, you specify all files that belong to your + plugin project. CMake sorts these into source files and header files + automatically. Other files in this section are ignored by CMake but appear + for example in the project tree that is shown in IDEs like \QC for easier + access. \section1 Plugin Meta Data Template @@ -289,22 +282,22 @@ \section1 Plugin Class - The files \c {exampleplugin.h} and \c {exampleplugin.cpp} define the plugin + The files \c {example.h} and \c {example.cpp} define the plugin implementation of your little plugin. We'll concentrate on some highlights here, and give pointers to more detailed information for the various parts. \section2 Header File - The header file \c {exampleplugin.h} defines the interface of the plugin + The header file \c {example.h} defines the interface of the plugin class. - \snippet exampleplugin/exampleplugin.h namespaces + \snippet exampleplugin/example.h namespaces The plugin is defined in a \c {Example::Internal} namespace, which conforms to the coding rules for \l{coding-rules-namespacing}{namespacing} in \QC sources. - \snippet exampleplugin/exampleplugin.h base class + \snippet exampleplugin/example.h base class All \QC plugins must be derived from \l{ExtensionSystem::IPlugin} and are QObjects. The \c {Q_PLUGIN_METADATA} macro is necessary to create a @@ -313,13 +306,13 @@ \c FILE must point to the plugin's meta data file as described in \l{Plugin Meta Data}. - \snippet exampleplugin/exampleplugin.h plugin functions + \snippet exampleplugin/example.h plugin functions The base class defines basic functions that are called during the life cycle of a plugin, which are here implemented for your new plugin. These functions and their roles are described in detail in \l{Plugin Life Cycle}. - \snippet exampleplugin/exampleplugin.h slot + \snippet exampleplugin/example.h slot The plugin has an additional custom slot, that is used to pop up a dialog when the user chooses the menu item that this plugin adds. @@ -341,7 +334,7 @@ For more information about implementing the plugin interface, see the \l{ExtensionSystem::IPlugin} API documentation and \l{Plugin Life Cycle}. - \snippet exampleplugin/exampleplugin.cpp add action + \snippet exampleplugin/example.cpp add action This part of the code creates a new \c QAction, registers it as a new \c Command in the action manager, and connects it to the plugin's slot. The @@ -350,12 +343,12 @@ be directed to different plugins under different circumstances, as well as a few other things. - \snippet exampleplugin/exampleplugin.cpp add menu + \snippet exampleplugin/example.cpp add menu Here a new menu item is created, the created command added to it, and the menu added to the \uicontrol Tools menu in the menu bar. - \snippet exampleplugin/exampleplugin.cpp slot implementation + \snippet exampleplugin/example.cpp slot implementation This part defines the code that is called when the menu item is triggered. It uses the Qt API to open a message box that displays informative text and