qmake: clean way to copy qt dlls into output folder - qt

OK, I have read existing answers about this question.
But no one is tolerable.
See how-to-copy-qt-runtime-dlls-to-project-output
But $$QMAKE_LIBDIR_QT doesn't contain any dll files. All dlls are located in the "bin" directory in qt installation. On the other hand, QMAKE_LIBDIR_QT refers to "lib" directory.
So, this method doesn't work.
Do anybody have a working method of doing this thing?

I do
QMAKE_DLLDIR_QT = $$QMAKE_LIBDIR_QT/../bin
but since 5.0 they no longer define QMAKE_LIBDIR_QT
my quick solution is:
isEmpty(QMAKE_LIBDIR_QT) : {
SPLITED=$$section(QMAKESPEC, "/", 0, -3)
QMAKE_LIBDIR_QT = $$SPLITED/lib
}
but
https://bugreports.qt-project.org/browse/QTBUG-28901
suggest we should use other method
PS: LIBDIR contains static lirbaries used for linker

Related

QMake 5.15 don't understand wildcard adding files [duplicate]

I have a .pro file which looks like:
SOURCES += myfolder/source1.cpp \
myfolder/source2.cpp
HEADERS += myfolder/header1.h\
myfolder/header2.h
FORMS += myfolder/form1.ui\
myfolder/form2.ui
And everything works great. However, if I try to use an asterisk to include all the files, i.e.:
SOURCES += myfolder/*.cpp
HEADERS += myfolder/*.h
FORMS += myfolder/*.ui
qmake throws a file-not-found-error:
WARNING: Failure to find: myfolder\*.cpp
[...]
:-1: error: No rule to make target `myfolder/*.cpp', needed by `release/source1.o'. Stop.
In both cases, Qt-Creator can find the files.
Is there a way to use the asterisk? It's annoying to type the files manually.
Thank you!
[EDIT: Qt 4.8.4, Windows 7, Qt-Creator 2.6.1. Sry for forgetting this thought it isnt needed.]
[EDIT: Found solution: http://qt-project.org/forums/viewthread/1127 . Thank you anyway!]
In qmake 3.0, at least, it's possible to use something like:
SOURCES = $$files(*.cpp, true)
HEADERS = $$files(*.h, true)
The true argument will cause the files function to recursively find all files matching the pattern given by the first argument.
At first, using asterisk is bad practice - despite that qmake allows it, QtCreator cannot edit such *.pro correctly on adding new, renaming or deleting file. So try to add new files with "New file" or "Add existing files" dialogs.
QMake has for loop and function $$files(directory_path: String). Also append files to SOURCES or HEADERS variable respectively.
Brief example, which adds all files, but not directories, to variable FILES (not affect build or project tree):
files = $$files($$PWD/src)
win32:files ~= s|\\\\|/|g
for(file, files):!exists($$file/*):FILES += $$file
If you want to check if file is *.cpp, try to use contains($$file, ".cpp").
files = $$files($$PWD/src)
win32:files ~= s|\\\\|/|g
for(file, files):!exists($$file/*):contains($$file, ".cpp"):SOURCES += $$file

Is it possible to use system environment variables in Qt resource file?

I want to import some of resources from another project without copying into my project directory. Environment variable ANOTHER_PROJECT_DIR stores path to another project.
I've tried to do something like this:
<file>%ANOTHER_PROJECT_DIR%/file</file>
or this:
<file>$$(ANOTHER_PROJECT_DIR)/file</file>
in my qrc file.
So is it possible to use system environment variables in Qt resource file and how can I do it?
It would be great to find crossplatform solution
qrc resource file is a static binary resource link. You cannot do it dynamically. However, you can do something like this from your code
#include <QProcessEnvironment>
...
somefunc(){
QString env = qgetenv("SOME_VAR");
QString filepath = env + "/path/to/file";
...
}
Rcc does not support such functionality. You can use qmake's "substitutes" (still undocumented?) feature instead.
test.pro
myqrc.input = myqrc.in
myqrc.output = myqrc.qrc
QMAKE_SUBSTITUTES += myqrc
myqrc.in
<file>$$(ANOTHER_PROJECT_DIR)/file</file>
Basically, "substitutes" is a builtin preprocessor capable of evaluating/expanding "qmake"-expressions (plus !!IF / !!ELSE / !!ENDIF conditional).

CMAKE - Changing outdir macro through cmake

Reading others questions here I found that is possible to change the outdir macro inside de visual studio. I really searched but didn't found/understand how to do it.
It's kind simple. I just want to change the Project property -> Configuration Properties -> General -> Output Directory. Because I know that will change the outdir macro.
I understand that is throught set_target_property using some kind of cmake PROPERTY but I really didn't found how.
It's pretty straightforward as you suspected. You need to look at the ARCHIVE_OUTPUT_DIRECTORY, LIBRARY_OUTPUT_DIRECTORY, and RUNTIME_OUTPUT_DIRECTORY target properties to modify the outdir path.
These all have config-specific variants too (e.g. ARCHIVE_OUTPUT_DIRECTORY_DEBUG) and can all be initialised by the global CMake variables of the same name with a CMAKE_ prepended.
So, you can do e.g.
set_target_properties(MyExe PROPERTIES RUNTIME_OUTPUT_DIRECTORY <custom path>)
or, to affect all targets,
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY <custom path>)
NB. From the docs:
Multi-configuration generators (VS, Xcode) append a per-configuration subdirectory to the specified directory.
Here's an example showing this behaviour. It writes its own trivial C++ source files, so all you should need to do is copy this to a folder, invoke CMake then try building the resultant solution in Debug, Release, MinSizeRel and RelWithDebInfo. Tested with VS2012. The executable always ends up in <build dir>/Exes/Debug regardless of build type, and similarly the library is always in <build dir>/Libs/Debug.
cmake_minimum_required(VERSION 2.8.11 FATAL_ERROR)
project(Example)
file(WRITE lib.hpp "void Print();\n")
file(WRITE lib.cpp "#include<iostream>\nvoid Print() { std::cout << \"Hello World\\n\"; }\n")
file(WRITE main.cpp "#include \"lib.hpp\"\nint main() { Print(); return 0; }\n")
set(ArchiveOutputDir ${CMAKE_BINARY_DIR}/Libs/Debug)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${ArchiveOutputDir})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_MINSIZEREL ${ArchiveOutputDir})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${ArchiveOutputDir})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO ${ArchiveOutputDir})
set(RuntimeOutputDir ${CMAKE_BINARY_DIR}/Exes/Debug)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${RuntimeOutputDir})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${RuntimeOutputDir})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${RuntimeOutputDir})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${RuntimeOutputDir})
add_library(MyLib lib.cpp lib.hpp)
add_executable(MyExe main.cpp)
target_link_libraries(MyExe MyLib)
In the end, what worked for me was placing the full path on the target_link_libraries with debug prefix and optimized prefix to point release config and relwithdebinfo config to release path and debug to debug. I also took off the link_directories... I don't if I didn't understand but it worked for me!

Qt - Using asterisk (*) in .pro-File with directories

I have a .pro file which looks like:
SOURCES += myfolder/source1.cpp \
myfolder/source2.cpp
HEADERS += myfolder/header1.h\
myfolder/header2.h
FORMS += myfolder/form1.ui\
myfolder/form2.ui
And everything works great. However, if I try to use an asterisk to include all the files, i.e.:
SOURCES += myfolder/*.cpp
HEADERS += myfolder/*.h
FORMS += myfolder/*.ui
qmake throws a file-not-found-error:
WARNING: Failure to find: myfolder\*.cpp
[...]
:-1: error: No rule to make target `myfolder/*.cpp', needed by `release/source1.o'. Stop.
In both cases, Qt-Creator can find the files.
Is there a way to use the asterisk? It's annoying to type the files manually.
Thank you!
[EDIT: Qt 4.8.4, Windows 7, Qt-Creator 2.6.1. Sry for forgetting this thought it isnt needed.]
[EDIT: Found solution: http://qt-project.org/forums/viewthread/1127 . Thank you anyway!]
In qmake 3.0, at least, it's possible to use something like:
SOURCES = $$files(*.cpp, true)
HEADERS = $$files(*.h, true)
The true argument will cause the files function to recursively find all files matching the pattern given by the first argument.
At first, using asterisk is bad practice - despite that qmake allows it, QtCreator cannot edit such *.pro correctly on adding new, renaming or deleting file. So try to add new files with "New file" or "Add existing files" dialogs.
QMake has for loop and function $$files(directory_path: String). Also append files to SOURCES or HEADERS variable respectively.
Brief example, which adds all files, but not directories, to variable FILES (not affect build or project tree):
files = $$files($$PWD/src)
win32:files ~= s|\\\\|/|g
for(file, files):!exists($$file/*):FILES += $$file
If you want to check if file is *.cpp, try to use contains($$file, ".cpp").
files = $$files($$PWD/src)
win32:files ~= s|\\\\|/|g
for(file, files):!exists($$file/*):contains($$file, ".cpp"):SOURCES += $$file

configure qmake for install headers to different subfolders

I have project where header files are in different subfolders (/config/.h; /thread/.h etc)
in qt project file they are included like:
HEADERS += $$PWD/src/*.h
HEADERS += $$PWD/src/config/*.h
then install is described as simple:
headers.files = $$HEADERS
headers.path = $$INSTALL_INC_DIR/proj
some other projects that use this lib will include files from that install dir and there problem occurs - all .h files are copied to same folder, without subfolders and in code they are included with subfolders (#include <proj/config/config.h>).
Is it possible to tell qmake (or actually nmake) that when copying files keep original folder stucture?
This works for me:
headerinstall.pri:
for(header, INSTALL_HEADERS) {
path = $${INSTALL_PREFIX}/$${dirname(header)}
eval(headers_$${path}.files += $$header)
eval(headers_$${path}.path = $$path)
eval(INSTALLS *= headers_$${path})
}
at the end of your .pro file:
INSTALL_PREFIX = /tmp/installprefix
INSTALL_HEADERS = $$HEADERS
include(headerinstall.pri)
I am sure, that the currently accepted answer from 2013 was valid for the time being.
However, it did not work well for me with all the slashes and dots and colons in the $${path}. Also we have to put $$list() around a list of files nowadays to use it in a for loop.
Here is the approach I came up with. I wrote that in a *.pri file and added it to my directory structure. No need for the extra INSTALL_HEADERS variable:
for(header, $$list($$HEADERS)) {
path = $$OUT_PWD/../include/$$dirname(header)
pathname = $$replace(path,/,)
pathname = $$replace(pathname,\.,)
pathname = $$replace(pathname,:,)
file = headers_$${pathname}
eval($${file}.files += $$header)
eval($${file}.path = $$path)
INSTALLS *= $${file}
}
Note that the replacement characters may vary for you. For example, my first approach above had still problems with whitespaces in the path, so I added:
pathname = $$replace(pathname," ",)

Resources