tcbrindle / span

Implementation of C++20's std::span for older compilers
Boost Software License 1.0
328 stars 35 forks source link

Allow usage as submodule #29

Open Flamefire opened 4 years ago

Flamefire commented 4 years ago

Would be great if this was usable as a git-submodule or via CMakes ExternalProject or FetchContent.

This requires

For the latter I'd suggest to remove the enable_testing and use:

if(PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
  include(CTest)
endif()
if(BUILD_TESTING)
  add_subdirectory(test)
endif()

This include adds an option BUILD_TESTING with default ON and enable_testing call if the current project is not the super project (aka cmake was called for another folder and this folder was added via add_subdirectory)

PS: CMAKE_CURRENT_SOURCE_DIR as used is not required and can be omitted.

tcbrindle commented 4 years ago

This sounds like a good idea. I'm not a CMake expert though -- I know how to make an "interface library", but how do I do the namespacing bit?

Flamefire commented 4 years ago

You use an ALIAS library: add_library(tcb::span ALIAS tcb_span) where `tcb_span is your regular INTERFACE library. And while you are at it: You can also add installation support:

include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
  target_include_directories(tcb_span INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)

  install(TARGETS tcb_span
    EXPORT ${PROJECT_NAME}Targets
  )
  install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
  set(configFile ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake)
  set(versionFile ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake)
  set(configInstallDestination lib/cmake/${configFolder})

  configure_package_config_file(
    ${PROJECT_SOURCE_DIR}/Config.cmake.in
    ${configFile} 
    INSTALL_DESTINATION ${configInstallDestination}
  )
  write_basic_package_version_file(
    ${versionFile}
    COMPATIBILITY SameMajorVersion
  )

  install(FILES ${configFile} ${versionFile} DESTINATION ${configInstallDestination})

  install(
    EXPORT ${PROJECT_NAME}Targets
    NAMESPACE "tcb::"
    DESTINATION ${configInstallDestination}
  )

This is mostly C&P from another project so double-check. You'll need to use a suitable project name (with the above users will be able to do find_package(<project-name>)) and use the VERSION x.y.z argument for project. The referenced Config.cmake.in is simple:

@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")

And yes it is a shame that so much boilerplate is required in CMake...

If you got any questions, feel free to ask. I can also review a PR