install with EXPORT and multiple CONFIGURATIONS

I want to make a multi configuration package using cpack -C and the Visual Studio multi-generator. So, knowing that each of RUNTIME, LIBRARY, and ARCHIVE can appear only once in a call to install(), I tried writing the code below, which involves two nearly identical calls to install(). However, I get the following error:

CMake Error: install(EXPORT "Halide_Targets" ...) includes target "Halide" more than once in the export set.

If I remove the second “EXPORT” line, then the targets aren’t populated for the release builds! What am I supposed to do here?

Install code
install(TARGETS Halide Halide_Plugin Halide_Runtime ${EXTRA_TARGETS}
        EXPORT Halide_Targets
  
        RUNTIME
        DESTINATION ${CMAKE_INSTALL_BINDIR}/Debug
        COMPONENT Halide_Runtime
        CONFIGURATIONS Debug
  
        LIBRARY
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/Debug
        COMPONENT Halide_Runtime
        NAMELINK_COMPONENT Halide_Development
        CONFIGURATIONS Debug
  
        ARCHIVE
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/Debug
        COMPONENT Halide_Development
        CONFIGURATIONS Debug
  
        INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

install(TARGETS Halide Halide_Plugin Halide_Runtime ${EXTRA_TARGETS}
        EXPORT Halide_Targets
  
        RUNTIME
        DESTINATION ${CMAKE_INSTALL_BINDIR}/Release
        COMPONENT Halide_Runtime
        CONFIGURATIONS Release RelWithDebInfo MinSizeRel
  
        LIBRARY
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/Release
        COMPONENT Halide_Runtime
        NAMELINK_COMPONENT Halide_Development
        CONFIGURATIONS Release RelWithDebInfo MinSizeRel
  
        ARCHIVE
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/Release
        COMPONENT Halide_Development
        CONFIGURATIONS Release RelWithDebInfo MinSizeRel
  
        INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

install(EXPORT Halide_Targets
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Halide
        NAMESPACE Halide::
        FILE Halide-Targets.cmake
        COMPONENT Halide_Development)
1 Like

Apparently you just specify the EXPORT bit on the last call to install() for those targets.

I don’t know whether that works by fluke or by design.

That doesn’t seem all that intuitive, I agree. It seems reasonable to expect that if you are separating out the install(TARGETS) calls for different configs for the same targets, you should be able to specify the export set for each call (perhaps with the restriction that it always has to be the same export set). @brad.king is this just a restriction of the current implementation, or is there an underlying reason why the original approach used by Alex leads to the reported error?

I think it is just a limitation of the current implementation. It probably isn’t tracking the CONFIGURATIONS of each time the target is associated with the export set.

At some point I discovered that doing this doesn’t work. It results in an empty “Halide-Targets-debug.cmake” file. I was using 3.16 in the OP and am using 3.18 now. Not sure if it never worked or if there was a regression. Regardless, using a generator expression is sufficient for my purposes here and does work.

# Sends Debug -> Debug, Release/MinSizeRel/RelWithDebInfo -> Release
set(CONFIG_DIR $<IF:$<CONFIG:Debug>,Debug,Release>)

install(TARGETS Halide Halide_Plugin Halide_Runtime ${EXTRA_TARGETS}
        EXPORT Halide_Targets

        RUNTIME
        DESTINATION ${CMAKE_INSTALL_BINDIR}/${CONFIG_DIR}
        COMPONENT Halide_Runtime

        LIBRARY
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/${CONFIG_DIR}
        COMPONENT Halide_Runtime
        NAMELINK_COMPONENT Halide_Development

        ARCHIVE
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/${CONFIG_DIR}
        COMPONENT Halide_Development

        INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

# install(EXPORT) as usual...