I have a project setup with a couple of Apps with a shared library, this is all built nicely using a SUBDIRS project, where the apps depend on the shared library.
TEMPLATE = subdirs
SUBDIRS = app1 app2 sharedLib
app1.depends = sharedLib
app2.depends = sharedLib
Each app also contains a number of tests, with CONFIG += testcase set.
This creates a check target so we can run all unit test from the top level .pro using make check.
The problem is that some of the app tests require the presence of the code within the sharedLib, therefore it needs to be discoverable according to each platforms library lookup rules.
On Windows one option is to have the sharedLib location on the PATH, on linux we can add the sharedLib location to LD_LIBRARY_PATH, on mac DYLD_LIBRARY_PATH.
One solution is to just set the location of the built shared lib before running make check:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:build/sharedDll/
make check
and this works, but it seems a little redundant as it is the build scripts themselves that are building the shared library so they know the path to the sharedLib binary location, which can be referenced from within .pro/pri files at:
$$TOP_BUILDDIR/sharedLib/release
So, is there anyway to set the PATH/LD_LIBRARY_PATH/DYLD_LIBRARY_PATH from within the project files for the purposes of the make check command?
If you are using gcc, you can use rpath parameter of gcc.
-rpath=dir
Add a directory to the runtime library search path. This is used
when linking an ELF executable with shared objects. All -rpath
arguments are concatenated and passed to the runtime linker, which
uses them to locate shared objects at runtime.
QMAKE_CXXFLAGS += -rpath=/the/absolute/path
If you use that technique, it will not be necessary to edit LD_LIBRARY_PATH
In Qt 5.5, the following qmake statement prepends the path $$TOP_BUILDDIR/sharedLib/release to LD_LIBRARY_PATH for the target check:
check.commands = LD_LIBRARY_PATH=$$TOP_BUILDDIR/sharedLib/release:\$$LD_LIBRARY_PATH $$check.commands
I drew inspiration for this solution from the files testcast.prf and qt_functions.prf (especially the functions qtAddTargetEnv() and qtAddToolEnv()), both located in $$[QT_INSTALL_PREFIX]/mkspecs/features.
I learned that qmake has a variable for searching for libs in a custom dir, it's called QMAKE_LIBDIR.
Instead of manually adding a lib path to LD_LIBRARY_PATH, you can set this in your .pro file, and then link the libraries you need with:
QMAKE_LIBDIR = /path_to_your_libs
-L/path_to_your_libs -l<whatever_lib_you_need>
Related
Question
a) How do we add library paths where the project should look for depended libraries in Qt Creator?
b) How are the settings in project >> Run >> Build Environment related to similar in .pro file? Does the environment variable listed there applies to .pro file as well (well they don't) so what are they exactly?
Context/Details:
Visual Studio has a various environment variables for folders where a project looks for include files, library files or executable files etc. This is rather confusing in Qt Creator and I havne't seen good documentation on it.
The only thing which is obvious is INCLUDEPATHvariable which points to the directories where to look for the include files (.h)
However how do I set the library paths, the path where it should look for dependent libraries/dlls etc? I can specify the exact library with LIBS variable in .pro file, there don't seem to equivalent of LIBPATH variable where it should look for other libraries if not found in current folder.
I have worked around this be adding library path the following way basically using LIBS variable but dropping the library file name and that seems to work and add the path but I don't see this documented anywhere.
LIBS += -L"$$_PRO_FILE_PWD_/Xerces/bin/"
But what makes things more interesting is the settings in Projects >> select 'Run' from current configuration and expand the Run Environment settings.
''
Here there is LIB variable and LIBPATH variable but there are clearly not .pro environment available. It also says here that these settings are local to user and saved in .pro.user file which perhaps suggest it's a different way to set but it doesn't say how to set them in .pro file but it does suggest to set them there if want to apply for all users!
Likewise there are DEPENDPATH AND VPATH and it is not really clearly what they are used for.
I don't have enough Rep to add comments to your question, So am adding my comment in form of answer. I am pretty new to Qt and have been developing Qt GUI application on Linux.
I set this LD_LIBRARY_PATH environment variable with the path to my Qt libraries. Am not sure how much it will be helpful to you since you are using visual studio on windows.
in Projects property go to Build Environment and add a variable with the libs path, example NAME_LIBPATH. So in the .pro file add the following:
# your lib configuration
LIBS += -L$$(NAME_LIBPATH) \
-llibname
I'm trying to use a SUBDIR qmake-project with relative subdirectories:
TEMPLATE = subdirs
SUBDIRS = app ../lib1
When QT creator build this project using "shadow build", which means in an other directory, it puts the output of the file this way:
Shadow-Build-Directory/
app/
main.obj
...
The problem is that because my subdir is relative, it uses the same relative path for the output, trying to put lib1 build in Shadow-Build-Directory/../lib1 !
How can I avoid this ?
EDIT: I'm using latest Qt 5.5.
New answer : I made some tests and being outside of the root project seems to be a big problem for qmake : $$shadowed() returns nothing (as stated in the documentation for being outside of source tree), and for the same reasons, .qmake.conf (undocumented feature) in root project directory isn't loaded in lib1 project.
I think the solution to you problem is to keep lib1 as a standalone project, build the library once and for all. Then include the reference to the binaries and headers of lib1 in each of your projects.
It could even be automated with qmake features :
In each of your projects, you give the path of your lib1 properly written feature, then adding
CONFIG += lib1
would automatically configure include path and link directive for your projects.
Old Answer :
Can't try right now, but I guess that
DESTDIR = $$shadowed($$PWD)/lib1
in lib.pro file should fix you problem.
I have been able create an application that depends on webkit and scripts in Qt5.2.1.But i was able to create a deb package for 14.04 version Ubuntu .But how can i make it as stand alone application .I have seen static and dynamic build .I tried static build but I don't kon w how to include webkit for static build.Also is it possible with shared library approach for creating a standalone application.Please help me out here..
Deploying a dynamically linked Qt application :
You should place Qt so files along the release version of your executable. These are libQtCore.so, libQtGui.so and possibly the ones for other modules that you have used. These so files are in your installed Qt directory in lib folder or in the directory /usr/lib/i386-linux-gnu. If you are using plugins you should place their so files in a folder named plugins beside your binary. In case of using icons and images you should ship their so files like libqico.so and libqsvg.so in a folder named imageformats.
Gathering required shared libraries :
If you want your application to run independently on a bare installed Linux, you should gather all dependent shared libraries and put them in your application directory. You can simply do it by a shell script named cpld. You can easily copy all dependencies to a folder.
It's worthy to note that you can put this in your .pro file to cause the dynamic linker to look in the same directory as your Qt application at runtime in Linux :
unix:{
# suppress the default RPATH if you wish
QMAKE_LFLAGS_RPATH=
# add your own with quoting gyrations to make sure $ORIGIN gets to the command line unexpanded
QMAKE_LFLAGS += "-Wl,-rpath,\'\$$ORIGIN\'"
}
I have several Qt projects that are dependent upon a Qt library that I've developed.
The project files (.pro) for projects which use the library define the LIBS and PRE_TARGETDEPS paths. For example: -
PRE_TARGETDEPS += ../ProjectLibrary_Qt_5_2_1_clang_64bit-Debug/projectlibrary.dylib
LIBS += -L../ProjectLibrary_Qt_5_2_1_clang_64bit-Debug -lProjectLibrary
As you can see, there is a defined path to the linked library and they have been building with Shadow Builds, via Qt Creator. The file hierarchy is like this: -
Projects
ProjectLibrary_Qt_5_2_1_clang_64bit-Debug
ProjectLib.dylib (the built library)
DependentProject
DependentProject.pro
(dylib is an OSX extension, but it could equally be .lib for Windows, or .so for linux)
However, Jenkins creates a different folder structure:-
jobs
ProjectLib
workspace
Project.dylib
DependentProject
workspace
DependentProject.pro
Now there is an extra directory (workspace), which would need this reflected in the .pro file and the names of the folders are different.
Obviously, If I just call qmake on the .pro with a Jenkins build, the path to the library is going to be wrong.
So, do I need to create a separate .pro just to be able to reflect the paths when building with Jenkins, or is there another way to handle specifying the location of libraries in the project file, for Jenkins, without having to change the directory structures?
Solution 1) Based on your current build configration
Modify your .pro file like this :
isEmpty(PROJECT_PATH) {
PROJECT_PATH=../ProjectLibrary_Qt_5_2_1_clang_64bit-Debug
}
LIBS += -L$${PROJECT_PATH} -lProjectLibrary
Then in Jenkins , you should pass PROJECT_PATH={path to your project} to qmake
Solution 2)
Using git submodule to fetch ProjectLibrary as a part of your building project. Then you don't need to build the ProjectLibrary by Qt Creator manually.
I would like to include libQtGui.so.4 libQtNetwork.so.4 and libQtCore.so.4 in the same directory as where my app resides. How would I make Qt understand this? y purpose is to have a standalone app that uses shared libraries
Setting the LD_LIBRARY_PATH environment variable is one option. For example:
export LD_LIBRARY_PATH=/path/to/dir/with/libs:$LD_LIBRARY_PATH
Another option is to set the RPATH of your Qt application during linking. Setting the RPATH to the value "$ORIGIN" will cause the dynamic linker to look in the same directory as your Qt application at runtime. For example, if using qmake, add the following snippet to your project file:
unix:!mac{
QMAKE_LFLAGS += -Wl,--rpath=\\\$\$ORIGIN
QMAKE_LFLAGS += -Wl,--rpath=\\\$\$ORIGIN/lib
QMAKE_LFLAGS += -Wl,--rpath=\\\$\$ORIGIN/libs
QMAKE_RPATH=
}
This will set the RPATH to "$ORIGIN:$ORIGIN/lib:$ORIGIN/libs", meaning that the dynamic linker will first look in the location of your Qt application, then in a lib subdirectory at its location, then in a libs subdirectory at its location, and finally in any system defined locations.
UNIX / Linux is going to look in LD_LIBRARY_PATH (if set) first before looking in the system standard libs. So if you set that, you can indeed override. Just like setting the PATH on Windows. Same effect. The ordering matters.
You can add ./ or . to LD_LIBRARY_PATH as well.
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
LD_LIBRARY_PATH and QMAKE_RPATH never worked for me. Instead, I set QMAKE_RPATHDIR in my .pro file. For example after having built and installed (make install) Qt, it has been placed in /usr/local/Trolltech/Qt-4.8.5/lib/. I then write the following in my .pro file:
QMAKE_RPATHDIR += /usr/local/Trolltech/Qt-4.8.5/lib/
Note 1: Relative paths seem not to work. Prefer absolute paths.
Note 2: When you then make, you can see that the following option is given to the linker: -Wl,-rpath,/usr/local/Trolltech/Qt-4.8.5/lib/
Note 3: To be sure that the binary links dynamically to the correct library, you can display the version of Qt at runtime delivered by qVersion().