Introducing qmake2cmake

Qt's own QMake project files have been converted with a Python script named pro2cmake that lives in qtbase. This script is specially tailored for converting the projects in Qt repositories and is little useful for converting user projects.

We have forked this script and turned it into a converter for your projects: Say hello to qmake2cmake!

What does it do?

The qmake2cmake tool creates a CMakeLists.txt that covers the most common attributes of the converted .pro file. The generated CMake project can be used as baseline and will most likely need manual adjustments.

QMake constructs that cannot be converted end up in the CMake project as comment. These comments are helpful when converting these bits manually.

Many projects have more than just one .pro file. For QMake SUBDIRS hierarchies, there's qmake2cmake_all which operates on a project's root directory and converts everything below it.

For Qt itself, conversion speed was a non-negligible aspect. That's why qmake2cmake_all parallelizes the conversion of subprojects.

What it does not

There are some QMake constructs that are not converted:

  • TEMPLATE = aux projects
  • custom .prf files
  • extra compilers
  • extra targets

All these will need to be manually converted.

Where do I get it?

Installation of qmake2cmake is as simple as

python -m pip install qmake2cmake

If you want the source code, clone the repository:

git clone git://code.qt.io/qt/qmake2cmake.git

Refer to README.md for requirements and further installation details.

How to use it?

To convert a whole project tree, pass the project directory to qmake2cmake_all:
qmake2cmake_all ~/projects/myapp --min-qt-version 6.3

It is necessary to specify the lowest Qt version the project will be built against. This selects the right CMake API for the Qt version.

To avoid passing this parameter to every call, you can set the QMAKE2CMAKE_MIN_QT_VERSION environment variable.

The following call converts a single QMake project file to CMake:
qmake2cmake ~/projects/myapp/myapp.pro

By default, a CMakeLists.txt is placed next to the .pro file.
To generate CMakeLists.txt in a different location, use the -o option:
qmake2cmake ~/projects/myapp/myapp.pro -o ~/projects/myapp-converted/CMakeLists.txt

How does it look like?

The following code snippet shows the result of converting the gui/analogclock example to CMake with the minimum Qt version 6.3:

cmake_minimum_required(VERSION 3.16) 
project(analogclock VERSION 1.0 LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

qt_standard_project_setup()

find_package(QT NAMES Qt5 Qt6 REQUIRED COMPONENTS Core)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui)

qt_add_executable(analogclock WIN32 MACOSX_BUNDLE
   ../rasterwindow/rasterwindow.cpp ../rasterwindow/rasterwindow.h
   main.cpp
)
target_include_directories(analogclock PRIVATE
   ../rasterwindow
)

target_link_libraries(analogclock PRIVATE
   Qt::Core
   Qt::Gui
)

install(TARGETS analogclock
   BUNDLE DESTINATION .
   RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

qt_generate_deploy_app_script(
   TARGET analogclock
   FILENAME_VARIABLE deploy_script
   NO_UNSUPPORTED_PLATFORM_ERROR
)
install(SCRIPT ${deploy_script}

Contributing

The qmake2cmake tool is hosted at the Qt project, and the usual contribution rules apply.

Please report bugs at https://bugreports.qt.io/ using the project "Qt (QTBUG)" and the component "Build Tools: other".

 


Blog Topics:

Comments

K
Kelteseth
1 point
36 months ago

Shameless plug of my blog post for people who are not yet convinced to transition from qmake to cmake 😁

J
Jörg Bornemann
0 points
36 months ago

That's a nice blog post!

I suspect that the problems you've experienced with SUBDIRS and dependencies are related to the order of items in the SUBDIRS variable. They have to be already topologically sorted - at least for some generators. :-/

C
CarelC
1 point
36 months ago

Perhaps a small code snippet could be useful of the before and after for this post? The "How to use it" is good and I would like to see a "How it looks" type thing.

J
Jörg Bornemann
0 points
36 months ago

Good suggestion, I'll amend the post.

Mike Inman
0 points
32 months ago

While quite helpful, I have a large qmake based project which has a number (~50) of modules defined in .pri files which are included in one or more of the dozen or so .pro files in the overall project... qmake2cmake_all doesn't keep the contents of these .pri files modular but rather inlines them with their respective .pro files which makes maintenance quite a bit harder (change in the module that used to be defined in a single .pri file may now appear in 8 to 10 CMakeLists.txt files). This might be addressed by continuing to maintain the .pri files and auto-generating the CMake files at each build, but the qmake2cmake_all process fails to completely translate about 6 of my .pro files, so again a lot of hand-work.

Any chance of an option to keep the .pri files represented in a modular fashion in the generated CMakeLists.txt files?

J
Jörg Bornemann
0 points
31 months ago

It might be possible to implement a switch for this. I've created a suggestion from your comment at https://bugreports.qt.io/browse/QTBUG-106642

Andrew Cunningham
0 points
18 months ago

I notice that even with --min-qt-version 5.15 the generated CMakeLists.txt might use the qtaddresources with QT6 only options like PREFIX, making the generated files useless with 5.15.

Samuel Grant
0 points
7 months ago

Getting an error when running 'qmake2cmake_all':

XXXX basename with value other than PROFILEPWD