How do I use install() with targets that might not be built?

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

How do I use install() with targets that might not be built?

Jason Heeris
My project consists of a lot of "module" style targets (static libraries, more or less), but only a few top-level targets that a user would actually want to build. The "all" target is empty, that is, every target has "EXCLUDE_FROM_ALL" set. The user will, at compile time, decide to build whichever target they need. A single target may depend on a couple of others, so the end result of a single target being built might be eg. an exe file plus a dll plus a couple of other things.

But I also want to provide installation capabilities, so users don't have to hunt down exes and libs scattered throughout CMake's build tree. I might want to create installers using CPack at some point too.

How do I do this if all of my targets are EXCLUDE_FROM_ALL? According to the documentation, even if I use the OPTIONAL flag in install(), the behaviour is undefined. Better not do that.

The only other option I see is to create custom commands (POST_BUILD style) for every target that copies it to some designated output directory. But then I can't take advantage of CMake's other installation capabilities, and I think that would be invisible to CPack.

Is there some other way?

I'm using CMake 3.12 on Windows 10/Ubuntu 18.04, if that's relevant.

Cheers,
Jason

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: How do I use install() with targets that might not be built?

Francis Giraldeau
To customize the build and install, I would suggest to use an install(TRAGET) wrapper for each target. It allows to define an option for each of them. 

* The list of targets must be recorded in a global property.
* The install option is constructed using the target name
* call generate_install_config() after all targets to get a template that you can customize and use as cmake initial cache

You might be able to adapt this to your needs.

Cheers,

====

set_property(GLOBAL PROPERTY target_list)

# add_install_option must be a macro, if put in a function, the option does
# not exists right after being declared.
macro(add_install_option target)
    string(TOUPPER ${target} TGT)
    option(CONFIG_INSTALL_${TGT} "Install ${TGT}" ON)
    get_property(tmp GLOBAL PROPERTY target_list)
    list(APPEND tmp CONFIG_INSTALL_${TGT})
    set_property(GLOBAL PROPERTY target_list ${tmp})
endmacro()

function(install_target_wrapper target)
  add_install_option(${target})
  if(CONFIG_INSTALL_${TGT})
      # message("CONFIG_INSTALL_${TGT}=${CONFIG_INSTALL_${TGT}}")
      install(TARGETS ${target}
          RUNTIME DESTINATION bin
          LIBRARY DESTINATION lib
          COMPONENT application
      )
  endif()
endfunction()

function(generate_install_config)
    set(CONF "${CMAKE_BINARY_DIR}/InstallConfig.cmake")
    file(WRITE "${CONF}" "# Automatically generated install config file. Copy this file and edit to customize the installation.\n")
    file(APPEND "${CONF}" "# Use to populate the initial cmake cache: cmake -C InstallConfigForCustomer.cmake\n")
    file(APPEND "${CONF}" "# EDIT VARIABLES BELOW\n")
    get_property(tmp GLOBAL PROPERTY target_list)
    list(SORT tmp)
    foreach(ITEM ${tmp})
        file(APPEND ${CONF} "set(${ITEM}_VALUE ${${ITEM}})\n")
    endforeach()
    file(APPEND "${CONF}" "#\n# DO NOT EDIT BELOW\n#\n")
    foreach(ITEM ${tmp})
        file(APPEND ${CONF} "set(${ITEM} \${${ITEM}_VALUE} CACHE BOOL \"Install ${ITEM}\" FORCE)\n")
    endforeach()
    list(LENGTH tmp tmp_len)
    message("-- Number of targets: ${tmp_len}")
endfunction()


Le mer. 25 juil. 2018 à 02:09, Jason Heeris <[hidden email]> a écrit :
My project consists of a lot of "module" style targets (static libraries, more or less), but only a few top-level targets that a user would actually want to build. The "all" target is empty, that is, every target has "EXCLUDE_FROM_ALL" set. The user will, at compile time, decide to build whichever target they need. A single target may depend on a couple of others, so the end result of a single target being built might be eg. an exe file plus a dll plus a couple of other things.

But I also want to provide installation capabilities, so users don't have to hunt down exes and libs scattered throughout CMake's build tree. I might want to create installers using CPack at some point too.

How do I do this if all of my targets are EXCLUDE_FROM_ALL? According to the documentation, even if I use the OPTIONAL flag in install(), the behaviour is undefined. Better not do that.

The only other option I see is to create custom commands (POST_BUILD style) for every target that copies it to some designated output directory. But then I can't take advantage of CMake's other installation capabilities, and I think that would be invisible to CPack.

Is there some other way?

I'm using CMake 3.12 on Windows 10/Ubuntu 18.04, if that's relevant.

Cheers,
Jason
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
--
Francis Giraldeau

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake