QMake: Get full path of output executable - qt

In my .pro file for QMake I would like to run install_name_tool to replace some library paths. For this I need to determine path to my output executable. Particularly on macx the path to executable looks like this
<build_directory>/<configuration_name>/<target_name>.app/Contents/MacOS/<target_name>
I figured out that
message("build_directory=$${OUT_PWD}")
message("target_name=$${TARGET}")
Is there a QMake variable to populate configuration_name?
By default it is supposed to return "release" for release configurations and "debug" for debug configurations. From what I saw online people just explicitly define $${DESTDIR}
debug { DESTDIR = debug }
release { DESTDIR = release }
debug_and_release { DESTDIR = bin }
if not defined message("DESTDIR=$$DESTDIR") returns empty value for DESTDIR.

This works:
CONFIG(debug, debug|release) {
DEBUG_OR_RELEASE = debug
} else {
DEBUG_OR_RELEASE = release
}
So then the full output path is:
$${OUT_PWD}/$${DEBUG_OR_RELEASE}

Related

Check if executable is in the PATH using qmake

I have a custom build target in my *.pro file:
docs.commands = doxygen $$PWD/../docs/Doxyfile
QMAKE_EXTRA_TARGETS += docs
POST_TARGETDEPS += docs
which runs Doxygen as a post build event. The problem is, if someone builds the project and hasn't installed doxygen the build fails. Is it possible to check whether or not doxygen is installed on the machine that builds the project so that I run the doxygen command only if doxygen is installed and added to the system PATH?
With qmake, you can try this:
DOXYGEN_BIN = $$system(which doxygen)
isEmpty(DOXYGEN_BIN) {
message("Doxygen not found")
}
Another option could be the following one:
DOXYGEN_BIN = $$system( echo $$(PATH) | grep doxygen )
isEmpty(DOXYGEN_BIN) {
message("Doxygen not found")
}
BTW, if you are using CMake
You can achieve that using
find_package(Doxygen)
Example:
FIND_PACKAGE(Doxygen)
if (NOT DOXYGEN_FOUND)
message(FATAL_ERROR "Doxygen is needed to build the documentation.")
endif()
You have more information in this site:
http://www.cmake.org/cmake/help/v3.0/module/FindDoxygen.html
Try this on your .pro file:
# Check if Doxygen is installed on the default Windows location
win32 {
exists( "C:\Program Files\doxygen\bin\doxygen.exe" ) {
message( "Doxygen exists")
# execute your logic here
}
}
# same idea for Mac
macx {
exists( "/Applications/doxygen.app/ ... " ) {
message( "Doxygen exists")
}
}
Update
Using #Tarod answer you can make it cross compatible with the following
# Check if Doxygen is installed on Windows (tested on Win7)
win32 {
DOXYGEN_BIN = $$system(where doxygen)
isEmpty(DOXYGEN_BIN) {
message("Doxygen not found")
# execute your logic here
} else {
message("Doxygen exists in " $$DOXYGEN_BIN)
}
}
# Check if Doxygen is installed on Linux or Mac (tested on Ubuntu, not yet on the Mac)
unix|max {
DOXYGEN_BIN = $$system(which doxygen)
isEmpty(DOXYGEN_BIN) {
message("Doxygen not found")
# execute your logic here
} else {
message("Doxygen exists in " $$DOXYGEN_BIN)
}
}
Qt docs say:
To obtain the contents of an environment value when qmake is run, use the $$(...) operator...
i.e.:
PATH_VAR = $$(PATH)
DOXYGEN = "doxygen"
contains(PATH_VAR, DOXYGEN) {
message("Doxygen found")
}

Qt 4.8.4 Creating release

I'm trying to build a release version of a project I'm working on. When building in Qt creator in Debug it works great. When I try building as release I get "cannot find -lQtSerialPort". Qt 4.8.4 does not include QtSerialPort. I had to add that manually. I'm assuming there is something I'm forgetting to include here. Possibly in the .pro file?
Also, I noticed in my Qt/4.8.4/lib directory I have many .prl files. There is one for QtSerialPortd.prl. This is the only one in here that seems to have a .dll version. Not sure if this is significant or not.
Makefile includes this:
Makefile: ???.pro
c:/Qt/4.8.4/mkspecs/features/serialport.prf \
$(QMAKE) -config release -o Makefile ???.pro
c:/Qt/4.8.4/mkspecs/features/serialport.prf:
serialport.prf looks like this:
qtAddLibrary(QtSerialPort)
!isEmpty(QTSERIALPORT_BUILD_ROOT) {
INCLUDEPATH -= $$QMAKE_INCDIR_QT/QtSerialPort
QMAKE_INCDIR += $$QTSERIALPORT_BUILD_ROOT/include $$QTSERIALPORT_BUILD_ROOT/include/QtSerialPort
QTSERIALPORT_BUILD_SUBDIR = src/serialport
debug_and_release_target {
CONFIG(debug, debug|release) {
QTSERIALPORT_BUILD_SUBDIR = $$QTSERIALPORT_BUILD_SUBDIR/debug
} else {
QTSERIALPORT_BUILD_SUBDIR = $$QTSERIALPORT_BUILD_SUBDIR/release
}
}
QMAKE_LIBDIR += $$QTSERIALPORT_BUILD_ROOT/$$QTSERIALPORT_BUILD_SUBDIR
}
mac {
LIBS -= -framework QtSerialPort$${QT_LIBINFIX}
if(!debug_and_release|build_pass):CONFIG(debug, debug|release) {
LIBS += -lQtSerialPort$${QT_LIBINFIX}_debug
} else {
LIBS += -lQtSerialPort$${QT_LIBINFIX}
}
}
Edit:
After figuring out I can change the name of the file by removing the d at the end, I realized that all the libraries included on the exe that is built include files that do not end in 'd.dll' with the exception of the QtSerialPortd.dll file.
I.E ldd on the debug .exe:
QtCored4.dll => /cygdrive/c/Qt/4.8.4/bin/QtCored4.dll (0x69cc0000)
QtGuid4.dll => /cygdrive/c/Qt/4.8.4/bin/QtGuid4.dll (0xf30000)
QtNetworkd4.dll => /cygdrive/c/Qt/4.8.4/bin/QtNetworkd4.dll (0x6cb40000)
QtSerialPortd.dll => /cygdrive/c/Qt/4.8.4/bin/QtSerialPortd.dll (0x63680000)
ldd on the release .exe:
QtCore4.dll => /cygdrive/c/Qt/4.8.4/bin/QtCore4.dll (0x6e0c0000)
QtGui4.dll => /cygdrive/c/Qt/4.8.4/bin/QtGui4.dll (0x67700000)
QtNetwork4.dll => /cygdrive/c/Qt/4.8.4/bin/QtNetwork4.dll (0x65c80000)
QtSerialPortd.dll => /cygdrive/c/Qt/4.8.4/bin/QtSerialPortd.dll (0x63680000)
Release vs Debug, it looks like the QtSerialPortd.dll remained the same. I'm guessing this is going to be problematic when I try this application on different machines.
I changed the name of Qt/4.8.4/lib/libQtSerialPortd.a to Qt/4.8.4/lib/libQtSerialPort.a. It builds now. Not sure if this is going to have adverse effects.

qmake CONFIG constains release and debug variable at the same time

I want to change some DEFINES and LIBS paths depending on Debug or Release build configuration, but my CONFIG variable constains release and debug variables at the same time.
Simple test in pro file:
CONFIG(debug, debug|release) {
message(DEBUG build)
}
CONFIG(release, debug|release) {
message(RELEASE build)
}
This test outputs:
Project MESSAGE: DEBUG build
Project MESSAGE: RELEASE build
How should I set up my project?
You should use this:
debug_and_release_target {
CONFIG(debug, debug|release) {
message("debug")
} else {
message("release")
}
}
This is what we use inside Qt as well, including QtSerialPort. Although we use this as well for Mac, just in case:
if(!debug_and_release|build_pass):CONFIG(debug, debug|release) {
LIBS += -lQtSerialPort$${QT_LIBINFIX}_debug
} else {
LIBS += -lQtSerialPort$${QT_LIBINFIX}
}

Best way to make QMake switch INCLUDEPATH on debug/release

I have a Qt project (.pro) which has some dependencies that put the include directory in a "release" or "debug" directory when built. What is the best practice method of "switching" which directories are in the include in debug and release? At the moment I have this in my .pro:
CONFIG(debug, debug|release) {
CONFIGURATION = debug
DESTDIR = $${PWD}/../../Interface/Debug
} else {
CONFIGURATION = release
DESTDIR = $${PWD}/../../Interface/Release
}
GENDIR = $${DESTDIR}/Generated
OBJECTS_DIR = $${GENDIR}/obj
MOC_DIR = $${GENDIR}/moc
RCC_DIR = $${GENDIR}/rcc
UI_DIR = $${GENDIR}/ui
INCLUDEPATH += $(LIBOPC_DIR)/$${CONFIGURATION}/include
However if I import this into VS2012 via the Qt VisualStudio plugin it puts $(LIBOPC_DIR)/debug/include into both the debug and release configurations... am I doing something wrong or is this a limitation of the VS plugin and/or qmake?

How can i add custom build steps in Qt-Creator?

After build my app, i want copy it to specific directory (on Windows 7).
Custom build step
cmd.exe \c \k copy MyPlugin.dll ..\..\..\HostApp\Debug\plugins
But I have error:
Can't run process "cmd.exe \c \k copy MyPlugin.dll ..\..\..\HostApp\Debug\plugins"
That's wrong?
One way to do it would be to change the build output directory in the .pro file.
Something like
CONFIG(debug, debug|release) {
DESTDIR = C:/myApp/debug
} else {
DESTDIR = C:/myApp/release
}
Or in your particular case
CONFIG(debug, debug|release) {
DESTDIR = ..\..\..\HostApp\Debug\plugins
} else {
DESTDIR = ..\..\..\HostApp\Release\plugins
}
Edit:
This question has some good alternatives to my answer.

Resources