How to install a "generated" directory?

I have been trying to get better at CMake (currently reading Professional CMake which is very good IMO) and I am trying to do the right thing in my build:

I have this program (which I am calling black-box because I don’t have control over it since it is provided part of some sdk) that needs to run during my build. This program takes an input and output directories as parameters. During the install phase, the output directory needs to be copied to some destination.

The program creates a bunch of files in output directory, one of them being gui.lua.

So I have the current setup:

  set(INPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/IN)
  set(OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/OUT)
  # it is possible that sources are not in the same folder so copying them in a single folder
  file(COPY ${SOURCES} DESTINATION ${INPUT_DIR})

  set(GUI_LUA_FILE ${OUTPUT_DIR}/gui.lua)

  add_custom_command(
      OUTPUT ${GUI_LUA_FILE}
      COMMAND black-box ${INPUT_DIR} ${OUTPUT_DIR}
      DEPENDS ${SOURCES}
  )

  add_custom_target(gen_dir DEPENDS ${GUI_LUA_FILE})

so now the issue is that I am not too sure how to express “copy output directory during the install phase” because OUTPUT_DIR is generated only if the target gen_dir is run. I also want the black-box command to run only when necessary (as it is a potentially a heavy command so it should not run unless any SOURCES changes).

I tried

  install(
      TARGETS gen_dir
      DESTINATION ${INSTALL_DIR}
  )

but this doesn’t work (not an executable, library, or module).

What would be the cmake way of doing this?

Thanks for the help
Yan

You have command install(DIRECTORY ...).

Yes I have tried to use this command.

But in this case it is a directory that does not exist unless it gets generated. As far as I can tell there is no way to say: install(DIRECTORY ... DEPENDS gen_dir). So if you run cmake --build . --target install then the directory will not be generated

The problem comes from the fact that you target gen_dir does not depend on target all so it is not built when you launch target all. Keyword ALL is required.

You must have:

add_custom_target(gen_dir ALL DEPENDS ${GUI_LUA_FILE})

install (DIRECTORY ${OUTPUT_DIR} DESTINATION ${INSTALL_DIR})

I just tried this change and yes that fixed the issue. Running an install from scratch will also run the gen_dir target. Thanks for the help.