Create a Qt library to be used in a non-Qt application - qt

I created a Qt static library following the instruction here:
http://qt-project.org/wiki/How_to_create_a_library_with_Qt_and_use_it_in_an_application
Then I tried to link the library with my own (non-Qt) application, and GCC complained about undefined references. Examining the library content using Linux nm utilty I found the function I intend to call has cryptic letters added before and after it.
Reading the instruction from the instruction link more closely, it suggests that I need to use use an import define so the right Qt macro can be called to import the function (which I assume renames the function to match the naming scheme in the library). But I don't really want to introduce Qt dependency in my main application.
What I really want to do is to build a UI frontend library with Qt, and my main application will simply link to it without having any Qt dependency. Is this possible? Or am I using Qt in an unintended manner?
Thanks.

It sounds like you're running into C++ namespace mangling. Try adding an 'extern "C" {}' block around your libraries export.
The main point of the QLibrary::resolve function is to provide an abstraction layer so you don't have to worry about the win32 command or the linux command for resolving a symbol. It shouldn't be necessary to use a library created with Qt.

Related

Adding new paths for native libraries at runtime in Java9

I have an app that includes some native code. In an effort to make things easy for users to install and run, I have been extending the private field ClassLoader.sys_paths at runtime as described in this previous question: Adding new paths for native libraries at runtime in Java. With this hack the app can run with a simple unadorned java -jar app.jar command and the native objects will be located correctly in the installation directory.
This technique no longer works in Java 9 (see How to solve InaccessibleObjectException ("Unable to make {member} accessible: module {A} does not 'opens {package}' to {B}") on Java 9?). This article describes the changes to Java 9 and suggests a solution (adding arguments to the command line to open the module), but this defeats my original intent of allowing a simple execution of the java command.
Is there any way to change the native library search path at runtime, or is this considered too much of a loaded gun to leave lying around?

GLEW (OpenGL Extension Wrangler): Loading opengl dll at runtime?

I would like to load opengl32.dll at runtime (using LoadLibrary from Win32) and then load OpenGL2/3/4 functions. I tried to use glew for that, but it can't resolve some wgl functions.
So is there an easy way I can use glew to import OpenGL functionalities while loading opengl dynamically ?
It is possible to do what you are asking for, but you will have to go about it differently. Typically, when a shared library (or dll) is manually loaded at runtime, you will have to search, by symbol, for the functions you want to use and assign them to handles so you can call them.
What you are doing now will never compile because you are explicitly using symbol names that the linker cannot find. You have to replace all of these unresolved function calls with queries into your manually loaded shared library (opengl32.dll).
There's some good code you can use for reference in the glfw project. Take a look at both the _glfwInitWGL and loadWGLExtensions functions.

Mixing Shared and Static Libraries

I'm using premake5 to build a complex application on multiple platforms. My application links against both static and shared/dynamic external libraries.
There seems to be significant build chain dependencies that break premake generated 'gmake' make files in this case.
Case in Point:
If you mix shared and static libraries in premake 'link' statements, GCC seems to get confused and expect your shared library references to actually be static libraries. When it can't find them the link stage fails. This is normally handled by prefixing your shared libs with '-Bdynamic'. Unfortunately there is no way to tell premake5 that an external link lib is static or dynamic, so you have to manually fixup the make files, which defeats the purpose of a build utility.
This is kind of a showstopper. I don't think you can just feed "-Bdynamic" into the linkoptions because it must be followed by the list of shared libraries.
Seems like a bug in gmake action (or at least a missing functionality)
For those, the best approach is to go to the Premake page on Github (https://github.com/premake/premake-core) and create a new issue.
And if you have the time to provide a small reproductible project (a static lib project, a dynamic one, and an application using both, each with only 1 cpp or some simple stuff + the premake script) and attach it to the issue, it would also be really appreciated (and much easier to treat this issue ^^)

Modules of Qt 5.1 and their interdependency?

I am looking for a way to create a minimal static build of Qt 5.1. By minimal, I mean a build with only the basic set of widget classes available (including 2D graphics acceleration through an OpenGL canvas/widget). I am aiming for a static build on Windows 7 32-bit using MinGW-builds GCC 4.8.1 as well as their bundle of MSYS and tools.
I have downloaded the entire source tree, and have met some problems with compiling due to the dependency of packages such as OpenSSL and ICU (the latest OpenSSL did not compile). I wanted to see, if I could avoid dependencies of these packages and, at the same time, achieve a minimal static build of Qt 5.1 so my final executable is not gigantic in size.
I took a look at this list:
http://download.qt-project.org/official_releases/qt/5.1/5.1.0/submodules/.
Q1: Which of these modules, do I need to select to have a basic Qt build without all the fancy stuff?
Q2: Are these modules interdependent on each other in some way (I assume they are all dependent on "qtbase")?
Q3: Do I use the names from that list, (for example: "qtxmlpatterns", "qtx11extras", "qtwebkit", etc.), to deselect them in the configuration of my Qt build?
It would also be nice, with an explanation of the various submodules of Qt 5? If someone could point to any links or docs with illuminating words on this subject, that would also be great.
I shared this same goal. I wanted to "minify" Qt, building only a small subset of the libraries/DLL(s) and omitting the rest.
I did succeed, at least on Mac OS X. I assume that this approach will work on other platforms, too.
I thought that the trick would be to find some kind of exclusion flags for the "configure" script, but that turned out not to be the case.
Here is what I did:
Download the source distribution (in my case, qt-everywhere-opensource-src-5.1.1). of course, extract it all.
Edit the following three "pro" files. these files are in a qt-specific format (but plain text). They are platform-independent project files that Qt (via qmake) uses to generate makefiles.
qtbase/src/src.pro
qtbase/src/plugins/plugins.pro
qtbase/examples/examples.pro
All the changes that I made to the "pro" files were deletions. I deleted references to: dbus, ipc, network, qtconcurrent, sql, xml, sqldrivers, qdbusxml2cpp, qdbuscpp2xml, src_dbus, src_concurrent, src_sql, src_network.
That last part may sound scary. It really wasn't.
The pro files contain a list of module names, plugin names, and directory names. It seemed fairly straightforward how to delete (for example) all SQL-related lines.
Step 3.
The usual configure/make/install. However, note the "module-qtbase" argument passed to make:
./configure -prefix ~/my_test_dir/
make -j2 module-qtbase
make -j2 module-qtbase-install_subtargets
Success. This built and installed only the essentials (QtCore, QtGui, QtOpenGL, QtWidgets) and skipped all the supporting dylibs like QtConcurrent, QtMultimedia, QtSql, and QtWebKit.
ICU can link statically, and you can customize it (see docs) to reduce size. By default the data is also large, I don't know how much data you need. You could include only enough data to run in one language.
Only part of an answer.
There's no need to disable Qt modules. Each application that uses Qt decides what modules it uses and links with. A basic console-only application may use the core module only. That's what you'd use when creating, say, a web service in Qt.

Using dlopen() on an executable

I need to call a function from another program. If the other program were a library, I could simply use dlopen and dlsym to get a handle to the function. Unfortunately, the other program is a Unix Executable, and building it as a library is not an option. Trying dlopen() on the executable gives this error message:
dlopen([...]/testprogram, 1): no suitable image found. Did find:
[...]/testprogram: can't map
This isn't surprising, as dlopen is meant for use with libraries, not executables. Is there any way to get dlopen and dlsym to work with executables? If not, is there an alternative way of achieving the same thing?
You can't open executables as libraries. The entry point of an executable will attempt to re-initialize the C library, and take over the brk pointer. This will corrupt your malloc heap. Additionally, the executable is likely to be mapped at a fixed address with no relocations, and if this address overlaps with anything already loaded, it's not possible to map it for that reason as well.
You need to refactor the other program into a library, or add a RPC interface to the other program.
Note that this does not necessarily apply for PIE executables. However, unless the executable is specifically designed for being dlopen()ed, this is unsafe, as main() will not be run, and any initialization done in main() therefore will not occur.
On some ELF systems (notably Linux), you can dlopen() PIE executables. When using GCC, just compile the executable with -fpie or -fPIE, and link it with -pie, and export the appropriate symbols using --dynamic-list or -rdynamic (explained in more detail in this other SO answer.
Tool here to do precisely that, handles ASLR/PIE and non-ASLR/PIE. Compiles on x86, ARM and MIPS (32 bit only). Edit the Makefile to set ARCH param.
http://rtfc.org.uk/cliapi.html
It's my tool but it seems to do what you want. Let me know if it doesn't work for you.
I appreciate how late I am to this party, but hey.
To add the ability to load executables via dlopen is registered as refused glibc RFE (Request For Enhancement). A detailed look at the RFE and a possible approach for some special cases may be found at
[http://sourceware.org/bugzilla/show_bug.cgi?id=11754][1]
Excluding PIEs there would be to many problems behind the scenes to implement such a functionality.

Resources