PDA

View Full Version : No ".pro" file--how to add modules in QtCreator, qt6?



davethomaspilot
21st January 2023, 15:12
Long time qt developer, but just now moving up to 6.4 and qtcreator 9.

I can build an example, but I'm thinking about how I will move my legacy apps to the new build environment.

Most of them required adding something like QT += module name.

Also, additional libraries to link, target name, etc.

So, I think cmake is now used for that?

Is there a resource to understand how to use cmake to do the things that used be done with qmake? Can I use qmake instead?

d_stranz
21st January 2023, 16:29
There is documentation from Qt (https://doc.qt.io/qtcreator/creator-project-cmake.html) as well as tutorial videos from KDAB (https://www.youtube.com/watch?v=952DsSbAHHg) and others, including some for creating CMake projects for cross-platform compilation (https://www.youtube.com/watch?v=XiMplRfuFJc) and cross-platform compilation for RPi (https://www.youtube.com/watch?v=oWpomXg9yj0).

It is well worth moving to CMake for builds. For basic projects, it is very straightforward and many things are just built in - like adding Qt to a project.

If you are serious about learning how to use CMake for large or complex builds, I would recommend two books: Modern CMake for C++ by Rafal Swidzinski and CMake Cookbook by Radovan Bast and Roberto Di Remigio. Kitware also has their own book, Mastering CMake by Ken Martin and Bill Hoffman.

The first book is a textbook which goes from first principles and builds to more complex project configuration and management. The second book is (as the title implies) a set of recipes for accomplishing specific tasks with CMake. The third is a distillation of the online CMake documentation into reference book form. What is good about it is that it explains in detail what all of the many, many commands, variables, and options in CMake mean and how and when they are used.

CMake is an incredibly powerful system, not just for builds but for complete project management - everything from source code control to generating documentation. I've used it to create a build system that builds a complete software development toolkit, consisting of dozens of projects, static and dynamic libraries, with a mix of C++, C, and C#. Probably close to a million lines of code spread over several thousand source code files. From one CMakelist hierarchy, it could build or cross-compile for 4 Windows distributions (debug and release, VS9 and VS10), 2 MacOS distributions, linux, and Android. Not all projects could be built for each configuration, and CMake handles that with conditionals.

davethomaspilot
21st January 2023, 19:36
Well, I was hoping not to have to go deep on a tool like cmake to just do what I've done previously in qt4 and qt5.

I did bother to learn more than the basics on qmake--now I have to do it all over again for cmake.

So yes, I did see the documentation, but Cmake is a very rich and powerful tool. Way more than I need for my relatively simple projects. So, I was hoping there was something more like a "quick start".

But, I'm hearing "buck it up, buttercup", so I'll dig in and learn it.

Thanks!

Added after 1 27 minutes:

I can't find anything in the referenced Qt documentation on how to do the equivalent of a QT += modulename like we did in qmake. It clearly explains configuring a kit include qmake setup, but I don't find what I need there.

That's a long video to watch (1 hour 34 minutes) just to figure out how to add modules. I already cross compiled, installed, and running testcases on the target rpi. Hopefully, the answer is in there someplace if I watch the whole video.

Surely it's not this hard? I'd just like an example of how to implement a typical .pro file in the new cmake environment.

d_stranz
22nd January 2023, 19:00
do the equivalent of a QT += modulename

Where "modulename" is what? The name of a Qt component, like XML, Widgets, or SQL? An external library?

If it is a Qt module, then you need this in your CMakelists file:



find_package(Qt6 REQUIRED COMPONENTS Widgets)
qt_standard_project_setup()

# Your custom list of sources here
add_executable(helloworld
mainwindow.ui
mainwindow.cpp
main.cpp
)

target_link_libraries(helloworld PRIVATE Qt6::Widgets)


I will typically move the declaration of target and source files into separate variables so the add_executable() command becomes generic:



# All of the customization occurs in these lines
set ( TARGET helloworld )
set ( QTVERSION ${QT_DEFAULT_MAJOR_VERSION} ) # uses an environment variable
set ( QTLIBS Widgets )
set ( SOURCES_ROOT . ) # or alternative locations if the CMakelists file is not in the same directory
set ( SOURCES
${SOURCES_ROOT}/mainwindow.ui
${SOURCES_ROOT}/mainwindow.cpp
${SOURCES_ROOT}/main.cpp
)

# So this is now boilerplate
find_package( Qt${QTVERSION} REQUIRED COMPONENTS ${QTLIBS} )
add_executable( ${TARGET} ${SOURCES} )

# Creates a list of scoped library names
foreach ( QTLIB QTLIBS )
set ( QTLINKS ${QTLINKS} Qt${QTVERSION}::${QTLIB} )
endforeach()

target_link_libraries( ${TARGET} PRIVATE ${QTLINKS} )


If "modulename" is an external library, simply define a variable / set of variables to specify the library names (without extensions) and modify the target_link_libraries() command.



set ( EXTRALIBS MyLib1 MyLib2 )

target_link_libraries( ${TARGET} PRIVATE ${QTLINKS} ${EXTRALIBS} )


If you are building a library instead of an executable, then you replace add_executable() with add_library() and omit the linking step. You can specify whether the library is static or shared using the STATIC or SHARED keywords in the add_library() command:



set ( SHARED_FLAG STATIC )

# ...

add_library ( ${TARGET} ${SHARED_FLAG} ${SOURCES} )


If I don't understand your question, please explain some more.

Note that I have defined my own variable names for QTLIBS, QTVERSION, QTLINKS, etc. There are some built-in variables (https://doc.qt.io/qt-6/cmake-variable-reference.html) that let you change the build via the command line or environment variable settings.

davethomaspilot
26th January 2023, 00:25
Perfect!

Haven't had a chance to try it yet, but I will tomorrow.

Thanks!

Added after 20 minutes:

Perfect!

Haven't had a chance to try it yet, but I will tomorrow.

Thanks!

d_stranz
26th January 2023, 17:21
An addendum - as far as I can tell, the "Component" names in the find_package() match the library file names in the binary "lib" directory (so-named in the Windows distribution), with the "Qtx" prefix removed: "Qt5Widgets" => Widgets, etc. According to the documentation, a declaration of a higher level library (like Widgets) will drag in dependent lower level libraries (Gui, Core) automatically.

Good luck. Once you get a template set up like the one above, it is pretty straightforward to create new projects. CMake also easily handles hierarchical project trees as well as projects that draw from sources or libraries spread out across a file system. You just have to tell it where to look.