CMake Port/Porting Guide: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
Line 43: Line 43:
=== General info ===
=== General info ===


Modules like Gui or Widgets are created in CMake with add_qt_module.
Modules like Gui or Widgets are created in CMake with '''add_qt_module'''.


Plugins with add_qt_plugin.
Plugins with '''add_qt_plugin'''.


Tools with add_qt_tool.
Tools with '''add_qt_tool'''.


Tests with add_qt_test.
Tests with '''add_qt_test'''.


Examples with add_qt_executable (consistent, right?).
Examples with '''add_qt_executable''' (consistent, right?).


=== Developer builds ===
=== Developer builds ===

Revision as of 14:56, 23 May 2019

Porting Notes

General porting guide

There is a python script called pro2cmake.py in qtbase/cmake/utils.

It takes a .pro file as input, and generates a CMakeLists.txt file in the same folder. You need to have python3 installed and a few packages from pip (pyparsing, sympy) to use the script.

Example:

python3 qtbase/util/cmake/pro2cmake.py qtbase/src/corelib/corelib.pro

The script can handle .pro files that add modules, plugins, examples, tests, and partial support for .pro files that just include other .pro files (subdirs).

The script does a good chunk of the conversion process for you, but you'll sometimes need to do manual fixes to the file. Make sure to mark those manual changes with a "# special case" marker. Example:

SOURCES
 foo.cpp
 bar.cpp # special case

This way when you re-run the script, you won't lose your manual modifications. You can also use block special case markers:

# special case begin
LIBRARIES
  Qt::Gui
# special case end

There is also another script called run_pro2cmake.py which runs the first script recursively on all .pro files in the given folder. A good place to use it would be on the examples folder, or on the whole repository you are porting: Example:

python3 qtbase/util/cmake/run_pro2cmake.py qtbase/examples
python3 qtbase/util/cmake/run_pro2cmake.py qtsvg

If a directory has a configure.json, you'll want to run a script called configurejson2cmake.py to generate a configure.cmake file. These files should not be modified manually, but rather the script should be fixed to handle your specific case.

python3 qtbase/util/cmake/configurejson2cmake.py qtbase/src/corelib

Porting a new repository

  • Request a wip/cmake branch for your repository from the dev branch
  • Copy the root CMakeLists.txt file from either qtsvg/CMakeLists.txt or qtimageformats/CMakeLists.txt into the root of your repository
  • Change the project name and description
  • Adjust the find_package() calls to import the required Qt Components (Core, Gui, Widgets, Test, Network, Xml, etc.) and make sure BuildInternals component is listed as well
  • Run either pro2cmake.py individually or run_pro2cmake.py on the whole repo.
  • Try to build it against an installation of qtbase, for example:
cmake ../qtsvg -DQT_USE_CCACHE=1 -GNinja -DCMAKE_INSTALL_PREFIX=/home/foo/qt/qt5_cmake/qtbase_installed && ninja
  • Fix something in the CMakeLists.txt file and rebuild again

General info

Modules like Gui or Widgets are created in CMake with add_qt_module.

Plugins with add_qt_plugin.

Tools with add_qt_tool.

Tests with add_qt_test.

Examples with add_qt_executable (consistent, right?).

Developer builds

When porting a new repo, it might be a hassle to get a changed qtbase file for your own repo module, because you first need to make install qtbase. You can configure your qtbase build with -DFEATURE_developer_build=ON, and then you don't have to install anything, only run make / ninja. To build another repo against such a qtbase, pass the build directory of qtbase as the CMAKE_INSTALL_PREFIX, e.g.:

cmake ../qtsvg -DQT_USE_CCACHE=1 -GNinja -DFEATURE_developer_build=ON -DCMAKE_INSTALL_PREFIX=/home/foo/qt/qt5_cmake/qtbase_built && ninja

Common qmake <-> CMake constructs

qmake CMake
qtHaveModule(foo) if(TARGET Qt::foo)
qtConfig(foo) if (QT_FEATURE_foo)
LIBS += zlib target_link_libraries(my_target PRIVATE ZLIB::ZLIB)
find a 3rdparty package qt_find_package(Cups REQUIRED PROVIDED_TARGETS Cups::Cups)