Use dynamic library in dynamic library - qt

I am always using QDesignerCustomWidgetInteface. I want to use two kinds of CustomWidget in another CustomWidget to combine two of them so that I need not to write some codes again.
So I write codes as below in project file:
LIBS +=-L./debug -lxzquxianplugin
LIBS +=-L./debug -lxzyctextplugin
When I finished the code I debug the codes in creator and started debugging designer. Designer ran well and recognized my new CustomWidget. But when I entered bin/gcc/debug folder and ran executable app Designer that debug mode produced directly without codes and Qt creator, Designer showed that could not find shared library: libxzquxianplugin.so.
I tried to use codes as below:
Debug {
LIBS +=absolute path way of xzquxianplugin
LIBS +=absolute path way of xzyctextplugin
}
But it still failed to find dynamic library when I ran Designer in debug folders. I cannot understand why it happened.

the libs -L switch is used when you want to add a directory to linker search path, you used:
LIBS +=-L. /debug -lxzquxianplugin
Which actually breaks your path because of the space after -L.
So you should have
LIBS +=-L./debug -lxzquxianplugin
given that your lib exists under debug folder.

Related

Link dynamically against Public\Qt inside ocean

Using Petrel 2016.1
Libraries reference:
https://www.ocean.slb.com/~/media/files/testing%20plug%20ins/libraries/petrel_2016-1_3rd_party_libraries.html
My plugin uses Qt for a window and some plots with qwt. I would like to link against the Qt dlls present at Petrel\Public\Qt to save some space while deploying the app and because is not possible to deploy libs already present in Petrel as public libs by policy.
I've successfully linked with the same Qt version over there. The problem is that PluginPackager.exe does not see the libs. I've tried editing PluginPackager.exe.config inside Petrel dir to include Public\Qt, copied it to the Release folder, copied it to the main project folder and every dir that I may suspect PluginPackager.exe is looking for this file but nothing seems to cause any effect.
I've copied the Qt dlls to the Release folder, so PluginPackager.exe could see them and register the Plugin. It works, even if I delete the Qt dlls from the Release folder afterwards. Petrel is loading them from Public\Qt. The problem is that when I try to open the Qt window, a message saying that Qt failed to load plugin windows.
I figured that it is related to qwindows.dll, which is inside Public\Qt\plugins\platforms. If I set the environment variable QT_QPA_PLATFORM_PLUGIN_PATH to C:..\petrel...\Public\Qt\plugins\platforms, it works fine. I've tried to use addLibraryPath() from QApplication with no success.
I guess we have everything we need inside Public\Qt, but for some reason Petrel is not finding it. Two questions, then:
1- How to make PluginPackager to see all the libs inside Public\Qt?
2- How to make my application to find qwindows.dll?
Plugin has code in C#, C++ cli and C++
EDIT 1:
Ok, for Q.2 I've found a solution by trial and error.
QString path = QDir::currentPath();
QString finalPath = QDir(path).filePath("Public/Qt/plugins");
QApplication::addLibraryPath(finalPath);
This will add the plugins dir to the qt lib search path and does the trick. I hope I can deploy using this.
EDIT 2:
For Q.1
I realize now that the PluginPackager only sees things inside the Extensions folder. The problem was that, in my opinion, the folder name Public is misleading. This led me to think that all libs inside that folder could be used by developers freely. The Ocean guide states that all libs other than the ones inside Extensions are considered internal libs:
The PluginPackager.exe assumes that files in the Petrel installation directory tree other than those in the Extensions folder are internal Petrel libraries.
Well, why name a folder Public if all the libs inside it are internal? This is really confusing. Besides, the Slb.Ocean libs inside the Public folders are Ok to use, the others are not? As PluginPackager.exe.config has Public\ but not the folders inside it.

Cannot open input file 'ANN.lib' in QT creator 4.21(community)

ANN: Approximate Nearest Neighbor Searching.
I am using QT creator in windows-10 64 bit system. I have compiled the source files from official site of ANN with visual studio 2015 and have successfully run the sample and test with the same environment. That is also the way how I get dll and lib files.
However, I tried to add the library to my QT creator but failed. I used both external library and internal library, even tried system library, but the problem of ' cannot open' always shows up. Meanwhile, I tried put all .h files, dll and lib file in the project's directory, still the same problem. All of other external libraries work fine after I configure them in my qmake file. Here is an example:
LIBS += -lopengl32
This is an internal lib I added (maybe system lib). And:
win32:CONFIG(release, debug|release): LIBS += -LC:/local/boost_1_63_0/lib64-msvc-14.0/ -lboost_filesystem-vc140-mt-gd-1_63
-llibboost_filesystem-vc140-mt-s-1_63
-llibboost_serialization-vc140-mt-s-1_63
-llibboost_system-vc140-mt-s-1_63
else:win32:CONFIG(debug, debug|release):
LIBS += -LC:/local/boost_1_63_0/lib64-msvc-14.0/
INCLUDEPATH += C:/local/boost_1_63_0
DEPENDPATH += C:/local/boost_1_63_0
As you can see, the two above libraries are working perfectly. Again, as I mentioned, my VS2015 can compile the sample by the library I put in the system directories. So how should I configure ANN lib in my QT?
I solved the main part of this problem by the suggestion made by the dude who commented above. Thanks a lot! The situation currently is that I can run the ANN.lib correctly in my QT creator with several other libraries (without compiling errors).
As I mentioned, I have already put all necessary files into the system directories, such as dll(system32), .lib(my visual studio 14/VC/lib), .h(my visual studio 14/VC/include). But that seemed not enough to run the ANN.lib successfully.
So I added a configuration of compilation, which is x64 release, to generate the newest dll and lib. Then I did the last step again, still not working. After that I put all files in single directory located in disk C and add this path to my qmake as external library. Now it works. Although I didn't delete the ones in my system's directories, it is running. Another thing I wonder to mention is that I also add this path to environment variables, so that I can just use += -lANN to run the lib without making it as external library. Both can work fine.

Qt: mingw compiled library does only work with both library.so and library.lib file present

I compiled a library using the MinGW toolchain provided with Qt 5.0.2 on Windows. As a result I received a library.so file. First I failed using the library in a Qt application, but now I found out that everything works fine when I make a copy of the liblibrary.so file and call it liblibrary.dll or liblibrary.lib (which is the only file ending supported by the add library wizard in QtCreator).
Now I wonder if this is normal or if I should change something in order not to have both files (which are exact copies). Leaving one away makes the application crash during start up. I added the library as follows to my Qt pro file:
LIBS += -L"../path/to/library" -llibrary
INCLUDEPATH += $$quote(../path/to/library)
EDIT: I compiled the library using the MinGW of Qt, not as Qt project but using mingw32-make and the provided Makefile. As a result I get the liblibrary.so.
EDIT: It seems to work also when renaming the copy to liblibrary.dll instead of .lib. But still, I need two files to make the application work -- the .so and the .dll.
Chris
That's weird, I think you should get a *.a and *.dll files when building a shared lib with MinGW on Windows, as said in the documentation:
In windows, MinGW will output .a and .dll, MSVC2010 will ouput .lib and .dll. In linux, MinGW will output .so, .so.1, .so.1.0 and .so.1.0.0 – .lib, .a and .so are import libraries.
You definitely shouldn't rename your file!
Be careful to:
not to include the "lib" prefix after "-l" in your project file.
put everything after after "-l" in lower case as you're on Windows
not adding any extension to your library name after "-l"
add and reference the .h file used in your library
A real example using QtWebsocket lib:
INCLUDEPATH += "$${PWD}/include/"
LIBS += -L"$${PWD}/libs/" -lqtwebsocket
...
HEADERS += ... \
$${PWD}/include/QWsSocket.h \
...
In my include/ folder, I have the following file:
QWsSocket.h (taken from original project - required)
In my libs/ folder, I have the following file:
libQtWebsocket.a
QtWebsocket.dll
Edit: I struggled with this too initially. Have you tried to build your lib as a static lib instead (CONFIG += staticlib in your library project)? This might help you getting you *.pro file right before switching to using the shared library.
Edit 2: Ok, the fact that you get a *.so file is still a bit odd. In this question
the user has the same issue as you and keep both files, which is just a workaround. According to a later answer it seems that you need to modify your makefile to generate a file with the proper extension. Maybe this will help: http://www.mingw.org/wiki/sampleDLL

Undefined references - I'm including correct header

I'm trying to subclass from ProjectExplorer::ProjectExplorerPlugin but I'm getting error telling me about undefined references. Any ideas how to fix it?
class MyPluginPlugin : public ProjectExplorer::ProjectExplorerPlugin
{
Q_OBJECT
...
};
error: undefined reference to `imp__ZN15ProjectExplorer21ProjectExplorerPluginC2Ev'
The fact that you don't get a compilation error, but an undefined reference usually means that your project knows where the header files are, but it doesn't know where the library is which contains the already compiled source code.
I've never written a plugin for Qt Creator but I've taken a quick look at its source code structure and I see the following options:
Option A)
There is a projectexplorer.pro file in Qt Creator's source under src/plugins/projectexplorer. You could manually build that project in order to get a ProjectExplorer.lib (plus a .dll or a .a) and then reference this library.Example: Assuming the library would be created in the same directory as its .pro file (I have no idea if it is like that) and you created your plugin withing Qt Creator's source under src/plugins/myplugin, you would define your LIBS variable like this:
LIBS += -L../projectexplorer \
-lProjectExplorer
The first line adds "../projectexplorer" as an additional library directory and the second line adds "ProjectExplorer" as a library to search in any of the defined directories (it automatically adds the OS-specific file extensions like .lib on windows etc).
Obviously if your project or the library is located somewhere else, you need to change the first line accordingly.
Option B)
You could include the source and header files of the projectexplorer directory to your own .pro file using the HEADERS and SOURCES variables. I'm not sure if this wouldn't interfere with any other plugins (including projectexplorer itself) though.
Option C)
There probably is a way to include the projectexplorer.pro file so that you have a master project which first builds the project explorer library and then your own plugin. This would be the safest way to go as it ensures the Project Explorer library is built and up-to-date before your own project is linked against it.
However I have limited experience on this.
If anyone reading this can give a detailed explanation on this option, feel free to edit or provide your own answer.
If you are using Qt Creator built from source coded after April 2013 which includes Commit: #66a3553 - make library and plugin dependencies declarative, then you can simply specify dependencies for your plugin in its .pro file:
# myplugin.pro
QTC_PLUGIN_DEPENDS += \
coreplugin \
projectexplorer

QMake OBJECTS issue after clean

I have a precompiled object file, say myObjectFile.o. Inside my .pro file I have a block of code like this:
mac {
...
OBJECTS += myObjectFile.o
}
This works great for linking in the object file with the rest of the project, but there is a fatal issue. If I do a clean this object file gets deleted. And since it's precompiled, when I try to build again I get a linking error until I copy the file back into my projects directory (I actually have a system call in my .pro file to copy the file so I just run qmake again).
This problem is annoying and causes some issues with our continuous integration server. Basically, I'm looking for a way I can link precompiled object files into my code.
You do this by adding the object files in LIBS rather than OBJECTS:
mac {
...
LIBS += myObjectFile.o
}
The contents of LIBS are passed to the linker as-is, which makes it possible to include object files in it.

Resources