How to link QtMain in CMake with Qt5? - c++

I upgraded my project code from Qt4 to Qt5. It uses CMake.
The conversion got well except for one line of Cmake commands related to Qt.
I can’t find in current documentation, like
http://qt-project.org/doc/qt-5.0/qtdoc/cmake-manual.html
http://qt-project.org/doc/qt-5.0/qtdoc/qtmain.html
How to link with QtMain from CMake (with Qt5)?
It is the only missing bit to convert my project.
Can someone point me to a doc explaining this or explain how to do it with Qt5? My Qt4 code worked correctly but I can't find the Cmake macro for Qt5.
EDIT> Here is the CMake file I have at the moment: https://bitbucket.org/klaim/aos_qt5/src/593c195c4c6889f6968d68fca018ef425783a063/tools/aosdesigner/CMakeLists.txt?at=wip_qt5
All qt5 necessary CMake macros have been set correctly I belive, the only thing that don't work is the linking to QtMain that do nothing, as expected since there should be a Qt5 specific way of doing it that I don't find in the Qt5 documentation.
You can browse the file history to see how it was working with Qt4.

From the Qt docs you linked to, it seems you can find Qt5Core instead of Qt5Widgets. That will create an imported target named Qt5::WinMain. From the Qt docs:
Imported targets are created for each Qt module. That means that the Qt5<Module>_LIBRARIES contains a name of an imported target, rather than a path to a library.
...
Each module in Qt 5 has a library target with the naming convention Qt5::<Module>
find_package( Qt5Widgets REQUIRED )
find_package( Qt5Core REQUIRED )
...
add_executable( aosdesigner WIN32 ${AOSDESIGNER_ALL_FILES} )
target_link_libraries( aosdesigner
${Boost_LIBRARIES}
utilcpp
aoslcpp
Qt5::WinMain # <-- New target available via find_package ( Qt5Core )
)
qt5_use_modules( aosdesigner Widgets )
I'd also recommend that you remove your two link_libraries calls since it's a deprecated command and I'd specify CMake version 2.8.9 rather than just 2.8 as the minimum required at the top of your CMakeLists.txt, since that's required for qt5_use_modules.

As of CMake 2.8.11 and Qt 5.1, linking to Qt5::WinMain is automatic/implicit if you specify WIN32 in your add_executable call, or otherwise set the WIN32_EXECUTABLE target property.
The presentation at
https://devdays.kdab.com/wp-content/uploads/2012/cmake.pdf
with video at
http://www.youtube.com/watch?feature=player_detailpage&v=GJ0kMsLbk6Q#t=751
describes the features which made it into CMake 2.8.11.
For more about CMake with Qt see
http://www.kdab.com/modern-cmake-with-qt-and-boost/

EDIT : Thanks to Archi comment (see below), simply add
target_link_libraries(<your_app> Qt5::WinMain)
or
target_link_libraries(<your_app> ${Qt5Core_QTMAIN_LIBRARIES})
in your application's CMakeLists.txt. Both syntaxes worked for me.

Related

Setup CMake with SFML in VS2017

Just like in CLion I want to use SFML with Visual Studio 2017, but I'm still learning cmake and I don't know the commands or the logic of how cmake works at all. I've just seen some posts and got this litle script.
Note: I downloaded the latest version of sfml in the link provided, I just taked the extrated directory and put alongside CMakeLists.txt in my folder
#sets up the minimum version of cmake
cmake_minimum_required(VERSION 3.9)
#how the project will be called
project (space_impact)
#set c++11 standard
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" -std=c++11)
#set source files
set (SOURCE_FILES main.cpp)
#we add the executable of the program
add_executable (space_impact ${SOURCE_FILES})
#taked from a mac-clion tutorial, doesn't work
set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/SFML/cmake-modules/")
find_package (SFML REQUIRED system window graphics network audio)
if (SFML_FOUND)
include_directories(${SFML_INCLUDE_DIR})
target_link_libraries(space_impact ${SFML_LIBRARIES})
endif()
that thing gave me errors:
Error CMake Error at SFML/cmake-modules/FindSFML.cmake:355 (message):
Could NOT find SFML (missing: SFML_SYSTEM_LIBRARY SFML_WINDOW_LIBRARY
SFML_GRAPHICS_LIBRARY SFML_NETWORK_LIBRARY SFML_AUDIO_LIBRARY) SFML/cmake-modules/FindSFML.cmake
I want everything to be dynamic, but I don't know how can I do that..
So my question is what should I do for setting up correctly SFML with Cmake in Visual Studio.
I don't want the old-fashioned method from the official website
UPDATE
Here's my location....
The thing is.. the FindSFML.cmake script it's not working...
What files should I move for make it working?
Your script is perfectly fine, except three things I'd change:
Move the whole module detection before defining targets. I'm pretty sure you also have to define your include directories before.
Your if(SFML_FOUND) bracket is pretty pointless right now, because you've set SFML to be required, which means it will never get past find_package() unless it's found.
-std=c++11 is a GCC only flag (MSVC will always use the latest standard, unless specified). As such you'll have to check the compiler here or use CMAKE_CXX_STANDARD.
So the "cleaned" CMakeLists.txt could look like this:
#sets up the minimum version of cmake
cmake_minimum_required(VERSION 3.9) # personally I'd set this version as low as required; you don't have to require the cutting edge version
#how the project will be called
project (space_impact)
#set the C++ standard to be used
set (CMAKE_CXX_STANDARD 11)
#set source files
set (SOURCE_FILES main.cpp)
#look for SFML and add it
set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/SFML/cmake-modules/")
find_package (SFML REQUIRED system window graphics network audio)
include_directories(${SFML_INCLUDE_DIR})
#we add the executable of the program
add_executable (space_impact ${SOURCE_FILES})
target_link_libraries(space_impact ${SFML_LIBRARIES} ${SFML_DEPENDENCIES})
Note that adding SFML_DEPENDENCIES to the library list is optional, unless you're using a static version of SFML.
But what about your SFML issue? Since you don't have the SFML files installed in any directory looked into by default, you'll have to tell CMake where it's found using the CMake variable SFML_ROOT or the environment variable of the same name.
So the first time you're invoking CMake, it could look like this:
cmake -G "Visual Studio 15 2017" -DSFML_ROOT=path/to/sfml path/to/source
This is all you need to compile sfml in your cmake project.
find_package(SFML 2.5.1 COMPONENTS system graphics audio network REQUIRED)
add_executable (AwesomeProject "AwesomeProject.cpp" "AwesomeProject.h")
target_link_libraries(AwesomeProject PRIVATE sfml-audio sfml-graphics sfml-network sfml-system)
Also set SFML_DIR var to your sfml folder.

How to stop cmake add wxjpeg.lib to visual studio project?

I have a project that uses both OpenCv and wxWidgets in a static library. These two libraries have definitions for jpeg and hence are generating conflicts during compilation.
As I am not using jpeg which is inside wxwidget, I would like to remove this library from my application. I tested my application and if I remove this library manually from MSVC poroject, it works well.
In cmake I have this line to add wxwidgets to my project:
set(wxWidgets_CONFIGURATION msvc)
find_package(wxWidgets COMPONENTS core base adv REQUIRED)
include(${wxWidgets_USE_FILE})
How can I instruct cmake not to add wxjpeg.lib to the requested linked libraries?
Based on the documentation to this cmake module (link) I would say that adding
set(wxWidgets_EXCLUDE_COMMON_LIBRARIES TRUE)
before using the find_package command would be enough to exclude wxjpeg.lib. Since this also excludes other common libraries (e.g. png), you may have to explicitly include more in your call to find_package
find_package(wxWidgets COMPONENTS core base adv png REQUIRED)

Ubuntu CMake what path to add to CMAKE_MODULE_PATH

My OS is Ubuntu. I would like to change from QT4 to QT5 in my project. The native package though is 4.x version in Ubuntu right now.
I have downloaded the Linux installer from QT homepage and installed QT5.4 under /opt/Qt/5.4/
This path is not found by
find_package (Qt5 REQUIRED)
I tried adding
set(CMAKE_MODULE_PATH "/opt/QT/5.4;${CMAKE_MODULE_PATH}")
to my CMAKELIST.txt but that does not help.
Where do I have to link, or am I using the wrong syntax?
Some edits after hint with calling:
cmake -DCMAKE_PREFIX_PATH=/opt/QT/5.4/gcc_64/ ../src/
I also have deleted the CMAKE_MODULE_PATH variable.
I still get the same error:
CMake Error at CMakeLists.txt:3 (find_package):
Found package configuration file:
/usr/lib/x86_64-linux-gnu/cmake/Qt5/Qt5Config.cmake
but it set Qt5_FOUND to FALSE so package "Qt5" is considered to be NOT
FOUND. Reason given by package:
The Qt5 package requires at least one component
I dont know why this is happening after reading https://blogs.kde.org/2008/12/12/how-get-cmake-find-what-you-want-it
. There it is stated, that the path will be searched before the default search directories. The path I used seems to be right now:
/opt/QT/5.4/gcc_64/
Adding subfolder gcc_64 must be right, as this subfolder has "lib", "include" ect as subfolders.
I remeber that I have called also
sudo apt-get install QT5-default
some time ago. This did not help, I needed the installer from QT. Although I removed qt5-default again to prevent cmake from finding the wrong package configuration file, the same error appears.
See discussion below, moved to here:
Cmake and QT5 - Include only takes one argument
You have to use the variable CMAKE_PREFIX_PATH, i.e. invoke
cmake -DCMAKE_PREFIX_PATH=/opt/QT/5.4 <path_to_source>
at the root of your build tree. Then you can use find_package(Qt5 ...) etc. See also the Qt5 cmake docs.
Rough distinction within you focus:
CMAKE_MODULE_PATH is for "general" inclusion of files and "FindXXX.cmake" files in find_package(... MODULE).
CMAKE_PREFIX_PATH has a special meaning in the context of find_package(... CONFIG).
After addition of new content
this is a new error and thus should require a new question. if you had that error before you'd have already found the Qt5 config.cmake file :-)
anyways, as the error tells you
The Qt5 package requires at least one component
you need to specify a component of the Qt5 package. As the cmake docs say, you need to use the find_package(Qt5 REQUIRED COMPONENTS Widgets Core ...) interface so that cmake (better: the logic of Qt5 FindQt5.cmake) knows what to look for. that will give you the targets Qt5::Widgets etc to use/link against.
i dont know if the syntax find_package(Qt5Widgets REQUIRED) works, could be equivalent.

zlib in Qt - QtZlib not present

I am using QuaZip library, which has zlib dependency. I want to compile my CMake managed application under Archlinux and Windows 7, in both I have Qt 5.3.0 installed.
On Linux:
I have read here "how to add zlib to an existing qt installation" that zlib is a native part of Qt installation. But in archlinux there is no such directory.
Of cause I searched through all other Qt include directories including QtCore, but there was no sign of zlib. On the other hand system installation of zlib can be found on archlinux through FindZLIB.cmake module.
On Windows:
In the Windows installation of Qt there is QtZlib folder in Qt include directory, so it can be included. Nevertheless, compiler always complain that he cannot link zlib functions from library, error log here. I've also tried to set external zlib library manually through TARGET_LINK_LIBRARIES but with no success.
Have anybody experiance with linking Zlib under Qt5 using CMake ?
Qt's zlib is an internal implementation detail. You're not supposed to use it. You need to link your own copy of zlib, just as you would need to if you weren't using Qt at all.
1) You should use your package manager on Archlinux and your own installation on Windows. Do not rely on the Qt third-party installation. It may be there today, but disappear at any certain moment when a new release comes out.
This is what I would suggest you doing on your Archlinux box:
pacman -S zlib
2) Also, you should use FindZLIB.cmake for finding zlib the following way in your CMakeLists.txt:
find_package( ZLIB REQUIRED )
if ( ZLIB_FOUND )
include_directories( ${ZLIB_INCLUDE_DIRS} )
target_link_libraries( YourProject ${ZLIB_LIBRARIES} )
endif( ZLIB_FOUND )

Finding package OpenCV with CMake

I've done as follows:
I have set OpenCV_DIR variable to my build path set to $(OPENCV_ROOT)/build/x86/vc11/lib.
In my CMakeLists.txt I call find_package function:
find_package( OpenCV REQUIRED )
Some variables connected to OpenCV should be set, but they are set incorrectly. Ex. OpenCV_INCLUDE_DIRS should be set to
$(OPENCV_ROOT)/build/include
or
$(OPENCV_ROOT)/include
but instead of it it's set to
$(OPENCV_ROOT)/build/x86/vc11/lib/include;$(OPENCV_ROOT)/x86/vc11/lib/include/opencv
What to do to have the right paths?
I had built OpenCV from source to make sure that all the variables and options were set correctly.. For the purpose of explanation, let's say your CMAKE_INSTALL_PREFIX is set to C:/opencv/.. This is where your OpenCV_DIR variable should point to..
To your system environment path, add C:/opencv/bin/ (just so that all login instances from your computer have access to it and also makes it easier for VS to recognize it later on, in my experience) to the PATH variable.. Make sure you build both debug and release version of the projects and build the INSTALL project for both..
Hope this helps.
Side note: For easy path editing, I use a freeware called RapidEE
I was recently fighting with compilation of OpenCV to get minimal module necessary and then automatically including this in my project. I ended up using it the following way:
CMakeLists.txt:
find_package(OpenCV CONFIG REQUIRED PATHS <path to the install dir>)
target_link_directories(<target> PUBLIC
${OpenCV_LIB_DIRS}
)
target_link_libraries(<target>
${OpenCV_LIBS}
)
target_include_directories(<target> PUBLIC
${OpenCV_INCLUDE_DIRS}
)
Using cmake 3.16
OpenCV 4.x