premake5 precompiled headers not working - premake

(this is using Premake5 alpha binary available for download on website)
I'm trying to port my existing VS solution over to using premake5.
It uses MS style precompiled headers(stdafx.h/stdafx.cpp).
When I specify this is my test project:
pchheader "stdafx.h"
pchsource "stdafx.cpp"
It does set the project to using precompiled headers, but it is not setting stdafx.cpp to generate precompiled headers(/Yc). Instead all the files in the project are trying to use(/Yu) and nobody is generating the PCH. So it does not build..
I'm guessing this does works somehow, what black magic am I missing here?
Here is my entire premake5 file for reference
-- premake5.lua
solution "Cloud"
configurations { "Debug", "Release", "Final" }
platforms { "Win32_AVX2", "Win64_AVX2"}
location "premake"
flags{"MultiProcessorCompile", "ExtraWarnings", "FatalCompileWarnings", "FatalLinkWarnings", "FloatFast"}
startproject "Cloud"
vectorextensions "AVX2"
filter { "platforms:Win32" }
system "Windows"
architecture "x32"
filter { "platforms:Win64" }
system "Windows"
architecture "x64"
filter "configurations:Debug"
defines { "DEBUG" }
flags { "Symbols" }
filter "configurations:Release"
defines { "NDEBUG" }
flags{"Symbols"}
optimize "Speed"
filter "configurations:Final"
defines { "NDEBUG" }
flags{"LinkTimeOptimization"}
optimize "Speed"
group "app"
--primary executable
project "Cloud"
location "../src_test/cloud"
kind "ConsoleApp"
language "C++"
targetdir "..//%{cfg.buildcfg}"
pchheader "stdafx.h"
pchsource "stdafx.cpp"
vpaths{
{["src/pch/*"] = "../src_test/cloud/stdafx.*"},
{["src/*"] = "../src_test/cloud/**.cpp"},
{["module/*"] = "../src_test/cloud/Module*.h"},
{["core/*"] = "../src_test/cloud/Core*.h"},
{["headers*"] = "../src_test/cloud/*.h"},
--{["src_c/*"] = "../src_test/cloud/**.c"}
}
files { "../src_test/cloud/*.h", "../src_test/cloud/*.c", "../src_test/cloud/*.cpp", "../src_test/cloud/*.hpp" }
One related question: how do I disable precompiled header usage on specific files within a project? Some of my files will not build if the PCH is included, so I have manually disabled them in the existing solution/projects.
Thanks!

It's probably because pchsource requires a file path (like files) Since your stdafx.cpp is not in the same directory as your script, Premake does not find it. Try using pchsource "../src_test/cloud/stdafxcpp" instead, it should fix the problem.
Also I see that you don't add "../src_test/cloud/" as an include directory, so that means that your pch header will be included using relative path, right ? If so, you'll need to update pchheader to reflect that. Due to the way Visual Studio works, you need to set pchheader as it appears in your cpp files. E.g. if in your cpp files you have #include "../src_test/cloud/stdafx.h" you need to use this in Premake: pchheader "../src_test/cloud/stdafx.h".
And finally, to deactivate precompiled headers on certain files, you can use filters:
-- deactivate precompiled headers for C files
filter "files:**.c"
flags { "NoPCH" }

I am changing a script from premake 4 to premake 5 and I had some troubles to deactivate pch on a specific file with :
filter "files:myfile.cpp"
flags { "NoPCH" }
It was disabling pch on the whole project and not on a specific file.
But it was because pchsource and pchheader were defined after the filtering.
When we flag a file with no PCH, pchsource and pchheader have to be defined first.

Related

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).

QMake: test functions do not work as expected

In QtCreator 4.2.0 I try to use one *.pro file for building binaries for multiple hardware configurations.
In Build & Run => Build Settings => Build Enviroment I define the enviroment variable TARGET like as follows:
Build Settings A: Variable TARGET has Value bbb
Build Settings B: Variable TARGET has Value desktop
In the pro-file I use the following test functions:
equals($$TARGET,"bbb")
{
message("setting include paths for bbb"))
message($$TARGET)
}
equals($$TARGET,"laptop")
{
message("setting include paths for laptop.")
message($$TARGET)
}
contains($$TARGET,"*bbb*")
{
message("setting include paths for bbb"))
message($$TARGET)
}
contains($$TARGET,"*laptop*")
{
message("setting include paths for laptop.")
message($$TARGET)
}
And I get this output when running qmake:
Project MESSAGE: setting include paths for bbb
Project MESSAGE: bbb
Project MESSAGE: setting include paths for laptop.
Project MESSAGE: bbb
Project MESSAGE: setting include paths for bbb
Project MESSAGE: bbb
Project MESSAGE: setting include paths for laptop.
Project MESSAGE: bbb
Project MESSAGE: setting include paths for bbb
This makes no sense to me an I can't figure what I'm doing wrong here. Why are the parts after testing fro laptop executed?
By the way, I solved my problem by using Scopes. This works perfect for me:
CONFIG += $$(TARGET_HW)
desktop {
message("setting include paths for laptop.")
}
cetec {
message("setting include paths for cetec."))
}
But I'm still interested in the correct way of using test functions.
I provide the correct syntax for the first test, as an example:
equals(TARGET,"bbb") {
message("setting include paths for bbb"))
message($$TARGET)
}
Please notice:
The curly brace is on the same line of the test.
The variable tested has no dollar signs, just the variable name
The opening brace must written on the same line as the condition (https://doc.qt.io/qt-5/qmake-language.html#scope-syntax).
There are so many issues in your question, that there is place for another answer, adding to the previous correct ones:
as #daru says, you need to open the brace in the same line as the test function.
as #p-a-o-l-o says, contains and equals syntax require variable names as first arguments, without $$.
TARGET is an internal variable, that contains the base name of the project file by default. It becomes the name of the executable or library you are building.
You may use an environment variable named TARGET, but then you should assign it to a qmake variable name with another name.
sample code:
TGT=$$(TARGET)
equals(TGT,"bbb") {
message("$$TGT equals bbb"))
message(TGT=$$TGT)
}
equals(TGT,"laptop") {
message("$$TGT equals laptop")
message(TGT=$$TGT)
}
contains(TGT,"bbb") {
message("$$TGT contains bbb"))
message(TGT=$$TGT)
}
contains(TGT,"top") {
message("$$TGT contains top")
message(TGT=$$TGT)
}

How to add a logic to .pro file based on configuration?

In my application (qmake based) I have 2 configuration, let's say CONF1 and CONF2.
Each configuration defines "Additional arguments" at Project/Build settings/Build step tab:
DEFINES+=CONF1
and
DEFINES+=CONF2
So in C++ code I can add some specified logic for specified build configuration:
#if defined CONF1
logo->setPixmap(QPixmap("conf1.png"));
#else
logo->setPixmap(QPixmap("conf2.png"));
#endif
Also I need to define icon for the application executable.
So in .pro file I've added:
win32 {
RC_ICONS = logo.ico
}
But the problem that I need different icons for different configuration.
I've tried:
contains(DEFINES, CONF1) {
RC_ICONS = conf1.ico
}
else {
RC_ICONS = conf2.ico
}
but that doesn't work. It looks that contains works only for variables defined inside .pro file only.
So my question - how can I add different settings (icons in my case) for different configuration?
As far as I'm aware qmake can't evaluate variables set in the DEFINES list, but only qmake variables.
However, you can use a qmake variable to perform both tasks at the same time. Just assign the "conf" value to your variable, evaluate that variable to add it to the DEFINES list and then test its value using qmake functions (e.g. equals).
As an example:
Add the following to your additional qmake arguments (including quotes):
"MYCONF = CONF1"
Then use these directives in your .pro file:
DEFINES += $${MYCONF}
equals(MYCONF, "CONF1") {
RC_ICONS = conf1.ico
} else {
RC_ICONS = conf2.ico
}

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!

qmake: clean way to copy qt dlls into output folder

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

Resources