Skip to content

Commit

Permalink
Merge pull request #16 from lanl/mauneyc/cmake-updates
Browse files Browse the repository at this point in the history
"Config-less" configuration
  • Loading branch information
Yurlungur authored Nov 21, 2022
2 parents 20de024 + 69fbb3d commit deb8c52
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 108 deletions.
101 changes: 32 additions & 69 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
# ----------------------------------------

Expand All @@ -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 <ports-of-call/portability.hpp>
target_include_directories(${POCLIB}
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

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
Expand All @@ -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})


42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -44,7 +84,7 @@ portable

DevOps support was provided by
- Karen Tsai
- Chris Mauney
- Christopher Mauney

## Copyright

Expand Down
File renamed without changes.
47 changes: 18 additions & 29 deletions doc/sphinx/src/building.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
^^^^^^
Expand Down
6 changes: 1 addition & 5 deletions installtest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.")
Expand Down
4 changes: 0 additions & 4 deletions spack-repo/packages/ports-of-call/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -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("[email protected]:")

depends_on("py-sphinx", when="+doc")
Expand All @@ -31,6 +28,5 @@ class PortsOfCall(CMakePackage):

def cmake_args(self):
args = [
self.define_from_variant("PORTABILITY_STRATEGY", "portability_strategy")
]
return args

0 comments on commit deb8c52

Please sign in to comment.