diff --git a/CMakeLists.txt b/CMakeLists.txt index da8c163c..2ca2bba2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,64 +24,17 @@ project(ports-of-call VERSION ${PORTS_OF_CALL_VERSION}) # CMAKE WARMUP # ---------------------------------------- -# update the module path -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") - -# some global properties -# TODO: may be more appropriate down the road to attach the standard -# directly to the target usage requirements -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_EXPORT_COMPILE_COMMANDS On) - -# bring in some helpful CMake scripts -# make cache variables for install destinations -include(GNUInstallDirs) -# package config file -include(CMakePackageConfigHelpers) - # Don't allow in-source builds -file(TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/CMakeLists.txt" LOC_PATH) -if(EXISTS "${LOC_PATH}") +if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) message(FATAL_ERROR "You cannot build in a source directory (or any directory with a CMakeLists.txt file). " "Please make a build subdirectory. Feel free to remove CMakeCache.txt and CMakeFiles.") endif() -# If the user doesn't specify a build type, prefer RelWithDebInfo -set(default_build_type "RelWithDebInfo") -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - message(STATUS "Setting build type to '${default_build_type}' as none was specified.") - set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE - STRING "Choose the type of build." FORCE) - # Set the possible values of build type for cmake-gui - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS - "Debug" "Release" "MinSizeRel" "RelWithDebInfo") -endif() # CONFIGURATION LOGIC # ---------------------------------------- -# TODO: I ended up not liking this -# set the portability strategy. we only allow 3 options: None, Kokkos, Cuda -set(PORTABILITY_STRATEGY_OPTIONS "None;Kokkos;Cuda" CACHE STRING "" FORCE) -set_property(CACHE PORTABILITY_STRATEGY_OPTIONS - PROPERTY STRINGS ${PORTABILITY_STRATEGY_OPTIONS}) -if(NOT PORTABILITY_STRATEGY) - list(GET PORTABILITY_STRATEGY_OPTIONS 0 PORTABILITY_STRATEGY) -endif() -# if the cache variable is not valid, display a warning and default to none -if (NOT PORTABILITY_STRATEGY IN_LIST PORTABILITY_STRATEGY_OPTIONS) - message(WARNING "The portability strategy [\"${PORTABILITY_STRATEGY}\"] is - not valid, defaulting to \"None\", valid options are - ${PORTABILITY_STRATEGY_OPTIONS}") - list(GET PORTABILITY_STRATEGY_OPTIONS 0 PORTABILITY_STRATEGY) -endif() -# string-manip for the define -string(TOUPPER ${PORTABILITY_STRATEGY} PORTABILITY_STRATEGY) -set(PORTABILITY_STRATEGY "PORTABILITY_STRATEGY_${PORTABILITY_STRATEGY}" - CACHE STRING "" FORCE) -message(STATUS "Will define ${PORTABILITY_STRATEGY}") - # TARGET CONFIGURATION # ---------------------------------------- @@ -94,23 +47,29 @@ add_library(${POCLIB} INTERFACE) # Make an alias (useful for in-tree builds) add_library(${POCLIB}::${POCLIB} ALIAS ${POCLIB}) -target_compile_definitions(${POCLIB} -INTERFACE - ${PORTABILITY_STRATEGY} -) +# make cache variables for install destinations +include(GNUInstallDirs) # Enables # #include target_include_directories(${POCLIB} INTERFACE - $ - $ + $ + $ ) +target_compile_features(${POCLIB} + INTERFACE + cxx_std_14 +) # INSTALL & EXPORT # ---------------------------------------- +# package config file +include(CMakePackageConfigHelpers) + + # Coordinate external CMake interface (EXPORT) with targets install(TARGETS ${POCLIB} EXPORT ${POCLIB}Targets @@ -120,42 +79,46 @@ install(TARGETS ${POCLIB} INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) -configure_package_config_file(${POCLIB}Config.cmake.in +configure_package_config_file( + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${POCLIB}Config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${POCLIB}Config.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${POCLIB} + NO_SET_AND_CHECK_MACRO # poc does not provide legacy style define ) # ...and the version file write_basic_package_version_file( ${CMAKE_CURRENT_BINARY_DIR}/${POCLIB}ConfigVersion.cmake VERSION ${PORTS_OF_CALL_VERSION} - COMPATIBILITY SameMajorVersion ) + COMPATIBILITY SameMajorVersion +) # Install the cmake configuration files install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${POCLIB}Config.cmake ${CMAKE_CURRENT_BINARY_DIR}/${POCLIB}ConfigVersion.cmake - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${POCLIB} ) + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${POCLIB} +) # Install the source header files -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/ports-of-call/portability.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/ports-of-call/portable_arrays.hpp" +install( + FILES "${CMAKE_CURRENT_SOURCE_DIR}/ports-of-call/portability.hpp" + "${CMAKE_CURRENT_SOURCE_DIR}/ports-of-call/portable_arrays.hpp" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${POCLIB} - ) +) # Install the export target. This will define the CMake target # for external projects when used with `find_package` -install(EXPORT ${POCLIB}Targets +install( + EXPORT ${POCLIB}Targets NAMESPACE ${POCLIB}:: - FILE "${POCLIB}Targets.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${POCLIB}" - COMPONENT dev) + FILE ${POCLIB}Targets.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${POCLIB} +) -# Export configuration for external projects that reference -# just our build-tree; e.g. for submodules. To use, ensure -# `CMAKE_PREFIX_PATH` points to this source directory. # NOTE: This config will not be relocatable! -export(TARGETS ${POCLIB} NAMESPACE ${POCLIB}:: +export( + TARGETS ${POCLIB} + NAMESPACE ${POCLIB}:: FILE "${CMAKE_CURRENT_BINARY_DIR}/${POCLIB}Targets.cmake") -export(PACKAGE ${POCLIB}) diff --git a/README.md b/README.md index 4ff7d46c..7fab4ade 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,46 @@ Provides an implementation of a multidimensional array with round parentheses access. Could be a Kokkos view or something that is not portable +## Using `ports-of-call` in your project + +There are several options for integrating `ports-of-call` into your project. +Being header-only, you may simply copy the `ports-of-call` directory into your project space. + +However, we encourage that you use `ports-of-call` as an installed package, and utilize CMake +to import `ports-of-call`. + +```cmake +find_package(ports-of-call) +``` + +This will provide your CMake build with the target `ports-of-call::ports-of-call`, which +can be used for your executable/library targets + +```cmake +target_link_libraries(myApp ports-of-call::ports-of-call) +``` + +That is the minimum necessary to begin to use `ports-of-call`. However, the project +should also specify the desired `PORTABILITY_STRATEGY_` compiler define: + +```cmake +target_compile_definitions(myApp PORTABILITY_STRATEGY_KOKKOS) +``` + +This may also be done ad-hoc at the configure stage as + +```bash +$> cmake /path/to/project/CMakeLists -DPORTABILITY_STRATEGY_KOKKOS +``` + +Note that, if not specified, `PORTABILITY_STRATEGY_NONE` will be used. + +### Important! + +For maintaining flexibility and ease-of-use, `ports-of-call` does not enforce +dependency requirements. It is therefore the job of the project using +`ports-of-call` to ensure that the necessary packages are available. + ## Contributors `ports-of-call` was primarily developed by Chad Meyer, in collaboration with @@ -44,7 +84,7 @@ portable DevOps support was provided by - Karen Tsai -- Chris Mauney +- Christopher Mauney ## Copyright diff --git a/ports-of-callConfig.cmake.in b/cmake/ports-of-callConfig.cmake.in similarity index 100% rename from ports-of-callConfig.cmake.in rename to cmake/ports-of-callConfig.cmake.in diff --git a/doc/sphinx/src/building.rst b/doc/sphinx/src/building.rst index 46675685..5e2aef64 100644 --- a/doc/sphinx/src/building.rst +++ b/doc/sphinx/src/building.rst @@ -26,40 +26,29 @@ Including in-tree If you want to include Ports of Call in a project in-tree, you can easily just include the two header files. Alternatively, our ``cmake`` build system supports in-tree builds. Simply add the repository as a -subdirectory in your project. We ``ports-of-call::ports-of-call`` target, -which sets the appropriate include paths. - -For in-tree builds, you can set the configure time option -``PORTABILITY_STRATEGY`` to ``Kokkos``, ``Cuda`` or ``None`` to set -the equivalent preprocessor macro. The default is ``None``. - -By default ``cmake`` keeps a registry of packages with install logic -that it has built in a user's home directory. Because -``ports-of-call`` fixes portability strategy at ``cmake`` configure -time, this can conflict with in-tree builds. A parent code that -includes ``ports-of-call`` may find the wrong build by default, rather -than the version that it includes explicitly in the source tree. To -resolve this, we recommend disabling ``cmake``'s package registry -machinery via: +subdirectory in your project. `ports-of-call` defines the CMake target +``ports-of-call::ports-of-call``, which sets the appropriate include paths. -.. code-block:: cmake - - set(CMAKE_FIND_USE_PACKAGE_REGISTRY OFF CACHE BOOL "" FORCE) - set(CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY OFF CACHE BOOL "" FORCE) - -If, on the other hand, you install the dependencies of your code -one-by-one, you should not disable the package registry. If you -encounter an issue where your configuration settings for -``ports-of-call`` don't seem to stick when building a code, you might -attempt disabling the package registry at configure time via +For in-tree builds, you can define exactly one of the preprocessor macros +``PORTABILITY_STRATEGY_KOKKOS``, ``PORTABILITY_STRATEGY_CUDA`` or ``PORTABILITY_STRATEGY_NONE``. +If none are set, the default is ``PORTABILITY_STRATEGY_NONE``. -.. code-block:: cmake +Note that it is the users repsonsibility to ensure that the appropriate +portability strategy is set. Furthermore, `ports-of-call` does not engage in +any dependency resolution, so the user is further required to ensure that +the appropriate dependencies are available when building. - -DCMAKE_FIND_USE_PACKAGE_REGISTRY=OFF -DCMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY=OFF +CMake +^^^^^^ -For more details, see the documentation on the `cmake package registry`_. +The prefered apporach for integratting into your project is is to use +the CMake `find_package` pattern. If `ports-of-call` has been installed and +is visible to the environment -.. _cmake package registry: https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#package-registry +.. code-block:: cmake + find_package(ports-of-call) + target_link_libraries(myProj ports-of-call::ports-of-call) + target_compile_definitions(myProj PORTABILITY_STRATEGY_KOKKOS) Spack ^^^^^^ diff --git a/installtest/CMakeLists.txt b/installtest/CMakeLists.txt index 9abe23ca..bd2de5ff 100644 --- a/installtest/CMakeLists.txt +++ b/installtest/CMakeLists.txt @@ -14,14 +14,10 @@ cmake_minimum_required(VERSION 3.14) -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_EXPORT_COMPILE_COMMANDS On) - project(ports-of-call-cmake-test) # Don't allow in-source builds -file(TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/CMakeLists.txt" LOC_PATH) -if(EXISTS "${LOC_PATH}") +if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) message(FATAL_ERROR "You cannot build in a source directory (or any directory with a CMakeLists.txt file). " "Please make a build subdirectory. Feel free to remove CMakeCache.txt and CMakeFiles.") diff --git a/spack-repo/packages/ports-of-call/package.py b/spack-repo/packages/ports-of-call/package.py index ef64e140..a6985ba8 100644 --- a/spack-repo/packages/ports-of-call/package.py +++ b/spack-repo/packages/ports-of-call/package.py @@ -20,9 +20,6 @@ class PortsOfCall(CMakePackage): version('1.1.0', sha256='c47f7e24c82176b69229a2bcb23a6adcf274dc90ec77a452a36ccae0b12e6e39') variant("doc", default=False, description="Sphinx Documentation Support") - variant("portability_strategy", description="Portability strategy backend", - values=("Kokkos", "Cuda", "None"), multi=False, default="None") - depends_on("cmake@3.12:") depends_on("py-sphinx", when="+doc") @@ -31,6 +28,5 @@ class PortsOfCall(CMakePackage): def cmake_args(self): args = [ - self.define_from_variant("PORTABILITY_STRATEGY", "portability_strategy") ] return args