CMake variable or property to discern betwen debug and release builds - build-process

I want to set a CMake variable differently for debug and release builds. I have tried to use CMAKE_CFG_INTDIR like this:
IF(${CMAKE_CFG_INTDIR} STREQUAL "Debug")
SET(TESTRUNNER DllPlugInTesterd_dll)
ELSE(${CMAKE_CFG_INTDIR} STREQUAL "Debug")
SET(TESTRUNNER DllPlugInTester_dll)
ENDIF(${CMAKE_CFG_INTDIR} STREQUAL "Debug")
But this variable evaluates to $(OUTDIR) at the time CMake does its thing.
Is there a CMake variable I can use to discern between debug and release builds, or something along the lines of how TARGET_LINK_LIBRARIES where one can specify debug and optimized libraries?
EDIT: I cannot use CMAKE_BUILD_TYPE since this is only supported by make based generators and I need to get this working with Visual Studio.

You can define your own CMAKE_CFG_INTDIR
IF(NOT CMAKE_CFG_INTDIR)
SET(CMAKE_CFG_INTDIR "Release")
ENDIF(NOT CMAKE_CFG_INTDIR)
IF(CMAKE_CFG_INTDIR MATCHES "Debug")
...Debug PART...
ELSE(CMAKE_CFG_INTDIR MATCHES "Debug")
...Release PART...
ENDIF(CMAKE_CFG_INTDIR MATCHES "Debug")
Then, when you call cmake add the Definition (-D):
cmake -DCMAKE_CFG_INTDIR=Debug /path/of/your/CMakeLists.txt
For targets, you have two solutions:
First one:
IF(CMAKE_CFG_INTDIR MATCHES "Debug")
TARGET_LINK_LIBRARIES(YOUR_EXE DllPlugInTesterd...)
ELSE(CMAKE_CFG_INTDIR MATCHES "Debug")
TARGET_LINK_LIBRARIES(YOUR_EXE DllPlugInTester...)
ENDIF(CMAKE_CFG_INTDIR MATCHES "Debug")
Second one:
IF(CMAKE_CFG_INTDIR MATCHES "Debug")
FIND_LIBRARY(DLL_PLUGIN DllPlugInTesterd_dll /path/of/your/lib)
ELSE(CMAKE_CFG_INTDIR MATCHES "Debug")
FIND_LIBRARY(DLL_PLUGIN PlugInTester_dll /path/of/your/lib)
ENDIF(CMAKE_CFG_INTDIR MATCHES "Debug")
Then for link
TARGET_LINK_LIBRARIES(YOUR_EXE ${DLL_PLUGIN}...)

Try to use CMAKE_BUILD_TYPE instead

Related

Add an extension in a .pro variable

I'm trying to print a message with QMake but I have problems with extensions:
lib_name = $$1
message("test1: $$MYPATH/$$lib_name/src/$$lib_name.pri");
message("test2: $$MYPATH/$$lib_name/src/$$lib_name");
For some reason, test1 doesn't print the correct path. It just prints the path until src/. But, test2 is ok. It prints everything until the value in $$1.
Any workaround?
QMake supports variables (objects) with members that can be used using the dot . operator e.g. target.path for INSTALLS. So, in your case, $$lib_name.pri means that you're accessing the member pri of lib_name which doesn't exist so there's no output.
You need to enclose variables in curly braces for QMake to distinguish them from the surrounding text i.e. $${lib_name}.pri.
Example:
message("test1: $$MYPATH/$$lib_name/src/$${lib_name}.pri");
# ~~~~~~~~~~~~
For more examples of objects, see Adding Custom Target and Adding Compilers sections of QMake's Advanced Usage page.
Here's another relevant SO thread: QMake - How to add and use a variable into the .pro file

Qt qmake TARGET value with special characters

How can I name output executable in qmake, with local characters like ä or ź. Every time I put a TARGET value with special characters, Qt throwing an error:
No rule to make target 'xxx.rc', needed by 'xxx.o'. Stop.
ex. TARGET = "genügen" or TARGET = "Obciążeń"

Qt Installer Framework : Create shortcut with argument

Does anyone know how to add an argument to a shortcut created by QT IFW?
I need the exe it launches to be passed an argument.
Here's what works (with no argument):
component.addOperation( "CreateShortcut",
"#TargetDir#/MyApp.exe",
"#StartMenuDir#/#ProductName#.lnk",
"workingDirectory=#TargetDir#",
"iconPath=#TargetDir#/MyApp.exe",
"iconId=0");
I want the exe to get something like -c passed to it. I've tried a few approaches, but am not having any luck.
Qt Installer framework documentation is very poor, but you can read in operations the following:
"CreateShortcut" filename linkname [arguments]
Creates a shortcut from the file specified by filename to linkname. On Windows, this creates a .lnk file which can have arguments. On Unix, this creates a symbolic link.
So do it in that way:
component.addOperation("CreateShortcut", "#TargetDir#/Appname.exe", "#DesktopDir#/Appname.lnk", "-param");
Result in lnk target element:
C:\YourAppDirectory\Appname.exe -param
EDIT:
Your case works as well for me:
component.addOperation( "CreateShortcut","#TargetDir#/Appname.exe","#StartMenuDir#/#‌​ProductName#.lnk", "-param", "workingDirectory=#TargetDir#", "iconPath=#TargetDir#/Appnam‌​e.exe","iconId=0");
with -param as the last argument too.

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

Resources