I have a Linux based operating system that, by default, does not provide a default.conf for qtchooser which results in:
$ qmake
qmake: could not find a Qt installation of ''
$ qmlcachegen
qmlcachegen: could not find a Qt installation of ''
Generally you would solve this by manually specifying a version:
$ qmake -qt5 -v
QMake version 3.1
Using Qt version 5.11.3 in /usr/lib/x86_64-linux-gnu
$ QT_SELECT=5 qmake -v
QMake version 3.1
Using Qt version 5.11.3 in /usr/lib/x86_64-linux-gnu
It can also be solved by creating files such as:
/etc/xdg/qtchooser/default.conf
/usr/share/qtchooser/default.conf
etc.
However, for the sake of this question my OS does not provide this file.
Problem
When using CMake 3.13.4 this works fine (optionally by providing -DCMAKE_PREFIX_PATH=/path/to/qt):
find_package(Qt5 REQUIRED COMPONENTS Core)
qt5_add_resources(RESOURCES assets.qrc)
target_link_libraries(my_app PUBLIC
Qt5::Core)
However, when trying to use QML ahead-of-time compilation we are instructed to replace qt5_add_resources() with qtquick_compiler_add_resources()
find_package(Qt5 REQUIRED COMPONENTS Core QuickCompiler)
qtquick_compiler_add_resources(RESOURCES assets.qrc)
[...]
Which will use /usr/lib/x86_64-linux-gnu/cmake/Qt5QuickCompiler/Qt5QuickCompilerConfig.cmake to find the location of the binary qmlcachegen and use that to compile QML files.
So CMake ends up doing something like execve("/usr/bin/qmlcachegen", resource_files);.
But /usr/bin/qmlcachegen does not know about any Qt installation, so it fails:
[ 15%] Generating qml_components_ChatScrollToBottomButton_qml.cpp
make[3]: *** [src/CMakeFiles/conversations_autogen.dir/build.make:85: src/qml_components_Chat_qml.cpp] Error 1
qmlcachegen: could not find a Qt installation of ''
Question
Even though we've used CMake to determine what Qt installation to use, qmlcachegen has its own logic for finding the path to Qt. Judging from Qt5QuickCompilerConfig.cmake there is no way to provide either an environment variable QT_SELECT or pass the -qt5 argument.
Is it the responsibility of my OS to provide a default.conf so that Qt can find the installation?
Is it the responsibility of CMake to correctly pass the necessary context before calling qmlcachegen?
qt5-default adds /usr/lib/x86_64-linux-gnu/qtchooser//default.conf and thus qmake and qmlcachegen will be able to find the default Qt install.
Related
I am trying to develop an application using GreatScottGadget's Ubertooth One. To start, I need to be able to use the libusb library. I'm working with Ubuntu 20.04.
I have a simple CMakeLists.txt file that sets the module path to a path in my project that contains all the Find*.cmake files that I stole from the ubertooth repository here. I include libusb like so:
find_package(USB1 REQUIRED)
When I run CMake, this is the error I get:
Could not find package configuration file provided by "USB1" with any of the following names:
USB1Config.cmake
usb1-config.cmake
Add the installation prefix of "USB1" to CMAKE_PREFIX_PATH or set
"USB1_DIR" to a directory containing one of the above files. If "USB1"
provides a separate development package or SDK, be sure that it has been
installed.
As far as I can tell, I have libusb already installed. apt list --installed | grep libusb shows libusb-1.0.0-dev/focal,now 2:1.0.23-2build1 amd64 [installed] (among others). I can see the shared object in /usr/lib/x86_64-linux-gnu
$ ls /usr/lib/x86_64-linux-gnu | grep libusb
libusb-0.1.so.4
libusb-0.1.so.4.4.4
libusb-1.0.a
libusb-1.0.so
libusb-1.0.so.0
libusb-1.0.so.0.2.0
libusbmuxd.so.6
libusbmuxd.so.6.0.0
Additionally, I can build the host code provided in the ubertooth repository just fine. In the CMake output, I see the following:
-- Checking for module 'libusb-1.0'
-- Found libusb-1.0, version 1.0.23
-- Found LIBUSB: /usr/lib/x86_64-linux-gnu/libusb-1.0.so
Looking through the ubertooth repository, I don't see anything special they are doing to find the package. The host project adds libubertooth as a subdirectory, in in its CMakeLists.txt, it uses the same method I have to find the library. I'm not seeing any other differences.
Maybe I'm misunderstanding and the libubertooth subdirectory isn't where the library is being found. Maybe there's some global config that I'm not setting. I haven't managed to find whatever it is.
I checked the libusb homepage and downloaded the source, but I didn't find any USB1Config.cmake files, so I'm not sure how this is supposed to work.
What am I missing to be able to find the library and use it in my project?
This is because you don't have a FindUSB1.cmake in you project. You can find it on ubertooth/host/cmake/modules/FindUSB1.cmake.
BTW, don't use stole, you can find ubertooth's license, it's GPL-2.0
I have git cloned, built (with MSVC for both Debug and Release) and then installed wxWidgets:
cmake -B build wxWidgets
cmake --build build --config <CONFIG>
cmake --install build --prefix my_install --config <CONFIG>
with <CONFIG> = Debug and <CONFIG> = Release.
Then I used the following CMake script to link against it, as suggested by the wiki:
cmake_minimum_required(VERSION 3.16)
project(Test)
add_executable(Test WIN32 Main.cpp)
# wxWidgets
SET(wxWidgets_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../thirdparty/my_install)
find_package(wxWidgets COMPONENTS core base REQUIRED)
include(${wxWidgets_USE_FILE})
target_link_libraries(Test PRIVATE ${wxWidgets_LIBRARIES})
# Copy runtime DLLs to the directory of the executable.
add_custom_command(TARGET Test POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Runtime Dlls: $<TARGET_RUNTIME_DLLS:Test>"
)
My goal is to automatically copy the DLLs into the directory of the built executable, so that they can be found at runtime. For that I'm using the TARGET_RUNTIME_DLLS generator expression (follwing the sample code in the docs). In the code above, I only print out the expression at build time for testing purposes. The problem is that it is empty.
The approach worked for me before when installing and linking SDL, but SDL provides package configuration files which create imported targets, defining the DLL location(s) via IMPORTED_LOCATION_RELEASE or IMPORTED_LOCATION_DEBUG. For wxWidgets one is apparently supposed to use the FindwxWidgets.cmake script shipped with CMake, which sadly doesn't define the produced binaries. Maybe that's why TARGET_RUNTIME_DLLS isn't populated.
Does anyone know, either how to get TARGET_RUNTIME_DLLS filled or how to obtain the list of built wxWidgets DLLs for the current configuration (Release/Debug) post build copying?
Thanks a lot in advance!
I am dealing with a similar problem.
First sanity checks:
You have to work on windows platform otherwise this feature does not
work.
Your Cmake is 3.21 or above
Next comes fuzzy part. I think the library that you are trying to include have to be a Shared Imported library and you have to set a set_target_properties for IMPORTED_IMPLIB which is a path to a .lib file of sort (dll import library, I think it is called) So you have to make sure that it is all set in the package library that you trying to link with your executable.
If you have those dll avaiable and you just want to use them and not actually build them then you can write your own cmake script that will do just what I said above. Then you can include that cmake file in your project and then link against your app.
Note: I also work on similar issue right now and what I just said have not been working very reliably. I got some dlls to be copied and some do not.
Edit:
Cmake docs give a more detailed explanation on how this library setting should look like if you use find_package feature.
Found here: https://cmake.org/cmake/help/latest/command/add_library.html#imported-libraries
An UNKNOWN library type is typically only used in the implementation
of Find Modules. It allows the path to an imported library (often
found using the find_library() command) to be used without having to
know what type of library it is. This is especially useful on Windows
where a static library and a DLL's import library both have the same
file extension.
I am really struggling to setup wxWidgets to work on Windows and CMake and would appreciate some help.
I have downloaded wxWidgets 3.1.4, run the setup (which extracted to C:\CPP_lib\wxWidgets) and then ran the following commands in the terminal:
cd C:\CPP_lib
mkdir wxWidgets-install
cmake C:\CPP_lib\wxWidgets -DCMAKE_INSTALL_PREFIX=C:\CPP_lib\wxWidgets-install -DwxBUILD_SHARED=OFF
cd wxWidgets-install
cmake --build . --target install
I have environment variables CMAKE_PREFIX_PATH set to C:\CPP_lib and wxWidgets_DIR and wxWidgets_ROOT_DIR both set to C:\CPP_lib\wxWidgets-install.
However, when I have a simple CMake project that calls find_package(wxWidgets), I get the following message in the terminal:
Found wxWidgets: winmm;comctl32;uuid;oleacc;uxtheme;rpcrt4;shlwapi;version;wsock32
missing components: core base png tiff jpeg zlib regex expat
Please help - I have been struggling for a while now :(
It turns out the issue was a very specific one related to vcpkg.
I had pointed CMake to my vcpkg toolchain file (even though wxWidgets was installed independent of vcpkg) and this was causing issues with finding wxWidgets i.e. vcpkg was preventing wxWidgets (a non-vcpkg installation) from being found.
I believe this is a vcpkg bug, although am not sure, but have reported it anyways.
I've tried official howto but failed. I got error:
"The procedure entry point InterlockedCompareExchange#12 could not be located in the dynamic link library libstdc++-6.dll"
The problem was due the old gcc compiler, bundled with DevKit from rubyinstaller.org (4.5 vs 4.8 on my PC). Use MSYS instead. Assume we have zeromq source inside D:\libs\zeromq, then the procedure is:
Download GUI MinGW installer.
Install base and MSYS (if you already have working gcc compiler you probably only need MSYS).
Launch MSYS environment by executing C:\MinGW\msys\1.0\msys.bat.
Follow Using MSYS with MinGW section:
mount c:/mingw /mingw
cd /d/libs/zeromq
./configure --prefix=/mingw
make
Copy /d/libs/zeromq/src/.libs/libzmq.dll to your desired place.
In fact I needed to use ZeroMQ with C++, so I downloaded zmq.hpp, moved it to include directory, and compiled hwserver.cpp to test it:
C:\MinGW\bin\g++.exe -o hwserver hwserver.cpp -L. -lzmq -ID:\libs\zeromq\include
It worked, but when I launch it I got:
Assertion failed!
Program: D:\tmp\zmq\hwserver.exe
File: D:\libs\zeromq\include/zmq.hpp, Line 280
Expression: rc == 0
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
I've managed to get rid of this failure by commenting lines 279, 280. Similar issue
I am using CMake to build a Qt5 project on OS X. I need to create a build process that is as simple as possible for others.
By default Qt5 installs to the home folder on OS X. However, it then places its files within a directory named after the exact version number, e.g. 5.2.1.
At the moment I am using these lines in my CMake file:
set(QT5_PATH $ENV{HOME}/Qt5.2.1/5.2.1/clang_64/ CACHE PATH "Path to Qt5")
set(QT5_MODULE_PATH ${QT5_PATH}/lib/cmake)
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT5_MODULE_PATH})
This works, but unfortunately breaks with each minor update of Qt as the 5.2.1 needs to be changed to 5.2.2, etc.
In Windows there are environment variables that can be used to find Qt. Is there anything similar in OS X that I can use within CMake to find a Qt installation?
Use find_package instead of juggling with the paths yourself. Then your users can rely on standard CMake mechanism instead of figuring out your own CMake code.
Use find_package(Qt5Widgets) to get targets like Qt::Widgets to link against and for the includes.
Similar for Qt5Core and whatever part of Qt 5 you need.
See Qt's documentation: http://doc.qt.io/qt-5/cmake-manual.html