Skip to content

Commit da0697a

Browse files
ports build integration and spiner install cleanup (#22)
* cmake looks for ports-of-call with find_package first * update ports of call to main * add ports-of-call to spack repo * update spiner spackage to depend on ports-of-call spackage * some tweaks * change to only one target, spiner::spiner, and export it * add integration test testing install * update docs * final update docs * fix naming bug in ports of call package * pass hdf5 through spack and also update cmake arguments appropriately * address comments Co-authored-by: Jonah Maxwell Miller <jonahm@lanl.gov>
1 parent eec0c65 commit da0697a

File tree

12 files changed

+244
-50
lines changed

12 files changed

+244
-50
lines changed

.github/workflows/install.yml

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Install
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
tests:
11+
name: Test installation
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v2
17+
with:
18+
submodules: recursive
19+
- name: Set system to non-interactive mode
20+
run: export DEBIAN_FRONTEND=noninteractive
21+
- name: install dependencies
22+
run: |
23+
sudo apt-get install -y --force-yes -qq build-essential
24+
- name: build and install
25+
run: |
26+
echo "Build"
27+
mkdir -p ${HOME}/install
28+
cmake -DCMAKE_INSTALL_PREFIX=${HOME}/install -B build .
29+
cmake --build build
30+
cmake --install build
31+
echo "Now try find package from a separate directory"
32+
rm -rf build
33+
cmake -DCMAKE_PREFIX_PATH=${HOME}/install -B build installtest
34+
echo "Now try and build with includes..."
35+
cmake --build build
36+
echo "Done"

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
build
12
bin
23
CMakeFiles
34
CMakeCache.txt

CMakeLists.txt

+80-34
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
cmake_minimum_required(VERSION 3.14)
1616
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
1717

18-
option (SPINER_USE_HDF "Pull in hdf5" OFF)
18+
option (SPINER_USE_HDF
19+
"Pull in hdf5" OFF)
1920
option (SPINER_USE_KOKKOS "Pull in Kokkos" OFF)
2021
option (SPINER_USE_CUDA "Use the Kokkos cuda backend" OFF)
22+
option (SPINER_FORCE_INTERNAL_PORTS "Force use of internal ports of call" OFF)
2123

2224
if (SPINER_USE_CUDA AND NOT SPINER_USE_KOKKOS)
2325
message(FATAL_ERROR "Currently cuda requires Kokkos")
@@ -26,7 +28,14 @@ endif()
2628
set(CMAKE_CXX_STANDARD 11)
2729
set(CMAKE_EXPORT_COMPILE_COMMANDS On)
2830

29-
project(spiner VERSION 1.4.0)
31+
set(SPINER_VERSION 1.4.0)
32+
project(spiner VERSION ${SPINER_VERSION})
33+
34+
# bring in some helpful CMake scripts
35+
# make cache variables for install destinations
36+
include(GNUInstallDirs)
37+
# package config file
38+
include(CMakePackageConfigHelpers)
3039

3140
# Don't allow in-source builds
3241
file(TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/CMakeLists.txt" LOC_PATH)
@@ -54,16 +63,9 @@ include(CTest)
5463
include(cmake/Format.cmake)
5564

5665
# Add a library
57-
# mostly includes
58-
add_library(spiner::flags INTERFACE IMPORTED GLOBAL)
59-
# mostly just contains automated linker connections
60-
add_library(spiner::libs INTERFACE IMPORTED)
61-
62-
# xl fix
63-
target_compile_options(spiner::flags INTERFACE
64-
$<$<COMPILE_LANG_AND_ID:CXX,XL>:-std=c++1y;-qxflag=disable__cplusplusOverride>)
65-
target_link_options(spiner::flags INTERFACE
66-
$<$<COMPILE_LANG_AND_ID:CXX,XL>:-std=c++1y;-qxflag=disable__cplusplusOverride>)
66+
set(SPLIB "spiner")
67+
add_library(${SPLIB} INTERFACE)
68+
add_library(${SPLIB}::${SPLIB} ALIAS ${SPLIB})
6769

6870
# HDF5
6971
if(SPINER_USE_HDF)
@@ -72,22 +74,16 @@ if(SPINER_USE_HDF)
7274
endif()
7375
find_package(HDF5 COMPONENTS C HL)
7476
if (HDF5_FOUND)
75-
add_library(spiner::hdf5 INTERFACE IMPORTED GLOBAL)
76-
target_compile_definitions(spiner::flags
77-
INTERFACE
78-
SPINER_USE_HDF)
79-
set_target_properties(spiner::hdf5 PROPERTIES
80-
INTERFACE_LINK_LIBRARIES "${HDF5_LIBRARIES};${HDF5_HL_LIBRARIES}"
81-
INTERFACE_COMPILE_DEFINITIONS "SPINER_USE_HDF"
82-
INTERFACE_INCLUDE_DIRECTORIES "${HDF5_INCLUDE_DIRS}")
77+
target_compile_definitions(${SPLIB} INTERFACE SPINER_USE_HDF)
78+
target_link_libraries(${SPLIB} INTERFACE ${HDF5_LIBRARIES} ${HDF5_HL_LIBRARIES})
79+
target_include_directories(${SPLIB} INTERFACE ${HDF5_INCLUDE_DIRS})
8380
else()
8481
message(FATAL_ERROR "HDF5 was requested but not found. Can be disabled with -SPINER_USE_HDF=OFF")
8582
endif()
86-
target_link_libraries(spiner::libs INTERFACE spiner::hdf5)
8783
endif()
8884

8985
if (SPINER_USE_KOKKOS)
90-
target_compile_definitions(spiner::flags INTERFACE
86+
target_compile_definitions(${SPLIB} INTERFACE
9187
PORTABILITY_STRATEGY_KOKKOS)
9288
# Import Kokkos if not already available as a build target
9389
if (NOT TARGET Kokkos::kokkos)
@@ -102,38 +98,88 @@ if (SPINER_USE_KOKKOS)
10298
endif()
10399
if(SPINER_USE_CUDA)
104100
target_compile_options(
105-
spiner::flags
101+
${SPLIB}
106102
INTERFACE # Generator expression shamelessly copied from EAP
107103
"$<$<COMPILE_LANGUAGE:CXX>:--expt-relaxed-constexpr;>"
108104
)
109105
endif()
110-
target_link_libraries(spiner::libs INTERFACE Kokkos::kokkos)
106+
target_link_libraries(${SPLIB} INTERFACE Kokkos::kokkos)
111107
endif ()
112108

113109
# ports of call
114110
# TODO: Integrate with find-package
115111
if (NOT TARGET ports-of-call::ports-of-call)
116-
add_subdirectory(ports-of-call)
112+
message(STATUS "Looking for ports-of-call")
113+
if (SPINER_FORCE_INTERNAL_PORTS)
114+
message(STATUS "Using in-system ports-of-call")
115+
add_subdirectory(ports-of-call)
116+
else()
117+
find_package(ports-of-call CONFIG)
118+
if (NOT ports-of-call_FOUND)
119+
message(STATUS "Ports of call not available in-system. Using submodule.")
120+
add_subdirectory(ports-of-call)
121+
else()
122+
message(STATUS "Ports of call is available. Using in-system installation.")
123+
endif()
124+
endif()
125+
else()
126+
message(STATUS "Ports of call already in environment")
117127
endif()
118-
target_link_libraries(spiner::flags INTERFACE ports-of-call::ports-of-call)
119-
120-
# parent library
121-
# so the user can just import `spiner::spiner` rather than flags or libs.
122-
add_library(spiner::spiner INTERFACE IMPORTED GLOBAL)
123-
target_link_libraries(spiner::spiner INTERFACE spiner::flags spiner::libs)
128+
target_link_libraries(${SPLIB} INTERFACE ports-of-call::ports-of-call)
124129

125130
# Enables
126131
# #include <spiner>
127-
target_include_directories(spiner::flags
132+
target_include_directories(${SPLIB}
128133
INTERFACE
129134
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>)
130135

131-
# Enables includes
136+
# Coordinate external CMAKE export with targets
137+
install(TARGETS ${SPLIB}
138+
EXPORT ${SPLIB}Targets
139+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
140+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
141+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
142+
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
143+
)
144+
145+
configure_package_config_file(${SPLIB}Config.cmake.in
146+
${CMAKE_CURRENT_BINARY_DIR}/${SPLIB}Config.cmake
147+
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${SPLIB}
148+
)
149+
150+
# ...and the version file
151+
write_basic_package_version_file(
152+
${CMAKE_CURRENT_BINARY_DIR}/${SPLIB}ConfigVersion.cmake
153+
VERSION ${SPINER_VERSION}
154+
COMPATIBILITY SameMajorVersion )
155+
156+
# Install the cmake configuration files
157+
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SPLIB}Config.cmake
158+
${CMAKE_CURRENT_BINARY_DIR}/${SPLIB}ConfigVersion.cmake
159+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${SPLIB} )
160+
161+
# Install header files
132162
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/spiner"
133-
DESTINATION "include"
163+
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
134164
FILES_MATCHING PATTERN "*.hpp"
135165
)
136166

167+
# Install the export target. This will define the CMake target
168+
# for external projects when used with `find_package`
169+
install(EXPORT ${SPLIB}Targets
170+
NAMESPACE ${SPLIB}::
171+
FILE "${SPLIB}Targets.cmake"
172+
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${SPLIB}"
173+
COMPONENT dev)
174+
175+
# Export configuration for external projects that reference
176+
# just our build-tree; e.g. for submodules. To use, ensure
177+
# `CMAKE_PREFIX_PATH` points to this source directory.
178+
# NOTE: This config will not be relocatable!
179+
export(TARGETS ${SPLIB} NAMESPACE ${SPLIB}::
180+
FILE "${CMAKE_CURRENT_BINARY_DIR}/${SPLIB}Targets.cmake")
181+
export(PACKAGE ${SPLIB})
182+
137183
# Option imported from `CTest`
138184
if (BUILD_TESTING)
139185
message("\nConfiguring tests")

README.md

+1-10
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,7 @@ after configuring and building.
5151

5252
You can build `spiner` in-line with your project, or pre-install
5353
it. It's header-only and the include directories should have the
54-
expected structure. If you build inline, add the following targets to your `cmake`:
55-
```cmake
56-
target_link_libraries(my_project PRIVATE spiner::flags spiner::libs)
57-
```
58-
`spiner::flags` contains compile and include flags, to be included at
59-
compile lines. `spiner::libs` contains linker flags. Since `spiner` is
60-
header-only, `spiner::libs` only contains link flags for dependencies,
61-
such as `HDF5` or `Kokkos`.
62-
63-
For access to both, use
54+
expected structure. If you build inline, add the following target to your `cmake`:
6455
```cmake
6556
target_link_libraries(my_project PRIVATE spiner::spiner)
6657
```

doc/sphinx/src/building.rst

+7-4
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,14 @@ Spiner supports a few ``cmake`` configuration options:
3232
* ``SPINER_USE_CUDA`` enables the Kokkos cuda backend
3333
* ``CMAKE_INSTALL_PREFIX`` sets the install location
3434
* ``CMAKE_BUILD_TYPE`` sets the build type
35+
* ``SPINER_FORCE_INTERNAL_PORTS`` forces use of a `ports-of-call`_ submodule rather than a system install
3536

3637
.. _`hdf5`: https://www.hdfgroup.org/solutions/hdf5
3738

3839
.. _`Kokkos`: https://github.com/kokkos/kokkos
3940

41+
.. _`ports-of-call`: https://lanl.github.io/ports-of-call/main/index.html
42+
4043
HDF5 is searched for and configured via the usual `cmake`_ machinery.
4144

4245
.. _`cmake`: https://cmake.org/
@@ -72,6 +75,8 @@ The spack repo supports a few variants:
7275

7376
* ``+kokkos`` enables the Kokkos backend
7477
* ``+cuda`` enables the cuda backend. A ``cuda_arch`` must be specified.
78+
* ``+hdf5`` enables HDF5 file support.
79+
* ``+mpi`` enables parallel hdf5 support
7580
* ``+python`` installs python, numpy, and matplotlib support
7681
* ``+doc`` adds tooling for building the docs
7782
* ``+format`` adds support for clang-format
@@ -80,7 +85,5 @@ Including Spiner in your Project
8085
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8186

8287
Spiner can be included into a cmake project, either in-tree as a
83-
submodule or after installation. The cmake system provides
84-
``spiner::flags`` and ``spiner::libs`` cmake targets. The former adds
85-
appropriate compilation flags, the latter adds link flags for
86-
dependencies such as hdf5.
88+
submodule or after installation via ``find_package``.
89+
The cmake system provides the ``spiner::spiner`` cmake target.

installtest/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
build

installtest/CMakeLists.txt

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#------------------------------------------------------------------------------#
2+
# © 2021-2022. Triad National Security, LLC. All rights reserved. This
3+
# program was produced under U.S. Government contract 89233218CNA000001
4+
# for Los Alamos National Laboratory (LANL), which is operated by Triad
5+
# National Security, LLC for the U.S. Department of Energy/National
6+
# Nuclear Security Administration. All rights in the program are
7+
# reserved by Triad National Security, LLC, and the U.S. Department of
8+
# Energy/National Nuclear Security Administration. The Government is
9+
# granted for itself and others acting on its behalf a nonexclusive,
10+
# paid-up, irrevocable worldwide license in this material to reproduce,
11+
# prepare derivative works, distribute copies to the public, perform
12+
# publicly and display publicly, and to permit others to do so.
13+
#------------------------------------------------------------------------------#
14+
15+
cmake_minimum_required(VERSION 3.14)
16+
17+
set(CMAKE_CXX_STANDARD 11)
18+
set(CMAKE_EXPORT_COMPILE_COMMANDS On)
19+
20+
project(spiner-cmake-test)
21+
22+
# Don't allow in-source builds
23+
file(TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/CMakeLists.txt" LOC_PATH)
24+
if(EXISTS "${LOC_PATH}")
25+
message(FATAL_ERROR
26+
"You cannot build in a source directory (or any directory with a CMakeLists.txt file). "
27+
"Please make a build subdirectory. Feel free to remove CMakeCache.txt and CMakeFiles.")
28+
endif()
29+
30+
find_package(spiner CONFIG REQUIRED)
31+
if (NOT spiner_FOUND)
32+
message(FATAL_ERROR "Spiner not found.")
33+
endif()
34+
35+
if (TARGET spiner::spiner)
36+
message(STATUS "The spiner library was succesfully provided")
37+
get_target_property(_sp_incdir spiner::spiner INTERFACE_INCLUDE_DIRECTORIES)
38+
message(STATUS "ports of call include directory: ${_sp_incdir}")
39+
else()
40+
message(FATAL_ERROR "The spiner library is missing!")
41+
endif()
42+
43+
add_library(mytest libtest.cpp)
44+
target_link_libraries(mytest
45+
PRIVATE
46+
spiner::spiner
47+
)

installtest/libtest.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// checks if compiler can find the poc header files
2+
#include <spiner/databox.hpp>
3+
4+
int main(){
5+
// TODO: add some library checks
6+
return 0;
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Spackage for Ports of Call
2+
3+
from spack import *
4+
5+
class PortsOfCall(CMakePackage, CudaPackage):
6+
"""ports-of-call"""
7+
8+
homepage = "https://github.com/lanl/ports-of-call"
9+
url = "https://github.com/lanl/ports-of-call/archive/refs/heads/main.zip"
10+
git = "git@github.com:lanl/ports-of-call.git"
11+
12+
version("main", branch="main")
13+
variant("doc", default=False, description="Sphinx Documentation Support")
14+
variant("portability_strategy", description="Portability strategy backend",
15+
values=("Kokkos","Cuda","None"),multi=False,default="Kokkos",
16+
when="^kokkos")
17+
variant("portability_strategy", description="Portability strategy backend",
18+
values=("Kokkos","Cuda","None"),multi=False,default="None")
19+
20+
depends_on("cmake@3.12:")
21+
22+
depends_on("py-sphinx", when="+doc")
23+
depends_on("py-sphinx-rtd-theme@0.4.3", when="+doc")
24+
depends_on("py-sphinx-multiversion", when="+doc")
25+
26+
def cmake_args(self):
27+
args = [
28+
self.define_from_variant("PORTABILITY_STRATEGY", "portability_strategy")
29+
]
30+
return args

0 commit comments

Comments
 (0)