Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cmake generator expression command

Tags:

cmake

If some boolean condition is true (such as ENABLE_TESTING) then I want to run something like:

COMMAND ./b2 --with-filesystem --with-program_options --with-test

And if the boolean condition is false, then I instead want:

COMMAND ""

It seems like I can achieve that with this very ugly code:

COMMAND $<$<BOOL:${ENABLE_TESTING}>:./b2> $<$<BOOL:${ENABLE_TESTING}>:--with-filesystem> $<$<BOOL:${ENABLE_TESTING}>:--with-program_options> $<$<BOOL:${ENABLE_TESTING}>:--with-test>

But as you can see, I have to repeat the boolean test over and over. If I naively try to combine them into a single expression:

COMMAND $<$<BOOL:${ENABLE_TESTING}>:./b2 --with-filesystem --with-program_options --with-test>

Then I get the error /bin/sh: 1: $<1:./b2: not found. The spaces, apparently, get parsed before the generator expression is evaluated. So I quote the whole thing:

COMMAND "$<$<BOOL:${ENABLE_TESTING}>:./b2 --with-filesystem --with-program_options --with-test>"

But this produces the error /bin/sh 1: /b2 --with-filesystem --with-program_options --with-test: not found. I suppose it's treating the whole thing as the name of a command rather than a command with options. How can I write this in a way that is clean and works?

EDIT: I've tried to simplify the code for a minimum example, but there's an extra complication I left out. This command is happening in an ExternalProject_Add section, and I need to rely on special tokens such as <BINARY_DIR>.

COMMAND ./b2 "--stagedir=<BINARY_DIR>" --with-filesystem --with-program_options --with-test

I can't move the commands into an if statement elsewhere, because if I do then the directory tokens aren't expanded.

like image 629
Jeff M Avatar asked Nov 18 '22 01:11

Jeff M


1 Answers

Code readability-wise, generator expressions are an unfortunate addition to the CMake language. In scenarios like yours where generator expression cannot be avoided, I use a regular CMake variable to avoid code duplication, i.e.:

set (_runB2GenEx "$<BOOL:${ENABLE_TESTING}>")
ExternalProject_Add(example
    ...
    COMMAND 
        $<${_runB2GenEx}:./b2> 
        $<${_runB2GenEx}:--stagedir=<BINARY_DIR>> 
        $<${_runB2GenEx}:--with-filesystem> 
        $<${_runB2GenEx}:--with-program_options> 
        $<${_runB2GenEx}:--with-test>
    ...
)
like image 95
sakra Avatar answered Feb 19 '23 05:02

sakra