1

For users that are using cmake 3.15 or later and are also using Ninja as a generator, I want to set the new JOB_POOL argument to some large add_custom_command() blocks. For other users, I want to keep my add_custom_command() the same (no JOB_POOL).

In earlier steps, I check the version and the generator and set ${JOB_POOLS} and I also set a variable such that users who should use a pool will see (something like):

For historical reasons, I leave this here, although @Tsyvarev points out that this is the source of my problem! The double-quotes are NOT wanted here!

set(USE_POOL "JOB_POOL pool_A")

Users that are not using a pool will not have that variable set.

Now how to leverage that variable in my custom command...?

1.) Generator expressions don't work, just including the text with the previous line...

add_custom_command(
  ...
  $<USE_POOL>
  )

2.) I can't seem to simply place the variable in the command, again just including the variable contents on the previous line. For example, when ${JOB_POOL} is set to the string "JOB_POOL pool_A", this code...

For historical reasons, I leave this here, although @Tsyvarev points out that this is the source of my problem! Don't use a STRING! No double-quotes!

add_custom_command(
  OUTPUT foo
  DEPENDS bar
  # Comment line here...
  ${USE_POOL}
  COMMAND
    ${CMAKE_COMMAND} -E ...
  )

gives this error...

ninja: error: '../path/to/src/dir/JOB_POOL pool_A', needed by 'path/to/src/dir/foo', missing and no known rule to make it 

It simply considers the ${JOB_POOL} string to be another dependency!

3.) I can't use the "APPEND" feature of add_custom_command(). It's just ignored...

if (${USE_POOL})
  add_custom_command(
    ...
    APPEND
    JOB_POOL pool_A
    )
endif()

The only thing that seems to work is to put an "if" around my entire command, which offends my sensibility since I don't like to duplicate so much code...

if(${USE_POOL})
  add_custom_command(
    ...many lines...
    JOB_POOL pool_A
    )
else()
  add_custom_command(
    ...many lines...
    )
endif()

Do you have a better idea...?

Here's a standalone example for @tsyvarev:

cmake_minimum_required(VERSION 3.15)
project foo

set_property(GLOBAL PROPERTY JOB_POOLS pool_A=2)
# For historical reasons, I leave this here, although @Tsyvarev
# points out that this is the source of my problem!
# Don't use a STRING!  No double-quotes!
set(USE_POOL "JOB_POOL pool_A")

add_custom_command(
  OUTPUT  foo.out
  DEPENDS foo.in
  ${USE_POOL}
  COMMAND
    ${CMAKE_COMMAND} -E copy foo.in foo.out
  COMMENT "Converting foo.in -> foo.out"
  VERBATIM
  )
add_custom_target(foo-out
  DEPENDS foo.out
  )
% cmake -GNinja .
% ninja foo-out
ninja: error: 'JOB_POOL pool_A', needed by 'foo.out', missing and no known rule to make it

It considers the string to be a dependency... If I move the USE_POOL to after the comment, it considers it part of the comment... If I move it to after the command, it considers it part of the command...

einpoklum
  • 118,144
  • 57
  • 340
  • 684
Lance E.T. Compte
  • 932
  • 1
  • 11
  • 33

1 Answers1

2

Your JOB_POOL option serves for the user's choice. You may create another variable which contains sequence of related parameters for add_custom_command:

if(JOB_POOL)
  set(JOB_POOL_PARAMS JOB_POOL pool_A) # Will add 'JOB_POOL pool_A' sequence of params
else()
  set(JOB_POOL_PARAMS) # Will add nothing
endif()

Then use new variable directly in add_custom_command call:

add_custom_command(
  ...
  ${JOB_POOL_PARAMS} # Will expand to additional parameters when needed
)
Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
  • Sorry @Tsyvarev. When I try this approach (as I tried to indicate above that I had), the contents of the ${JOB_POOL_PARAMS} variable are MERGED with the line above. If it's a COMMAND, then it's garbage appended to the command. If it's a DEPENDS, then it's a garbage that nothing knows how to build. If it's COMMENT, then I get garbage added to my comment text. My point is that this approach seems reasonable *IF* I know what to put just before it. What must be in place of "..." in your code box above? – Lance E.T. Compte Sep 12 '19 at 22:01
  • "What must be in place of "..." in your code box above?" - The same as in the code in your question. Please, show the **exact** command you use. It is difficult to say what is wrong with it without viewing it. Also make sure that you run CMake exactly of 3.15 version (and have corresponded `cmake_minimum_required`). – Tsyvarev Sep 12 '19 at 22:18
  • 1
    You set the variable to `"JOB_POOL pool_A"`, but look into my code: there is **no double quotes** in it, neither in setting the variable nor in using it. – Tsyvarev Sep 17 '19 at 19:19
  • Thanks! That's it! I'm best bash scripting, so I'm always getting burned by things like ';' appearing, lists vs. strings, and that I think of as strings in "cmake" but aren't. – Lance E.T. Compte Sep 19 '19 at 16:53