Reputation: 11046
I created an empty Qt Project to illustrate my issue. There is NOTHING in the project whatsoever except for this QMake code in a in pro file. The project/build configuration is just the defaults.
This Qmake code ALWAYS executes the $$system()
function, but it does it "behind the scenes". There is some mystery process in which contains( DEFINES, anything )
ALWAYS evaluates to true and fires off the subsequent code. Note that you can literally use any value where I've used something
and anything
.
CONFIG( something ){ DEFINES+=anything }
contains( DEFINES, anything ){
message( anything! )
stdOut=$$system( echo x > test.txt )
}
else{
message( nothing! )
}
Every time this is run (I'm just saving the file in QtCreator to kick it off btw - NOT running QMake), this General Message appears:
Project MESSAGE: nothing!
A second later, the test.txt file appears in the project directory.
Adding to the oddity, if you use the CONFIG()
directly as the condition to control the file writing, then this does NOT happen. Further, if you remove that CONFIG()
line this does NOT happen.
It seems that there is a mysterious background process which evaluates this and ALWAYS executes DEFINES+=anything
and then continues to process whatever logic is present.
I know that if you add source files to the project conditionally, they will always appear in the file browsing tree, even if they are not compiled. That is an example where Qt Creator ignores conditionals and executes the QMake for it's own purposes. Is this the same mechanism at play?
Upvotes: 4
Views: 1290
Reputation: 11046
I wasted a couple of hours fighting this, and then arrived at an answer just after posting my question. I often find that the act of simply explaining my issue in detail seems to clarify how to solve it!
Anyway, I'm pretty sure that my guess is correct about what is happening under the hood. Qt Creator performs a pass of the code where it ignores all conditionals in order to create the defines (for whatever private purpose...).
One solution would be to not a set define value, and just use a QMake variable like this:
CONFIG( something ){ IS_SOMETHING=true } else { IS_SOMETHING=false }
$$IS_SOMETHING{
message( anything! )
stdOut=$$system( echo x > test.txt )
}
else{
message( nothing! )
}
That's fine if you only need to use a subsequent conditional within the QMake. The weakness of that, however, is you don't have the logic cascade down into your C++. So, I found a better solution:
defineReplace( hideFromIdeParser ){ return( $$1 ) }
CONFIG( something ){ DEFINES+=$$hideFromIdeParser(anything) }
contains( DEFINES, anything ){
message( anything! )
stdOut=$$system( echo x > test.txt )
}
else{
message( nothing! )
}
Apparently, the blackbox parser does not resolve function results, so this trick makes everything work as desired!
Upvotes: 2