How to compile qtwebkit plugins? - c++

QtWebkit-plugins is a library that provides features to the QWebView, eg SpellCheck and Notification Web API.
Read about:
SpellCheck
Notification Web API
I tried to compile the code in Windows, but my QWebView not working as expected, in other words, SpellCheck and Notification Web API not working. It's like I've been not-using QtWebkit-plugins. Which can be?
In the documentation that says to compile I have to run:
$ qmake
$ make && make install
Read more in QtWebkit-plugins repository
I'm using mingw, instead of make I used mingw32-make:
I compiled hunspell
Copied hunspell for C:\Qt5.4.0\5.4\mingw491_32\bin and C:\Qt5.4.0\5.4\mingw491_32\lib
I compiled qtwebkit-plugins using in cmd:
qmake
mingw32-make && mingw32-make install
mingw32-make generated libqtwebkitpluginsd.a and qtwebkitplugins.dll
Copied libqtwebkitpluginsd.a for C:\Qt5.4.0\5.4\mingw491_32\lib
Copied qtwebkitplugins.dll for C:\Qt5.4.0\5.4\mingw491_32\plugins\webkit and C:\Qt5.4.0\5.4\mingw491_32\bin
After that I compiled another simple project that uses QWebView then tested the SpellCheck in a <textarea spellcheck="true"></textarea> and did not work.
I tested the Notification Web API and also did not work.
Note: When running my project using QT_DEBUG_PLUGINS=1 and use Notification Web API in the application output tab (in QtCreator) returns:
Found metadata in lib C:/Qt5.4.0/5.4/mingw491_32/plugins/webkit/qtwebkitplugins.dll, metadata=
{
"IID": "org.qtwebkit.QtWebKit.QtWebKitPlugin",
"MetaData": {
},
"className": "QtWebKitPlugin",
"debug": false,
"version": 328704
}
loaded library "C:/Qt5.4.0/5.4/mingw491_32/plugins/webkit/qtwebkitplugins.dll"
QLibraryPrivate::unload succeeded on "C:/Qt5.4.0/5.4/mingw491_32/plugins/webkit/qtwebkitplugins.dll"
QSystemTrayIcon::setVisible: No Icon set
It seems to me that the dll is loaded, it just is not working.
How do my projects work these features?

For this work in QT-5.2+ is necessary to modified the qwebkitplatformplugin.h file
Change this:
QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(QWebKitPlatformPlugin, "com.nokia.Qt.WebKit.PlatformPlugin/1.9");
By this:
QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(QWebKitPlatformPlugin,
"org.qt-project.Qt.WebKit.PlatformPlugin/1.9");
If needed compatibility with QT-4.8 change the code for this:
QT_BEGIN_NAMESPACE
#if QT_VERSION >= 0x050200
Q_DECLARE_INTERFACE(QWebKitPlatformPlugin, "org.qt-project.Qt.WebKit.PlatformPlugin/1.9")
#else
Q_DECLARE_INTERFACE(QWebKitPlatformPlugin, "com.nokia.Qt.WebKit.PlatformPlugin/1.9")
#endif
QT_END_NAMESPACE

Related

Tensorflow Lite c++ Build

I have already put a question about the access violation of the TensorFlow lite c++ API. No one answered it so far, I believe the error I made is with selecting the wrong header- and library files from the Bazel build.
The steps that I have done to get the Tensorflow Lite Header and Libraries are from Youtube Tutorial and from Tensorflow.
Get Required Python (for me Python 3.9.5)
Install required Packages locally
Install Bazel (for me 3.7.2) and MSYS2 (after installation run pacman -S git patch unzip) and add it to Path
Check VS Build Tools 2019 for C++ (I have VS 19 Community with MSVC v142 & Windows 10 SDK)
Download and Unzip Tensorflow Sources from Github (Release of 2.5.3)
Inside the Tensorflow Sources, use python .\configure.py to start configure the bazel build (I only used Yes for override eigen strong inline, the rest is kept on the default value)
The I opened GitBash cmd inside the tensorflow source bazel build -c opt //tensorflow/lite:tensorflowlite
After a successful build later I get the "bazel-bin", "bazel-out", "bazel-tensorflow-2.5.3" and "bazel-testlogs" folder.
I created the following folders tensorflow/include/tensorflow/lite & core and tensorflow/include/flatbuffers for the headers and finally the tensorflow/lib for the libraries.
I copied the tensorflowlite.dll & tensorflow.dll.if.lib from the build directory (tensorflow-2.5.3\bazel-bin\tensorflow\lite) into the tensorflow/lib directory together with the flatbuffers.lib (from tensorflow-2.5.3\bazel-bin\external\flatbuffers\src)
I copied the tensorflow-2.5.3\bazel-bin\external\flatbuffers\src_virtual_includes\flatbuffers\flatbuffers headers into the tensorflow/include/flatbuffers directory
I copied the tensorflow-2.5.3\tensorflow\lite and tensorflow-2.5.3\tensorflow\core from the original sources into the tensorflow/include/tensorflow/lite & core directory.
After those steps, I could create a new VS Project and add the created linker and include information. And created the following short example to read the input layer.
#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/kernels/register.h"
#include "tensorflow/lite/model.h"
#include "tensorflow/lite/optional_debug_tools.h"
#define TFLITE_MINIMAL_CHECK(x) \
if (!(x)) \
{ \
fprintf(stderr, "Error at %s:%d\n", __FILE__, __LINE__); \
exit(1); \
}
int main()
{
std::string filename = "C:/project/tflitetesting/models/classification/mobilenet_v1_1.0_224_quant.tflite";
std::unique_ptr<tflite::FlatBufferModel> model =
tflite::FlatBufferModel::BuildFromFile(filename.c_str());
tflite::ops::builtin::BuiltinOpResolver resolver;
tflite::InterpreterBuilder builder(*model, resolver);
std::unique_ptr<tflite::Interpreter> interpreter;
builder(&interpreter);
TFLITE_MINIMAL_CHECK(interpreter->AllocateTensors() == kTfLiteOk);
printf("=== Pre-invoke Interpreter State ===\n");
tflite::PrintInterpreterState(interpreter.get());
interpreter->SetAllowFp16PrecisionForFp32(true);
interpreter->SetNumThreads(1);
// Get Input Tensor Dimensions
unsigned char* input = interpreter->typed_input_tensor<unsigned char>(0);
}
But I am still receiving the access violation exception inside interpreter.h at
const Subgraph& primary_subgraph() const {
return *subgraphs_.front(); // Safe as subgraphs_ always has 1 entry.
}
What am I doing wrong? I dont want to build the shared library since the target (Coral Edge) has direct access to those functions (ex. interpreter->typed_input_tensor<unsigned char>(0); too.
The thing is, you cannot Debug a Release (Optimized) version.
with the command bazel build -c opt //tensorflow/lite:tensorflowlite you will create an "Release" version of the dll's and lib's.
Therefore just apply bazel build -c dbg //tensorflow/lite:tensorflowlite to get the debug tflite c++ version.

Using custom node packages in Electron

I am trying to use a custom node package that I wrote in an Electron application and I am having trouble getting the resulting DLL/Node package to initialize. When I launch my Electron application, I get the following error:
Uncaught Error: A dynamic link library (DLL) initialization routine failed.
The DLL being linked is a simple library written in C++ that has one function that takes a double as an input and simply adds one to it, returning the result. To build the C++ library, I use SWIG (http://www.swig.org/) and node-gyp with the following commands:
swig -c++ -javascript -node ./src/mace_api.i
node-gyp clean configure build
mace_api is the package I am trying to build. mace_api.i, the binding.gyp file, and the source files for my library are defined as follows:
mace_api.i
%module MaceAPI
%{
#include "./mace_api.cpp"
%}
%include <windows.i>
%include "./mace_api.h"
binding.gyp
{
"targets": [
{
"target_name": "mace-api",
"sources": [ "./src/mace_api_wrap.cxx" ]
}
]
}
mace_api.h
#ifndef MACE_API_H
#define MACE_API_H
#include <iostream>
#include <functional>
using namespace std;
class MaceAPI
{
public:
MaceAPI();
double addOne(double input);
};
#endif // MACE_API_H
mace_api.cpp
#include "mace_api.h"
MaceAPI::MaceAPI()
{
}
double MaceAPI::addOne(double input)
{
double ret = input + 1.0;
return ret;
}
SWIG takes the C++ source files and basically writes a wrapper that can be used, in this case, by node-gyp to build a Node package. Has anyone tried to use a custom Node module built in this manner in an Electron application? Am I missing something with how SWIG generates a wrapper for my C++ library, or how Electron handles custom Node packages? I am able to link the library with Node, but not with Electron. Any help would be appreciated.
For completeness, below is how I am trying to include and use my package in my Electron application:
var libMaceTest= require('mace-api/build/Release/mace-api');
var test = new libMaceTest.MaceAPI();
console.log(test.addOne(5));
Have you checked out https://github.com/electron/electron/blob/master/docs/tutorial/using-native-node-modules.md#manually-building-for-electron
Specifically,
Manually building for Electron
If you are a developer developing a native module and want to test it
against Electron, you might want to rebuild the module for Electron
manually. You can use node-gyp directly to build for Electron:
cd /path-to-module/ HOME=~/.electron-gyp node-gyp rebuild
--target=1.2.3 --arch=x64 --dist-url=https://atom.io/download/atom-shell
The HOME=~/.electron-gyp changes where to find development headers.
The
--target=1.2.3 is version of Electron. The --dist-url=... specifies where to download the headers. The --arch=x64 says the module is built
for 64bit system.

Qt deployed (macdeployqt) application does not create a file

I'm facing the following problem:
I wrote a simple application to track working hours. Therefor I create a *.db file programmatically.
Launching the application from Qt Creator (debug or release) works perfectly fine.
I used the macdeployqt tool to get a *.dmg file. When starting the application now the method (see below) cannot open, respectively create the *.db file and I run out of ideas why. In addition to this, the application should output some *.csv files. This also fails.
One more information, running the application as administrator using the sudo command on terminal...well it works and the *.db file and *.csv files get created.
So I am quite sure it must deal with file permissions but I have no idea how to change this except for changing it in the information context menu but this didn't help at all.
Below the method for the *.db file which always returns false when not launching the app from Qt Creator:
QFile file(Globals::Environment::WORKING_DIRECTORY + "/" + "Records.db");
if(file.open(QIODevice::ReadWrite))
return true;
else
{
QMessageBox msg;
msg.setWindowTitle("Error");
msg.setText("Failed to create database file!");
msg.exec();
}
return false;
I am on MacOS 10.11.3.
Qt 5.5.1 (Clang 6.1 (Apple), 64 bit)
If more information is needed, I will provide it of course.
Thanks a lot for every help in advance.

Derelict3 D bindings on OS X

I just want to make a little test with GLFW3 D binding.
I create a new package using
dub init glfw3Test
Then I wrote a little test in glfw3Test\source\app.d
import derelict.glfw3.glfw3;
void main()
{
// Load the GLFW 3 library.
DerelictGLFW3.load();
if(DerelictGLFW3.isLoaded)
{
// Do something cool!
}
}
And I modified the default JSON with:
{
"name": "glfw3Test",
"dependencies":
{
"derelict-glfw3": "~master"
},
"configurations": [
{
"name": "glfw3Test",
"targetType": "executable"
}
]
}
I built with dub build, everything went fine, but when I tred to launch the executable I got the following errors:
derelict.util.exception.SharedLibLoadException#../../../.dub/packages/derelict-util-1.0.2/source/derelict/util/exception.d(35): Failed to load one or more shared libraries:
libglfw.3.dylib - dlopen(libglfw.3.dylib, 2): image not found
libglfw3.dylib - dlopen(libglfw3.dylib, 2): image not found
I have also tried to compile my application manually without using DUB, but I got always the same problem.
It seems to look for the GLFW3 shared library, but I was thinking that the lib is statically linked by the built process.
I am on OS X 10.10 with Xcode 6 installed (DMD compiler 2.065)
I've noticed that the default make process of GLFW3 (using cmake) does not create the dylib files. So I rebuilt GLFW with the following option:
cmake -D BUILD_SHARED_LIBS=ON
And then I made a make install, so now the file libglfw.dylib is correctly installed in /usr/local/lib
Thank to #duselbaer for make me noticed this problem.

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.