I have a .pro file on my project, but now I want to port it to a CMakeLists.txt file. How can I do this?
QT += core
QT -= gui
CONFIG += c++11
TARGET = test
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
QT += network
SOURCES += main.cpp \
test_interface.cpp \
motomanlibrary.cpp \
processing.cpp
SOURCES += main.cpp \
test_interface.h \
motomanlibrary.h \
processing.h
QMake: The required libraries.
QT += core
QT -= gui
QT += network
CMake: only the add is necessary. An exclude (QT -= gui) is not required.
find_package(Qt5Core REQUIRED)
find_package(Qt5Network REQUIRED)
QMake: Additional Compiler flags:
CONFIG += c++11
CMake: Extend the list of compiler flags as required.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
QMake: The source files
SOURCES += main.cpp \
test_interface.cpp \
motomanlibrary.cpp \
processing.cpp
CMake: Create a list of source files
set(SOURCES
main.cpp
test_interface.cpp
motomanlibrary.cpp
processing.cpp
)
QMake: The header to be included:
SOURCES += main.cpp \
test_interface.h \
motomanlibrary.h \
processing.h
CMake: Just show where the header files are.
include_directory(.) # or include_directory(${CMAKE_CURRENT_SOURCE_DIR})
include_directory(some/where/else)
QMake: The target to be built:
TARGET = test
CMake: Set the name of the target, add the sources, link the required libs.
add_executable(test ${SOURCES} )
qt5_use_modules(test Core Network) # This macro depends from the Qt version
# Should not be necessary
#CONFIG += console
#CONFIG -= app_bundle
#TEMPLATE = app
See further details on Convert qmake to cmake
There is a python script to convert QMake to CMake on a WIP branch of Qt Base: https://code.qt.io/cgit/qt/qtbase.git/tree/util/cmake/pro2cmake.py?h=wip/cmake
It will probably be released with Qt 6 when CMake will become the main build system.
This is what you would typically write in a simple Qt application built with cmake consuming Qt. A few gotchas:
Use automoc. This reduces the maintenance overhead significantly. It is also fast enough even for large projects so that you do not need to care about build-time slow-down.
Use versionless cmake targets so that they are compatible across Qt versions.
If you can, take advantage of the QT_DISABLE_DEPRECATED_BEFORE variable.
As a bonus, enable some usual warning, error and sanitizer detections if you aim for high quality.
You may or may not want to add a Qt 5 fallback in case anyone would like to use your software with Qt 5. This requirement may phase out slowly, but surely.
project(Application VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
find_package(Qt6 COMPONENTS Widgets)
if (NOT Qt6_FOUND)
find_package(Qt5 5.15 REQUIRED COMPONENTS Widgets)
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "(Clang|GNU)")
add_compile_options(-Wall -Wpedantic -Wextra -Werror)
add_compile_options(-fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer)
add_link_options(-fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer)
elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS "/w")
endif()
add_compile_definitions(QT_DISABLE_DEPRECATED_BEFORE=0xFFFFFF)
add_executable(Application
mainwindow.cpp
main.cpp
)
target_link_libraries(Application Qt::Widgets)
Related
I have two similar projects on the same machine. Their difference is that one is using GUI (Qt and Qwt) and the other is not. As the result, the one that has Qt is using qmake to compile and the other one cmake.
The project itself is about signal processing and working with audio. I decided to use RtAudio for capturing audio signal. I can compile and run the example code fine when I'm compiling with cmake but when I try to compile the other project using qmake, it fails.
The problem is jack (audio library) which is not found when compiling using qmake. But first, let's start with the project that works. Here's what I have in my CMakeLists.txt file:
cmake_minimum_required(VERSION 3.18)
project(cli_test)
set(CMAKE_CXX_STANDARD 17)
add_executable(cli_test main.cpp)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(arecord PRIVATE Threads::Threads)
target_link_libraries(arecord PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/fftw/lib/libfftw3.a)
include_directories(./rtaudio/include/rtaudio)
#list(GET LIB_TARGETS 0 LIBRTAUDIO)
set(LINKLIBS)
list(APPEND LINKLIBS ${ALSA_LIBRARY})
list(APPEND INCDIRS ${ALSA_INCLUDE_DIR})
target_link_libraries(cli_test ${CMAKE_CURRENT_SOURCE_DIR}/rtaudio/lib/librtaudio.a ${LINKLIBS})
target_link_libraries(cli_test PRIVATE Threads::Threads)
target_link_libraries(cli_test PRIVATE jack)
target_link_libraries(cli_test PRIVATE /usr/lib/libasound.so)
target_link_libraries(cli_test PRIVATE /usr/lib/libpulse.so)
target_link_libraries(cli_test PRIVATE /usr/lib/libpulse-simple.so)
(which again, works just fine). Then I got this one for qwt_test.pro:
CONFIG += c++1z c++14
INCLUDEPATH += .
INCLUDEPATH += $${PWD}/rtaudio/include/rtaudio
LIBS += $${PWD}/fftw/lib/libfftw3.a
LIBS += $${PWD}/rtaudio/lib/librtaudio.a
LIBS += jack
LIBS += /usr/lib/libasound.so
LIBS += /usr/lib/libpulse.so
LIBS += /usr/lib/libpulse-simple.so
TARGET = qwt_test
SOURCES = \
main.cpp
The error that I get is:
linking ../bin/qwt_test
/usr/bin/ld: cannot find jack: No such file or directory
collect2: error: ld returned 1 exit status
My question is, how can I link my project that is using qmake with jack?
To let qmake know where to find the lib please add
LIBS += -L"where-you-have-jack-lib" -ljack
I'm trying to build a with Qt 5.14 an application on release mode and everything is working fine inside of Qt Creator, but when I'm trying to run the executable by itself I'm getting an error like this:
OS: Windows 10
Qt: 5.14
Cmake: 3.5
What I've tried:
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -static")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -fPIC")
${ADDITIONAL_LIBRARIES} -static inside of target_link_libraries
None of the above worked for me and I'm getting the same error whenever I'm trying to run the executable by its self without using Qt Creator.
My CMake file:
cmake_minimum_required(VERSION 3.5)
project(Scrollable LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -static")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -fPIC")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt5 REQUIRED Core Widgets Gui Qml Quick Qml)
qt5_add_resources(resource.qrc)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories("MoviesInterface")
set(SOURCES
main.cpp
MovieInterface/movieinterfaceomdb.cpp
MovieInterface/moviesinterface.cpp
)
set(HEADERS
MovieInterface/movieinterfaceomdb.h
MovieInterface/moviesinterface.h
)
add_executable(Scrollable ${SOURCES} ${HEADERS} qml.qrc)
qt5_use_modules(Scrollable Core Network)
target_link_libraries(Scrollable
Qt5::Core
Qt5::Gui
Qt5::Widgets
Qt5::Qml
${ADDITIONAL_LIBRARIES} -static
)
A You want to statically compile. This won't work for Qt libs and Mingw libs itself, because these would need to be compiled statically, too.
But they are only distributed as dynamic linked libraries.
If you really want to have statically linkable Qt libs, you would need to compile Qt statically, before you can link them. There are some descriptions for compiling Qt statically out there. But it's a lot of work.
B Why Qt5Core.dll is not found:
Inside Qt Creator the path to the Qt libraries for your application is automatically set, because of Compiler/Toolchain auto-detection.
But, when you run your application executable standalone, the path to the Qt libs is not set and they do not reside in the application folder next to the executable.
To solve this i would suggest using windeployqt.
windeployqt analyzes the library or executable you build and copies the needed Qt dependencies into the build folder.
I tend to use a cmake helper function for this.
Create windeployqt.cmake with the following content and place it into /cmake modules folder of your project:
find_package(Qt5Core REQUIRED)
# get absolute path to qmake, then use it to find windeployqt executable
get_target_property(_qmake_executable Qt5::qmake IMPORTED_LOCATION)
get_filename_component(_qt_bin_dir "${_qmake_executable}" DIRECTORY)
function(windeployqt target)
# POST_BUILD step
# - after build, we have a bin/lib for analyzing qt dependencies
# - we run windeployqt on target and deploy Qt libs
add_custom_command(TARGET ${target} POST_BUILD
COMMAND "${_qt_bin_dir}/windeployqt.exe"
--verbose 1
--release
--no-svg
--no-angle
--no-opengl
--no-opengl-sw
--no-compiler-runtime
--no-system-d3d-compiler
\"$<TARGET_FILE:${target}>\"
COMMENT "Deploying Qt libraries using windeployqt for compilation target '${target}' ..."
)
endfunction()
Note 1: --verbose 1 is set, so that you see what's going on. You might disable it later.
Note 2: Please handle the excludes yourself. I don't know the specific requirements of your app, e.g. if you need OpenGL or SVG support.
Then add to your CMakeLists.txt:
# Set path to our custom CMAKE scripts
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
# Include Qt deployment helper function
include(windeployqt)
Finally, add to the end of CMakeLists.txt:
windeployqt(Scrollable)
Now, windeployqt is run as a POST_BUILD step on your executable, copying the qt libraries to the build folder. The executable will now pick up the Qt dependencies from this folder and should be able to run standalone (without path to Qt libs set).
Keep in mind to also copy other dependencies, e.g. third-party libs or runtime-dependencies.
Follow-up for your mingw dependencies:
set(QT_MINGW "/path/to/your/qt/mingw/compiler")
add_custom_command(TARGET Scrollable POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_MINGW}/bin/libgcc_s_dw2-1.dll $<TARGET_FILE_DIR:${TARGET}>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_MINGW}/bin/libstdc++-6.dll $<TARGET_FILE_DIR:${TARGET}>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_MINGW}/bin/libwinpthread-1.dll $<TARGET_FILE_DIR:${TARGET}>
COMMENT "Deploy mingw runtime libraries from ${QT_MINGW}/bin"
)
Follow-up for your mingw dependencies:
...
If Qt is installed with MinGW as well, you can avoid additional copy operattions for runtime libraries within add_custom_command just using windeployqt.exe with --compiler-runtime command line option.
I tried this in my .pro and it is being ignored:
TEMPLATE = app
CONFIG += console c++98
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += \
main.cpp
The simplest solution would be to have a cmake project instead. Then you'd have:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.1)
project(foo)
add_executable(${PROJECT_NAME} "main.cpp")
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 98)
Qt Creator supports cmake projects, thus there's no advantage to using qmake for such projects anymore. After all, the Qt dependency is specious - it's a dependency on qmake and nothing else, and qmake only comes bundled with Qt's Base module.
For qmake, you have to set the compiler flags directly:
!win32-msvc: QMAKE_CXXFLAGS += -std=c++98
Theres no way to set it for MSVC, no matter what build tool you're using: it's the limitation of the compiler itself. The only approach is to use a sufficiently old toolset, and optionally override QMAKE_CXX with the compiler's name (not path!). The compiler needs to be in the PATH, i.e. you'd have to use the toolset's vsvars script to set it up.
I'm trying to build an application on Linux with Qt where I can set the Cursor position. The project is managed with CMake.
CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.4)
project(Project)
add_definitions(-std=gnu++14 -std=c++14 -Wall -Wextra)
set(CMAKE_PREFIX_PATH "/home/elmewo/Libraries/Qt/5.3/gcc_64")
set(CMAKE_AUTOMOC ON)
find_package(Qt5Core REQUIRED)
find_package(Qt5Quick REQUIRED)
find_package(Qt5Gui REQUIRED)
include_directories(${CMAKE_SOURCE_DIR}/src)
set(SOURCE_FILES src/main.cpp)
add_executable(Project ${SOURCE_FILES})
qt5_use_modules(Project Core Quick Gui)
The packages are found by CMake. But when I try to
#include <QCursor>
my compiler says
fatal error: QCursor: file or directory not found
I was able to compile another basic QGuiApplication on the same machine.
The QCursor file is situated in ${CMAKE_PREFIX_PATH}/include/QtGui.
Am I missing something?
It seems that you are depending on 2.8.4, so at least you either need to change your build rules based on this or you will need to upgrade the dependency to at least cmake version 2.8.9:
Using Qt 5 with CMake older than 2.8.9
If using CMake older than 2.8.9, the qt5_use_modules macro is not available. Attempting to use it will result in an error.
To use Qt 5 with versions of CMake older than 2.8.9, it is necessary to use the target_link_libraries, include_directories, and add_definitions commands, and to manually specify moc requirements with either qt5_generate_moc or qt5_wrap_cpp:
Therefore, please add these if you stick with old cmake:
# Add the include directories for the Qt 5 Widgets module to
# the compile lines.
include_directories(${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Quick_INCLUDE_DIRS})
#Link the helloworld executable to the Qt 5 widgets library.
target_link_libraries(helloworld Qt5::Core Qt5::Gui Qt5::Quick)
The amount of tutorials, how to create a qt designer plugin is very thin..and the ones i found always use qt creator ( like this one : http://qt-project.org/doc/qt-4.8/designer-customwidgetplugin.html ). Where i have to add some qt definitions in the .pro file
CONFIG += designer plugin
I use CMake and Visual Studio for coding, so it would be really awesome if someone could tell me how i successfully create a .dll that i can put in the plugins/designer folder to have the custom widget show up in Qt Designer
Disclaimer: I know this is an old question but Even now I didn't find complete resources on how to do it.
I can't answer you for the Visual Studio part since I build on the (windows) command line, but here is my cmake.
I assume you have already created the following files related to the plugin, i.e.:
widget.h
widget.cpp
widget.ui
widgetPlugin.h -> QDesignerCustomWidgetInterface class
widgetPlugin.cpp
And that you want to create a library with multiple plugins, i.e. created the related files:
plugins.h -> QDesignerCustomWidgetCollectionInterface class
plugins.cpp
The content of the files simply follow what's in the tutorials.
The CMakeLists.txt is:
cmake_minimum_required(VERSION 2.8)
set(PROJECT Plugins)
project(${PROJECT})
# Needed to compile against ui and moc generated files
include_directories(${CMAKE_CURRENT_BINARY_DIR})
set(SOURCES
plugins.cpp
widgetPlugin.cpp
widget.cpp
)
set(HEADERS
plugins.h
widgetPlugin.h
widget.h
)
set(FORMS
widget.ui
)
# This is experimental, it works but it may be not optimal, don't hesitate to change this
find_package(Qt4 REQUIRED QtCore QtGui QtDesigner)
if (QT4_FOUND AND QT_QTCORE_FOUND AND QT_QTGUI_FOUND AND QT_QTDESIGNER_FOUND)
set(QT_USE_QTDESIGNER TRUE)
include(${QT_USE_FILE})
else()
message(FATAL_ERROR "no qt...")
endif()
qt4_wrap_cpp(HEADERS_MOC ${HEADERS})
qt4_wrap_ui(FORMS_HEADERS ${FORMS})
qt4_add_resources(RESOURCES_RCC ${RESOURCES})
# Here too, I'm not sure every define is necessary
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_definitions(-DQT_PLUGIN)
add_definitions(-DQT_NO_DEBUG)
add_definitions(-DQT_SHARED)
add_definitions(-DQDESIGNER_EXPORT_WIDGETS)
add_library(${PROJECT} SHARED
${SOURCES}
${HEADERS_MOC}
${FORMS_HEADERS}
${RESOURCES_RCC}
)
target_link_libraries(${PROJECT} ${QT_LIBRARIES})
# Install the library in QtDesigner plugin directory
install(TARGETS ${PROJECT}
DESTINATION ${QT_PLUGINS_DIR}/designer
)
To reload the plugins in QtDesigner, go to Help > About Plugins > Reload.
Then in the other CMakeLists.txt, I didn't want to include the library since there are also useless *Plugin files. So I included again the files I wanted :
cmake_minimum_required(VERSION 2.8)
set(PROJECT GPAUSX)
project(${PROJECT})
# Include the other CMakeLists.txt
subdirs(Plugins)
find_package(Qt4 REQUIRED)
# Files to insert
set(SOURCES
main.cpp
MainWindow.cpp
${Plugins_SOURCE_DIR}/widget.cpp
)
set(HEADERS
MainWindow.h
${Plugins_SOURCE_DIR}/widget.h
)
set(FORMS
MainWindow.ui
${Plugins_SOURCE_DIR}/widget.ui
)
qt4_wrap_cpp(HEADERS_MOC ${HEADERS})
qt4_wrap_ui(FORMS_HEADERS ${FORMS})
qt4_add_resources(RESOURCES_RCC ${RESOURCES})
include(${QT_USE_FILE})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_definitions(${QT_DEFINITIONS})
# I'm no expert in libraries so, intuitively I'd say this is useless but it won't compile if I don't define it.
# This clearly needs to get fixed.
add_definitions(-DQDESIGNER_EXPORT_WIDGETS)
# Possible variants making it compile :
# 1/ either include Plugins_BINARY_DIR or include .uis
# including the binary dir makes use of the already generated .uis
# 2/ either target Plugins or add Plugins .uis, .hs and .cpps with -DQDESIGNER_EXPORT_WIDGETS
# if you target plugins, make sure you compile with the same flags
add_executable(${PROJECT}
${SOURCES}
${HEADERS_MOC}
${FORMS_HEADERS}
${RESOURCES_RCC}
)
target_link_libraries(${PROJECT}
# Uncomment the following if you want to target Plugins
#Plugins
${QT_LIBRARIES}
)
Hope you'll find it useful !
Just use the cmake's qt auto tools and add all sources(.cpp .ui .qrc etc) to the target as follow:
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt4 REQUIRED QtCore QtGui QtDesigner #...
)
include(${QT_USE_FILE})
add_definitions(${QT_DEFINITIONS})
add_library(someplugin SHARED
path/to/plugin/someplugin.cpp
path/to/plugin/someplugin.qrc
path/to/plugin/someplugin.ui
path/to/plugin/s/other/src.cpp
#...
)
target_link_libraries(someplugin ${QT_LIBRARIES})
install(TARGETS someplugin
DESTINATION ${QT_PLUGINS_DIR}/designer
)