I want to run my program in two different machines and they have two different user names and different library paths. I want to define LIBS , INCLUDEPATH and DEPENDPATH based on user name detected from the environment variable in my Qt .pro file. Is there a way to achieve it?
I am using Scientific Linux 6.5 and Qt 5.3.
Thanks in advance.
You can use $$(USER) to get the user env var in qmake. All thats left is to do is to decide which to use based on that value.
Simple example:
CURRENT_USER = $$(USER)
message("The current user is: $$CURRENT_USER")
equals(CURRENT_USER, "user1") {
LIBS += -L/first/path/lib -lstuff
INCLUDEPATH += /first/path/include
} else:equals(CURRENT_USER, "user2") {
LIBS += -L/second/path/lib -lstuff
INCLUDEPATH += /second/path/include
} //...
Note: If, for example, the library was located in ~/libs/mylib for each user, you can also do something like this:
LIBS += -L$$(HOME)/libs/mylib/lib -lstuff
INCLUDEPATH += $$(HOME)/libs/mylib/include
Related
I am creating a function in a .pri file that will be included in a .pro file with the intent of being able to do:
template(subdirs)
addMyProject(libA)
addMyProject(libB)
addMyProject(libC)
instead of
template(subdirs)
SUBDIRS += libA
libA.path = source/
SUBDIRS += libB
libB.path = source/
SUBDIRS += libC
libC.path = source/
Same problem if I want to use the depend keyword.
My current implementation is the following one:
defineTest(addMyProject) {
library_name = $$1
SUBDIRS += $$library_name
export(SUBDIRS)
{$$library_name}.file = {$$library_name}/source/{$$library_name}.pro
QMAKE_EXTRA_TARGETS += {$$library_name}
export(QMAKE_EXTRA_TARGETS)
}
The SUBDIRS part is ok. I have tried to make it work for the .file part in different ways, but still I have not found a solution.
Any hints?
[EDIT]
Each library contains different sub-projects, and the goal is to let Qt creator see only one of them (the one at the path source/libraryname.pro).
The issue is that all the libraries are correctly displayed, but also all the other sub-projects. Basically, only the SUBDIRS variable is recognised, but not the .file keyword)
firstly,I have downloaded the libconfig x64-windows via vcpkg like this:
PS E:\vcpkg> .\vcpkg install libconfig:x64-windows
then,I added the lib to my Qt project with three steps
1.add the headfile
#include "libconfig.h++"
2.specify the lib path in the pro file(I have tried two ways)
LIBS += -L$PWD -llibconfig++
#LIBS += libconfig++.lib
3.in the build debug folder,I added the libconfig++.dll
after doing those steps,project was been built successfully without any error.then I added some code like these:
libconfig::Config cfg;
try{
cfg.readFile("D:\test.cfg");
}
catch(const libconfig::FileIOException&filex) {
Q_UNUSED(filex);
qDebug()<<"error";
return;
}
qDebug()<<"success";
and the output was always :"error",I have done the everything and the Qt window was displayed successfully.Once I called readFile api,it occured an error .
I have got the answer to my issue. The file path in Windows must have the double backslash.
So I must switch:
cfg.readFile("D:\test.cfg");
to
cfg.readFile("D:\\test.cfg");
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
Absolute paths are ridiculous. All we need - and all we are allowed, by the way - is to use a folder on the same level that the folder containing .pro file for shadow builds. There are bugs otherwise.
But you can't just specify ../mingw_debug for example. Yes, it is a relative path but relative to what? It turns out it is relative to current directory of Qt Creator, and this is completely meaningless.
%{sourceDir} is of no help either. %{sourceDir}/../mingw_debug dosen't work, at least on Windows. If there was a way to extract parent folder from sourceDir!
Does anybody know a way to solve the issue?
In Qt Creator 3.6.1 at least, this is fixed - relative paths work just fine. The resolved full path is shown in the tooltip. I don't know when in the past few years this was fixed.
Not exactly shadow builds as qt-creator defines them but I am using the following to get a neat build structure.
Excerpt from a pro-file for a library that I build for multiple targets and also
in test modes.
TARGET = ../lib/common
message("libcommon:")
contains(CONFIG,test){
message("Building Test")
DESTDIR = test
TARGET = $$TARGET-test
}else{
message("Building Program")
DESTDIR = program
TARGET = $$TARGET
}
contains(MEEGO_EDITION,harmattan){
message("Maemo Harmattan")
DESTDIR = $$DESTDIR-maemo6
TARGET = $$TARGET-maemo6
DEFINES += MAEMO MAEMO6
}
unix:!maemo5:!contains(MEEGO_EDITION,harmattan){#desktop
message("Desktop")
DESTDIR = $$DESTDIR-desktop
TARGET = $$TARGET-desktop
}
contains(CONFIG,test){
TEMPLATE = app
SOURCES += $$files(src_test/main.cpp)
HEADERS += $$files(src_test/*.h)
INCLUDEPATH += src_test
}else{
TEMPLATE = lib
CONFIG += staticlib
}
CONFIG(debug, debug|release) {
message("Debug")
DESTDIR = $$DESTDIR-debug
CONFIG += debug
DEFINES += DEBUG
TARGET = $$TARGET-debug
}else{
message("Release")
//DEFINES += QT_NO_DEBUG_OUTPUT
DESTDIR = $$DESTDIR-release
TARGET = $$TARGET-release
}
MOC_DIR = build/$${DESTDIR}/moc
OBJECTS_DIR = build/$${DESTDIR}/obj
UI_DIR = build/$${DESTDIR}/ui
So you get all your object,moc,gui files in separate directories (e.g libcommon/build/program-desktop-debug/moc) and your binaries in the same with different names. To trigger one build or another you simply set a CONFIG+= in the build target. And the best about it this structure only depends on the pro file and you can put parts of it in a common.pri and use it for all your projects. No need for shadow-build configuration anymore. By the way the pro file resides in libcommon/libcommon.pro as it should.
I'm using this code in *.pro file, it seems working fine.
CONFIG(debug, debug|release){
DESTDIR=$$shadowed($$ROOT_PWD)/debug
}else{
DESTDIR=$$shadowed($$ROOT_PWD)/release
}
There are several things that can be used to make this manageable:
$$_PRO_FILE_PWD_ (version >=4.5) variable contains the directory of the current pro file being read.
Use the .qmake.cache file in the root directory of the project, and define a variable for the directory:
PROJECT_DIR = $$PWD
Then use that to navigate around beginning from the root.
how to define a config in pro file ?
by default, we have two config, debug and release. I want to add 2 other config but not in pro.user ! in pro file.
Your question is a bit unclear. It sounds like maybe you're currently building with "debug" and "release", from the command line, and you want to add your own build variants similar to that.
If that's the case... the mechanism for this is addExclusiveBuilds. Here is an example. I wouldn't recommend to mess around with it if you aren't comfortable reading qmake code.
TEMPLATE = app
SOURCES = main.cpp
# Adds two build variants.
# One of them builds the app with optimal compiler flags,
# the other one builds the app with support for collecting coverage data.
# For the first one, CONFIG will contain `optimized' and a Makefile.Optimized will be generated.
# For the second, CONFIG will contain `coverage' and a Makefile.Coverage will be generated.
# There will also be a top-level Makefile which invokes both the sub-makefiles.
addExclusiveBuilds(optimized, Optimized, coverage, Coverage)
CONFIG(optimized, coverage|optimized) {
message(I am in the optimized build variant)
QMAKE_CXXFLAGS += -O3
TARGET = myapp-optimized
}
else:CONFIG(coverage, coverage|optimized) {
message(I am in the coverage build variant)
QMAKE_CXXFLAGS += --coverage
QMAKE_LFLAGS += --coverage
TARGET = myapp-coverage
}
else {
message(I am in the glue project which contains the build variants)
# This will cause a `make' to build both optimized and coverage
# variants by default.
CONFIG += build_all
}
If I understand what you are saying, you add what you want to the CONFIG variable:
CONFIG += user_setting
...
user_setting: message( "compiling with user_setting" )
See the qmake manual where it talks about the CONFIG variable, especially near the end of the section.