Running a basic Qt application in Docker - c++

I am trying to run a basic console application (developed in Qt) in docker for windows. Development environment is windows 10, compiler VC2015, 32bit Application.
It is hello world and idea was to find the issues, before I try to port the actual application.
The code is simplest c++ code:
#include <QCoreApplication>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::cout<<"Hello world";
return a.exec();
}
The Dockerfile is:
# Comment:
#It needs a Microsoft environment to run
FROM microsoft/nanoserver:latest
#Create a folder inside the home folder in the Container Operating System
RUN mkdir -p C:\HelloWorld
#Copy the excutable from this folder to the folder inside the Container
Operating System.
COPY . /HelloWorld/
#Run the application inside the container operating system.
CMD ["C:\\HelloWorld\\docker_HelloWorld.exe"]
My expected end result was a console/shell output of "Hello world". But I get nothing. Can someone point out what is missing?
Thanks.

I suspect that nanoserver images only supports x64 applications, if possible please build your application as x64 and run it inside the nanoserver with its dependencies.
If not possible to build as x64, then you can use windowsservercore containers to run the x86 applications.
You should copy the dependency assemblies with that application, other wise it will not work.

Related

Qt plugin not loaded

I have problems loading the built-in plugins for iconengines for a deployed application. Below is a minimal program to show the problem. It is not exactly the same, because Qt scans the plugin directories at start and registers it according to the file suffix, but I hope when I can get the minimal program to run, then the automatic scanning works, too.
main.cpp:
#include <QCoreApplication>
#include <QPluginLoader>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QPluginLoader loader("C:/Qt/5.15.1/msvc2019_64/plugins/iconengines/qsvgicon.dll");
if (loader.load()) {
qDebug() << "load ok";
} else {
qDebug() << "load failed";
}
return a.exec();
}
and PluginTest.pro:
QT -= gui
CONFIG += c++11 console
CONFIG -= app_bundle
SOURCES += main.cpp
When I start it from the Qt Creator IDE, version 4.13.1, with Visual Studio 2019, 64 bit compiled, it prints "load ok". Now I do this from a "x64 Native Tools Command Prompt for VS 2019" command prompt in the project directory:
set PATH=%PATH%;C:\Qt\5.15.1\msvc2019_64\bin
mkdir deploy
copy release\PluginTest.exe deploy
windeployqt --release release\PluginTest.exe --plugindir deploy\QtPlugins
When I start PluginText.exe from the command prompt in the deploy directory, I get the output "load failed".
Additional information: when I set set qt_debug_plugins=1 and start the real application, I see these errors:
QFactoryLoader::QFactoryLoader() checking directory path "C:/projects/deploy/QtPlugins/iconengines" ...
QFactoryLoader::QFactoryLoader() looking at "C:/projects/deploy/QtPlugins/iconengines/qsvgicon.dll"
"Failed to extract plugin meta data from 'C:/projects/deploy/QtPlugins/iconengines/qsvgicon.dll'"
not a plugin
The qsvgicon.dll file is identical to "c:\Qt\5.15.1\msvc2019_64\plugins\iconengines\qsvgicon.dll".
I found the problem. It used some other Qt DLLs from the path when starting the application. This fixed it:
xcopy /y c:\Qt\5.15.1\msvc2019_64\bin\*.dll deploy

Terminal command in a ROS package is not executed

I have a little problem with a ROS node even if i think that it's mainly a C++ code problem.
What i want to do is using a script that runs in the terminal (Ubuntu 14.04) within a ROS node.
I'm doing this using the system() command code of the C++ language.
This script has to elaborate a .txt file stored locally on my PC; when i use the script by a normal command line method, obviously i have to navigate to the directory where my script lies first, and then i launch the script.
To replying this on my node, i use 2 system() instances to navigate to the directory and then to run the script.
The problem is that it seems that the node "cannot see" the command which tells it to navigate to the correct directory, so, all i can obtain is an error saying: cannot read the text file.
The only way to start the script correctly is to launch the node after i manually navigate to the directory where it lies the script.
I'm posting the code below, maybe I'm writing something bad or there is another problem that i can't see, since i'm a noob in the world of ROS and coding in general. Thank you in advance, i know that maybe it's a stupid question!
Marco
Here it is the code:
int main(int argc, char **argv)
{
ros::init(argc, argv, "heart_rate_monitor");
ros::NodeHandle n;
system("cd ~/home/marco/catkin_ws/src/heart_rate_monitor");
system("get_hrv -R test.txt");
exit(0);
return 0;
}
Note: i tried also without the ~ .
EDIT: now it seems that's running correctly, here it is the code:
int main(int argc, char **argv)
{
ros::init(argc, argv, "heart_rate_monitor");
ros::NodeHandle n;
chdir("/home/marco/catkin_ws/src/heart_rate_monitor");
system("get_hrv -R test.txt >doc.txt");
exit(0);
return 0;
}
Use chdir to change directory. System will create a new shell and execute the cd command. Please refer to this stack overflow post for more information.
As neo pointed out, the first system call is changing the current directory of the system call, but it does not influence the parent's (i.e. your node's) current directory.
But, if I may, you should try to solve this differently. Apart from hardcoding the path being wrong, you generally should not assume to have access to the source folder on runtime (e.g. if you do an install, the source could be anywhere). Instead:
put additional data in a new directory (e.g. 'data')
add an install target
retrieve the runtime path to your package using ros::package::getPath('your_package_name') and use the full path + "/data/test.txt" in your system call

How to use LibVLC with Qt 5

I'm trying to use LibVLC in a Qt 5 program to open a VLC instance and play a video.
The following code comes from https://wiki.videolan.org/LibVLC_Tutorial/
I'm using Linux.
.pro :
TEMPLATE = app
TARGET = projectLoic
INCLUDEPATH += . vlc
QT += widgets
# Input
HEADERS +=
SOURCES += main.cpp
LIBS +=-lvlc
main :
#include <vlc/vlc.h>
#include <QApplication>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
libvlc_instance_t * inst;
libvlc_media_player_t *mp;
libvlc_media_t *m;
// Load the VLC engine
inst = libvlc_new(0, NULL);
// Create a new item
m = libvlc_media_new_path (inst, "/home/........mp3");
// Create a media player playing environement
mp = libvlc_media_player_new_from_media (m);
// play the media_player
libvlc_media_player_play (mp);
return app.exec();
}
The compilation is fine. But the program immediatly crashes when I build it (with Qt Creator). Any idea?
Many thanks
Many things could cause this crash. The best is to get VLC source code to trace back the issue. Passing the option '--verbose=2' when initializing libVLC can help as well.
In my case the cause of the crash was due to this bug in the ubuntu package of vlc:
https://bugs.launchpad.net/ubuntu/+source/vlc/+bug/1328466
When calling libvlc_new() vlc modules and their dependent libraries are loaded into memory. The qt module of LibVLC was searching for Qt4 shared objects instead of Qt5 (manually installed).
The solution was to rebuild the module cache which was outdated an pointing to Qt4 binaries. You can reset it on the command line:
sudo /usr/lib/vlc/vlc-cache-gen -f /usr/lib/vlc/plugins/
Or pass to vlc the option:
--reset-plugins-cache
I have never used this library, but Are you using exactly this code?
m = libvlc_media_new_path (inst, "/home/........mp3");
This path may be the problem.
What distribution of Linux are you using?
I ran into this same problem with Qt5 and LibVLC, and the primary cause (Ubuntu 12.04 LTS and 14.04 LTS), was that LibVLC was loading the qt4 interface plugin, which conflicted with Qt5. If you check your call stack, you'll most likely see that at a Qt4 library was being loaded, causing the crash.
If this is the problem, there are only 3 options (tested with LibVLC 2.2 and Qt5 on Ubuntu 12.04 and 14.04 LTS 64 bit).
The first (worst) is to delete the qt4 user interface plugin. You can test this is the problem by moving and running and then setting it back. Deleting will break your regular VLC player most likely.
Second option is to create a copy of the plugins directory and set that in your runtime path using VLC_PLUGIN_PATH, environment variable. but I've had trouble getting that to work without changing the original plugin path folder also (which will break your VLC player unless you modify your shortcuts, etc. to also set VLC_PLUGIN_PATH.
The third option, and what I ended up doing, was to custom build my own static LibVLC binary with a few edits to the source code so that it will not load the qt4 interface plugin installed with VLC. You can follow these steps to do this.
1) Download VLC Source Code for your platforms distribution.
http://download.videolan.org/pub/videolan/vlc/
Make sure you download the version matching your distribution. For
example, match the VLC version to what is installed with Ubuntu.
2) Extract source code to folder
3) Install dependencies for the OS distribution
sudo apt-get build-dep vlc
4) Modify src/modules/bank.c
Edit the module_InitDynamic function
Add the following code at the top of the function:
// HACK TO DISABLE QT4 PLUGIN
if(strstr(path, "qt4") != NULL)
return NULL;
// END HACK
3) From terminal
./bootstrap
./configure --disable-qt --disable-skins2 --enable-xcb --prefix=/home/$USER/vlc-custom_build_output_folder_name
./make
./make install
4) Copy/Save the resulting files in the install folder.
Then just link against this library instead.

How to debug Qt dll issues with cross compiled builds?

After cross-compiling Qt 5 applications (host: Fedora 19/64 bit, target: Windows 32 bit) I execute following steps for deploying the executable:
$ DEST=/windows/testdir
$ cp /usr/i686-w64-mingw32/sys-root/mingw/bin/*.dll $DEST
$ mkdir $DEST/platforms
$ cp /usr/i686-w64-mingw32/sys-root/mingw/lib/qt5/plugins/platforms/qwindows.dll\
$DEST/platforms
$ cp release/main.exe $DEST # the cross-compiled Qt5 binary
I test it on Windows like this:
say /windows is mounted on f:
start command prompt window
f:
cd testdir
main
And there I get:
Failed to load platform plugin "windows". Available platforms are:
Microsoft Visual C++ Runtime Library
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
I don't really believe the first message because:
a) the above steps worked in the past (executed on the same Fedora 19 system)
b) the platforms directory is there as documented in the qt docs.
What changed is that now the application includes some PNGs/JPGs in dialogs (read via Qt's resource file system, as QIcons).
Thus, I've also copied some plugins:
$ cp -r /usr/i686-w64-mingw32/sys-root/mingw/lib/qt5/plugins $DEST
Which didn't help to resolve the above issue.
Conclusion
Is there a way to debug dynamic runtime linker issues like these?
Can I instruct it such that I somehow get output on which dll's the app/linker tries to load and where is does its lookups? (and why they fail ...)
For example something like this would be great:
ldd: main.exe -> load of foo.dll in work-dir failed (no such file)
ldd: main.exe -> load of bar.dll in work-dir/platforms failed (wrong file format)
ldd: main.exe -> load of baz.dll in work-dir successful
...
Compile steps
I used following steps for cross-compiling on Fedora 19:
$ mingw32-qmake-qt5 main.pro -o win32.mf
$ mingw32-make -f win32.mf
$ # -> binary is created in release/main.exe
Wine
I've looked at wine for testing purposes. It is helpful because it displays an error message when it can't find a DLL, e.g.:
$ wine $DEST/main.exe
err:module:import_dll Library libEGL.dll (which is needed by L"Z:\\usr\\i686-w64-mingw32\\sys-root\\mingw\\lib\\qt5\\plugins\\platforms\\qwindows.dll") not found
err:module:import_dll Library libjpeg-62.dll (which is needed by L"Z:\\usr\\i686-w64-mingw32\\sys-root\\mingw\\lib\\qt5\\plugins\\imageformats\\qjpeg.dll") not found
Interestingly, it directly finds the platforms library and needed plugin under Z:\\usr\\i686-w64-mingw32\\sys-root\\mingw\\lib\\qt5\\.
But when all needed DLLs from /usr/i686-w64-mingw32/sys-root/mingw/bin/*.dll are copied to $DEST, wine runs the same main.exe just fine - where on native windows (7) I get the above error boxes.
You can use tools like Dependency Walker for checking dependencies of a single DLL, Wine for quickly checking startup on the compile-host and Process Monitor to see which directories/files are accessed during runtime of the process.
It also makes sense to debug-output the library path from the Qt application, e.g.
int main(int argc, char **argv)
{
qDebug() << "Library paths: " << QApplication::libraryPaths();
QApplication app(argc, argv);
...
With that I get following output on native windows:
Library paths: ()
(To enable qDebug() statements - even with release binaries - you have to add CONFIG += console to your qmake project file.)
Looking at the Process Monitor output it seems that the binary does not try to open any plugins (platforms or other) in its current working directory (CWD) nor in its base directory.
When I extend the library path the binary finds all needed plugins in its CWD:
int main(int argc, char **argv)
{
QApplication::addLibraryPath(QDir::currentPath());
QApplication app(argc, argv);
...
I don't know if this qualifies as a work-around - perhaps one is supposed to do something like this. But the Qt documentation seems to suggest opposite:
To deploy the application, we must make sure that we copy the relevant Qt DLL (corresponding to the Qt modules used in the application) and the windows platform plugin as well as the executable to the same directory in the release subdirectory.
The complete deploy procedure is now:
$ cp /usr/i686-w64-mingw32/sys-root/mingw/bin/*.dll $DEST
# copying platforms, imageformats etc. plugin directories:
$ cp /usr/i686-w64-mingw32/sys-root/mingw/lib/qt5/plugins/* $DEST -r
$ cp release/main.exe $DEST
(Depending on what packages are installed on your compile-host you probably don't need to copy all DLLs - with wine it is easy to start a fixpoint iteration for all needed non-plugin dlls.)
Missing non-platform plugins don't necessarily abort the programs startup - e.g. without a jpeg plugin some icons are just not displayed.

Qt Creator + OpenCV: Program runs from .exe but not from editor

Well, I need to start working with OpenCV and as I'm used to working with QtCreator, I'm trying to make it all work together. I downloaded the latest OpenCV version, and compiled it with MinGW. Then, I created this little console project to try it out. Below is the .pro file:
QT += core
QT -= gui
TARGET = OpenCV_test4
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
INCLUDEPATH += C:\\Librerias\\opencv2.3.1\\release\\include
LIBS += -LC:\\Librerias\\opencv2.3.1\\release\\lib \
-lopencv_core231.dll \
-lopencv_highgui231.dll \
-lopencv_imgproc231.dll \
-lopencv_features2d231.dll \
-lopencv_calib3d231.dll
Here is the main.cpp file:
#include <QtCore/QCoreApplication>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// read an image
cv::Mat image= cv::imread("img.jpg");
// create image window named "My Image"
cv::namedWindow("OpenCV Window");
// show the image on window
cv::imshow("OpenCV Window", image);
// wait key for 5000 ms
cv::waitKey(5000);
return a.exec();
}
(I have tried this code with and without the QCoreApplication lines)
The deal is: It links and builds, and when runs from QtCreator only a terminal window called C:\QtSDK\QtCreator\bin\qtcreator_process_stub.exe appears with the line "Press RETURN to close this window..."
But, if I run the .exe from the project folder, it runs perfectly!! Why is QtCreator unable to launch the application? I found this really strange, and I would appreciate any hint about this. It's really not THAT important, but it is kind of a pain to have to run the .exe manually every time I change something to check how it works.
Thanks for your time :)
Additional Info:
I have tried both debug and release versions, the problem is the same in both of them.
Debugging does not work, it never stops at any breakpoint.
I'm running on Windows 7 Proffesional x64
SOLVED, I don't really know what I did, it suddenly worked and keeps working, I wish I could tell you how I fixed it but I have no idea, such a weird thing :(
Check Projects -> Run Settings -> Run in terminal. It have to be enabled, but seems to be disabled.
I have met same problem with QtCreator and OpenCL under Linux. Simple test program works after start from terminal and it does not work after start from the QtCreator.
I found the cause was hardcoded LD_LIBRARY_PATH in the project's run environment settings. I had dropped it to empty string and this had fixed issue.
I had the same issue with the following environment: Raspbian, Qt, openCV and a gui application.
old-ufo recommendation worked for me:
- First, enable "Run in terminal", which failed
- Then, disable "Run in terminal", which allowed me to correctly debug my app.
I understand that this is not scientific.