Qt resources not displaying when building with cmake (windows) - c++

I have a Visual Studio Qt solution that I am moving to Cmake.
Everything is compiling and working fine, except all icons (.png) that I have in *.qrc file are not displayed at all.
My CMakeLists.txt is standard for a Qt project:
...
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(SOURCE_FILES ...)
set(HEADER_FILES ...)
set(UI_FILES ...)
set(RESOURCE_FILES resources/res.qrc)
add_executable(project WIN32 ${SOURCE_FILES} ${HEADER_FILES} ${UI_FILES} ${RESOURCE_FILES})
find_package(Qt5 REQUIRED COMPONENTS ...)
target_link_libraries(project PRIVATE Qt5::Core etc...)
I think that all icons are in fact embedded into .exe, because:
1. If I remove all paths from the qrc file and recompile, the .exe size is decreased by the icons size
2. I checked the qrc_*.cpp generated by AUTORCC and all the images are there.
But when I am iterating over all my resources using this code snippet
QDirIterator it(":", QDirIterator::Subdirectories);
while (it.hasNext()) {
qDebug() << it.next();
}
the icons are NOT there.
I have tried an alternative approach with qt5_add_resources() instead of AUTORCC and the result is the same.
I also have all the iconengines, imageformats, platforms, styles folders on the same path as .exe.
Edit:
Added the whole Cmake part of the project to github.

Considering the discussion we had in your post comment, CMake works as expected and the resources are loaded into your application.
As you mentioned "When I run my app from clion it shows the images. If I copy the exe to a folder with *.dll etc it doesn't.", so either:
Some files are missing when you copy them, you should try to use windeployqt to correctly copy what's needed at runtime
Or the problem comes from the way the qrc is neing loaded, then, I suggest that you debug the content of qrc_*.cpp files (your can debug it after you copied it outside clion) and see why it fails to load the resource
Anyway this looks more like a deployment issue than a configuration/compilation issue.

Related

cmake + VS = "Microsoft.VisualStudio.ProjectSystem.References.UnresolvedBuildDependencyProjectReference"

I have a very simple CMake solution with one shared library and one executable.
CMakeLists.txt:
cmake_minimum_required(VERSION 3.24)
project(Test)
add_subdirectory(A)
add_subdirectory(B)
A/CMakeLists.txt:
cmake_minimum_required(VERSION 3.24)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project(A)
file(GLOB_RECURSE Hdr CONFIGURE_DEPENDS inc/*)
file(GLOB_RECURSE Src CONFIGURE_DEPENDS src/*)
add_library(${PROJECT_NAME} SHARED ${Hdr} ${Src})
target_include_directories(${PROJECT_NAME} BEFORE PUBLIC inc PRIVATE src)
set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY PUBLIC_HEADER ${Hdr})
A/CMakeLists.txt:
cmake_minimum_required(VERSION 3.24)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project(B)
file(GLOB_RECURSE Src CONFIGURE_DEPENDS src/*)
add_executable(${PROJECT_NAME} ${Hdr} ${Src})
target_include_directories(${PROJECT_NAME} BEFORE PUBLIC inc PRIVATE src)
target_link_libraries(${PROJECT_NAME} PRIVATE A)
I use all these to generate a VS2022 solution and open it:
cmake.exe -S . -B tmp
start tmp\Test.sln
The CMake target "A" seems to be taken into consideration because I see the public headers folder (A/inc) amongst "Additional Include Directories" of VS project "B".
When I navigate in VS to B/References I see a reference to project "A" as expected:
but when I double-click it or try to see its properties , I get:
"Microsoft.VisualStudio.ProjectSystem.References.UnresolvedBuildDependencyProjectReference"
Is there a CMake+VS bug? or I do something wrong?
NOTE: if I create the entire solution by hand from Visual Studio (without CMake), it works fine!
I'm using CMake 3.24.1 and VS2019 and I'm facing the same problem. From what I see on my PC, I can conclude it's certainly not a CMake issue. That's because, after having used CMake to generate my VS Solution, I'm able to get rid of the problem by simply modifying the vcxproj file(s) inside my solution. However, there still is one thing I don't understand yet and what makes me to suspect VS having some kind of problem. Here is what I see/do.
My CMake generated solution contains one console application that depends on a number of static library projects: the projects are added to the application's References section. Now, when I double click on one of them I get the following message:
The Full Path property of the referenced project inside the Properties pane shows the same message.
To fix this I open the console application's vcxproj file and look for the following entry:
I remove the complete ProjectReferences element for each configuration, save the vcxproj file and restart my solution. In my case the problem is then solved: no more annoying message and the Full path property resolves to a valid path. But ...
Since I removed this ProjectReferences element the Link Library Dependencies property now defaults to Yes. I can verify this by opening the Property window and check the proper field. It shows Yes.
Now, I my case CMake generated a solution in which LinkLibraryDependencies was set to false. Therefore, I again open my console application's Property pane and set the Link Library Dependencies property back to false. I close the Property window and try rebuilding my project: no problem. Running the application: no problem.
When, after updating the Link Library Dependencies property with false inside the Property pane, I save my project and then open the vcxproj file using a text editor, I notice the ProjectReferences element has been added again. It's set to false. That is as expected. But, when close and I re-open the solution the initial problem is back again. However, when I change the ProjectReferences property value from false to true inside the vcxproj file using a text editor, the problem stays away after opening the solution!!
Based on the experience with my VS Solution, I come to the following conclusion:
I can get rid of the problem by removing the complete ProjectReferences element from the vcxproj file (use text editor) and then re-open the solution. But then the Link Library Dependencies property defaults to Yes
I can then change the Link Library Dependencies property back and forth to Yes and No without the problem shows up again. (Note: what I find strange is that the vcxproj file is not updated when I modify some properties and close the Property window.
When the application's project is saved to disk (vcxproj file gets updated), re-opening the solution will bring back the problem but only in case the Link Library Dependencies property was saved as false.
Maybe I overlook something, but this looks as a VS problem to me. Not a showstopper but annoying it is.

OpenSceneGraph plugin not included in Conan?

I'm trying to do simple mesh viewer using OpenSceneGraph and I want to use Conan for dependencies.
The compilation is working well in both debug and release mode (I'm compiling on Windows for now with msvc toolchain).
As soon as I try to load any kind of mesh, the osgDB::readNodeFiles just fail. Looks like the plugin are not linked to the final binary.
I checked in the Conan's package, the plugin list of .lib exists and are supposed to be linked I guess.
What could I miss ?
There is my conanfile.txt :
[requires]
openscenegraph/3.6.5
[generators]
cmake
The CMakeLists.txt is also straightforward :
cmake_minimum_required(VERSION 3.17)
# Set a default build type if none was specified
set(default_build_type "Release")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE
STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
set(PROJECT_NAME 3D_radio)
project(${PROJECT_NAME})
if(EXISTS ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
set(CMAKE_CONFIGURATION_TYPES ${CONAN_CONFIGURATION_TYPES})
else()
message(WARNING "The file conanbuildinfo.cmake doesn't exist, you have to run conan install first")
endif()
# get all source files
file(GLOB all_SRCS
"include/*.h"
"source/*.cpp"
)
# add executable and addShader libraries
add_executable(${PROJECT_NAME} ${all_SRCS} source/main.cpp include/main.h)
target_include_directories(${PROJECT_NAME} PRIVATE
include
${CONAN_INCLUDE_DIRS}
)
target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS})
And the code is also very simple :
int main(int argc, char **argv) {
// use an ArgumentParser object to manage the program arguments.
osg::ArgumentParser arguments(&argc,argv);
// read the scene from the list of file specified commandline args.
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
// if not loaded assume no arguments passed in, try use default mode instead.
if (!loadedModel) loadedModel = osgDB::readNodeFile("cow.osgt");
// if no model has been successfully loaded report failure.
if (!loadedModel)
{
std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
return 1;
}
}
The console output :
C:\...\cmake-build-release\bin\program.exe C:\...\first.obj
C:\...\cmake-build-release\bin\program.exe: No data loaded
Error reading file C:\...\first.obj: read error (Could not find plugin to read objects from file "C:\...\first.obj".)
Error reading file cow.osgt: read error (Could not find plugin to read objects from file "cow.osgt".)
I have no problem to open those files in Paint 3D for example. So I know they are correct. The problem looks to come from linking. Any idea ?
I found the solution.
I'm compiling statically the program, the plugins are linked to the final binary but the plugin registry look for a dynamic library (osgdb_obj.dll for example).
If you have the same problem, you have to register manually the plugin :
USE_OSGPLUGIN(obj)
USE_GRAPHICSWINDOW() // and you may want this to get a window
The "plugin list of .lib" which you highlighted are, unlike static libs, import libraries which will introduce a dynamic DLL dependency in the final link. The plugin DLLs still have to be present somewhere from where the linker can then load them off, at runtime. OSG plugins are typically loaded relative to the value of OSG_LIBRARY_PATH env variable. Setting this to the folder holding the, say "osgPlugins-3.6.5" directory, should successfully load the plugins.
SET OSG_LIBRARY_PATH=C:\TOOLS\vcpkg\installed\x64-windows\debug\plugins\
Few things which could still break this are: Debug/Release plugins mismatch and some spurious space in the OSG_LIBRARY_PATH env variable, like this one (logged via SET OSG_NOTIFY_LEVEL=DEBUG)
FindFileInPath() : trying C:\TOOLS\vcpkg\installed\x64-windows\debug\plugins\ \osgPlugins-3.6.5\osgdb_osgd.dll
The space above was present in the OSG_LIBRARY_PATH env

Cant compile OpenCV Source file with my project

This question is a continuation of one I asked before
I have a project that uses the librealsense library and OpenCV. librealsense works but I cannot include OpenCV in my project for the life of me. There is currently only 1 CPP file and 1 HPP file, this is the cmake file of the root
project(peoplecounting)
add_subdirectory(libs/librealsense-master)
add_subdirectory(libs/opencv-4.3.0)
set(OpenCV_DIR ${CMAKE_BINARY_DIR}/libs/opencv-4.3.0)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable (CMakeRealSense "CMakeRealSense.cpp" "CMakeRealSense.h")
find_library(realsense2 HINTS libs/librealsense-master)
find_library(opencv HINTS ${CMAKE_BINARY_DIR}/libs/opencv-4.3.0)
target_link_libraries(CMakeRealSense ${OpenCV_LIBS} realsense2)
I have both source files in a libs folder(so directory would look like root/libs/opencv-4.3.0). I am new to cmake so I just might be missing something but its driving me nuts
Some extra notes
1, OpenCV does build the libs when I can build the project, if I remove any include from my self written code it wont make errors which lets me build the project. This does make the opencv librairys which makes me think the linking is the issue
2, If I dont add a project as a executable it does see a opencv include
3, I am doing this to make the project portable, it has to work on a rpi down the line so being able to build it all from source could make it much more portable
EDIT 1
So I did some diging in my files, the exe gets outputted into
root\out\build\x64-Debug\bin but this folder does not only contain the librealsense dll but also the opencv ones. This would make it seem that the exe knows about the library but doesnt want to use it some how? This is very strange to me too
EDIT 2
I managed to find_package(OpenCV) by setting
CMAKE_PREFIX_PATH to win-install which contained a config file, problem now is that iam missing the include dir in said folder
EDIT 3
New error seems to be
Target "opencv_highgui" INTERFACE_INCLUDE_DIRECTORIES property contains
path:
"root/opencv-4.3.0/modules/dnn/include"
which is prefixed in the source directory.
I read somewhere that OpenCV prevents source files being used or something to prevent corruption but now now again at a end when it comes to what iam suppose to be doing
Updated CMake file
project(peoplecounting)
add_subdirectory(librealsense-master)
add_subdirectory(opencv-4.3.0)
set(OpenCV_DIR ${CMAKE_BINARY_DIR})
set(INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_BINARY_DIR}/")
set(BUILD_SHARED_LIBS OFF)
find_package(OpenCV CONFIG REQUIRED)
add_library(opencv INTERFACE)
include_directories(${OpenCV_INCLUDE_DIRS})
#add_executable (CMakeRealSense "CMakeRealSense.cpp" "CMakeRealSense.h")
add_executable(RealSenseTest "TestRealSense.cpp")
find_library(realsense2 HINTS librealsense-master)
message(" cv_libs: " ${OpenCV_INSTALL_PATH})
message(" cv_includes: " ${OPENCV_INCLUDE_DIRS})
target_include_directories(opencv INTERFACE "${OpenCV_INCLUDE_DIRS}")
target_link_libraries(RealSenseTest "${OpenCV_LIBS}" realsense2)```

Why can CLion correctly build and link Qt, but not run my executable?

Summary
I am trying to compile ánd run/debug Qt code in Clion on Windows. Both CMake and the building process return no errors.
The following scenarios occur:
When I try to run I get Process finished with exit code -1073741511 (0xC0000139)
When I try to debug I get Process finished with exit code 1
When I try to run the executable via Windows CMD directly, the executable runs as intended.
When I copy all dll files from ../Qt/5.12.6/mingw73_64/bin to the project's cmake-build-debug folder, the executable runs and debugs within CLion as expected.
My setup
Windows 10
Qt 5.12.6 (mingw73_64 build)
CLion 2019.2.5
MinGW (x86_64-8.1.0-win32-seh-rt_v6_rev0)
CMake (bundled, 3.15.3)
Other findings
I believe there are many related topics on StackOverflow that deal with the same issue. But none manage to provide a definitive answer to what I believe to be a Path/Environment issue. Many suggestions boil down to "Add Qt to your path/PATH/Path environment variable and reboot reboot reboot!", and/or mostly pertain to linux installs. Hence I hope this becomes a more complete question and answer for people running into the same error code within this context, as it is likely related to this same issue.
As things work outside of CLion (as shown by (3)) and work inside of CLion when I copy DLLs (4), I believe I am dealing a dynamic linking issue as a result of CLion related environment issues. Adding the Qt bin folder, which is C:\Qt\5.12.6\mingw73_64\bin, to my System Environment Variables made it so I could run the exe file directly from CMD. Note that I added the Qt bin folder path to the Path variable.
Given that some mentioned online that it is possibly an issue with the user variables due to CLion running as a certain system user, I also added said path as a User Environment Variable, again Path. But alas.
Additionally, I tried adding it as an environment variable directly in CLion via Settings -> Appearance & Behavior -> Path Variables. Here I tried mapping the Qt bin folder to Path, PATH, and QT_DIR respectively. Still no success, even though I tried many reboots. Both Windows restarts and real shutdowns were attempted many times in between changing paths etc.
Main question:
How can I resolve the issue I described, so I can run and debug my Qt builds in CLion without having to copy Qt related DLLs to my cmake-build-debug where the executable is located.
CMakeLists.txt
Within Settings -> Build, Execution, Deployment -> CMake I have set CMake options: to -DCMAKE_PREFIX_PATH=C:\\Qt\\5.12.6\\mingw73_64\\lib\\cmake
cmake_minimum_required(VERSION 3.8)
project(HelloWorld)
set(CMAKE_CXX_STANDARD 14)
# Include a library search using find_package()
# via REQUIRED, specify that libraries are required
find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
find_package(Qt5Widgets REQUIRED)
set(SOURCE_FILES main.cpp)
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
# specify which libraries to connect
target_link_libraries(${PROJECT_NAME} Qt5::Core)
target_link_libraries(${PROJECT_NAME} Qt5::Gui)
target_link_libraries(${PROJECT_NAME} Qt5::Widgets)
main.cpp
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QLabel>
int main (int argc, char * argv []) {
QApplication app (argc, argv);
QWidget widget;
widget.resize (640, 480);
widget.setWindowTitle ("Hello, world !!!");
QGridLayout * gridLayout = new QGridLayout (& widget);
QLabel * label = new QLabel ("Hello, world !!!");
label-> setAlignment (Qt :: AlignVCenter | Qt :: AlignHCenter);
gridLayout-> addWidget (label);
widget.show ();
return app.exec ();
}
This has been resolved for me in the meanwhile.
Solution was as follows:
Go to edit configurations
Add the Qt bin folder to Working directory
Hit OK and/or APPLY
Now I am able to run and build my Qt applications from within CLion directly.

QtCreator CMake project - how to show all project files

I use QtCreator to open CMake project. Some directories apart from CMakeLists.txt contains only headers files *.h and for those directories QtCreator in the project tree view shows only CMakeLists.txt. How to fix that ? I need to see all project files from QtCreator.
Viewing project as a file system is not a solution at all cause your project editor settings for example would not apply.
And I do not like to add headers to executable target, cause they do not actually belong there. You effectively cripple the project file to work nicely with one particular IDE... not good.
The cleaner option IMHO would be:
FILE(GLOB_RECURSE LibFiles "include/*.hpp")
add_custom_target(headers SOURCES ${LibFiles})
As a bonus you get your includes shown in a separate folder.
(borrowed from https://cmake.org/pipermail/cmake/2012-August/051811.html)
I would suggest you switching your project view to File System. This would display a view where you could view any file you want:
You might want to split your project view into two by clicking the second to right button, if you still desire the Projects mode.
You should add header files to the list of your source files: add_executable(${Executable} ${Sources} ${headers})
You can use GLOB_RECURSE if have many header files:
FILE(GLOB_RECURSE INC_ALL "headers/*.h")
include_directories("headers")
add_executable(main "main.cpp" ${INC_ALL})
Don't forget to run CMake again (Build>Run Cmake).
Based on another thread asking the same question, I found a generic solution to the problem, working for all IDE's (at least tested with QtCreator and Visual Studio).
Can be found here : https://github.com/sauter-hq/cmake-ide-support
# \brief adds for the given target a fake executable targets which allows all
# headers and symbols to be shown in IDEs.
# \param target_name Which target properties should be added to the IDE support target.
function(target_add_ide_support target_name)
if (NOT TARGET ${target_name})
message(FATAL_ERROR "No target defined with name ${target_name}, cannot target_add_ide_support it.")
endif()
set (target_for_ide "${target_name}_ide_support")
if (NOT TARGET ${target_for_ide})
file(GLOB_RECURSE target_for_ide_srcs "*.h" "*.hpp" "*.hxx" "*.c" "*.cpp" "*.cxx")
add_executable(${target_for_ide} ${target_for_ide_srcs})
set_target_properties(${target_for_ide} PROPERTIES EXCLUDE_FROM_ALL 1 EXCLUDE_FROM_DEFAULT_BUILD 1)
endif()
get_target_property(dirs ${target_name} INCLUDE_DIRECTORIES)
target_include_directories(${target_for_ide} PRIVATE ${dirs})
endfunction(target_add_ide_support)
Usage is then for any targets in the CMakeLists, add the following call (can be made in top-most CMakeLists.txt after all add_subdirectory :
include(add_ide_support.cmake)
target_add_ide_support(some-target)
You can try CMakeProjectManager2. Code to display all files already propagated to upstream as a proof of concept. Concept applied but code can't be applied as-is for some reasons. So, simple wait feature in upstream.
There is a closed bug report about this issue: CMake project shows no files.
In that particular case the issue was with the chosen generator, Ninja, which is not well supported by QtCreator.
Please change that to "CodeBlocks - Ninja". Creator needs the CodeBlocks extra generator.
You should see a warning about that when hovering the kit (and the kit should have a warning icon in front of its name).
Using CodeBlocks - Ninja solved it for me too.
Overall, it may help to try up a few generators...