how to set variables for install(SCRIPT...)?

is it possible to pass a variable for the cmake script when using install(SCRIPT) mode?

the following is invalid:

install(SCRIPT -DFOO=bar -P foo.cmake)

and this generates without error but doesn’t pass FOO to foo.cmake:

install(SCRIPT foo.cmake -DFOO=bar)

one option would be to use install(CODE ...), instead.

Yeah, you’ll need to inject variable settings into the install step somehow. I have written a set of set() calls to a file then added an inclusion of that file via install(CODE) to work around this before.

1 Like

That’s one way to do it. I would have loved to see something like this working:

# no options here for simplicity
install(CODE [[
	execute_process(
		COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/foo.cmake
	)
]])

but this doesn’t fly because source dir is that source dir not this one.

execute_process(
	COMMAND ${CMAKE_COMMAND} -E echo src dir: ${CMAKE_CURRENT_SOURCE_DIR}
)
install(CODE "message(\"this src dir: ${CMAKE_CURRENT_SOURCE_DIR}\")")
install(CODE [[
	execute_process(
		COMMAND ${CMAKE_COMMAND} -E echo that src dir: ${CMAKE_CURRENT_SOURCE_DIR}
	)
]])

this gives me

src dir: /tmp/test/extern/foo
this src dir: /tmp/test/extern/foo
that src dir: /tmp/test/build/extern/foo-prefix/src/foo-build

why is this? The first 2 commands know about my source dir but the last one does not. It looks like source dir is equal to binary dir in the last command.

I think that the [[ / ]] quoting in the latter prevents expansion until the install time.

this is it, thank you!

Note that you may not want (and/or need) to pass directory paths in to the install script. If you’re doing it because you need to reference, say, the location of a build file, you may be able to reference it via a generator expression like $<TARGET_FILE:output_target>, $<TARGET_OBJECTS:object_target>, or $<TARGET_PROPERTY:imported_target,LOCATION>1 — and another bonus, those can be used inside [[ ]] blocks. Unlike variable references, generator expressions are always expanded.

Notes

  1. With that last one, unless the target was imported in the current scope you might have to resort to passing in a variable:
    get_target_property(DEPENDENCY_PATH imported_target LOCATION)
    install(CODE "set(DEPENDENCY_PATH \"${DEPENDENCY_PATH}\")")
    install(CODE [[
      something_using(${DEPENDENCY_PATH})
    ]])