Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ commands:
cache-tag:
description: "A unique tag to append to the cache name"
type: string
default: "1"
default: "2"
steps:
- run:
name: "Build Pygrackle from Gold-Standard Commit (<< parameters.gold-standard-tag >>)"
Expand Down Expand Up @@ -449,14 +449,14 @@ workflows:
jobs:
- test-suite:
name: "Pygrackle test suite - Python 3.10"
tag: "3.10.3"
tag: "3.10.14"

- corelib-tests:
name: "Core library test suite"

- docs-build:
name: "Docs build"
tag: "3.10.3"
tag: "3.10.14"

weekly:
triggers:
Expand All @@ -469,11 +469,11 @@ workflows:
jobs:
- test-suite:
name: "Pygrackle test suite - Python 3.10"
tag: "3.10.3"
tag: "3.10.14"

- corelib-tests:
name: "Core library test suite"

- docs-build:
name: "Docs build"
tag: "3.10.3"
tag: "3.10.14"
15 changes: 8 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ endif()

# Preamble
# --------
cmake_minimum_required(VERSION 3.16)
# we currently set the minimum required version CMake version to the version
# that can be downloaded with apt for the oldest Ubuntu LTS release that
# still receives General Support
cmake_minimum_required(VERSION 3.22)
cmake_policy(SET CMP0077 NEW)
cmake_policy(SET CMP0082 NEW)

Expand All @@ -35,12 +38,10 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

# determine whether we are building a stand-alone program, or if grackle has
# been embedded within another project
set(GRACKLE_IS_TOP_LEVEL ON)
if (NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(GRACKLE_IS_TOP_LEVEL OFF)
endif()
# -> todo gradually replace GRACKLE_IS_TOP_LEVEL with PROJECT_IS_TOP_LEVEL
set(GRACKLE_IS_TOP_LEVEL ${PROJECT_IS_TOP_LEVEL})

if (GRACKLE_IS_TOP_LEVEL AND ("${CMAKE_EXPORT_COMPILE_COMMANDS}" STREQUAL ""))
if (PROJECT_IS_TOP_LEVEL AND ("${CMAKE_EXPORT_COMPILE_COMMANDS}" STREQUAL ""))
# aside: replacing the string-comparison with a check for whether
# CMAKE_EXPORT_COMPILE_COMMANDS exists doesn't seem work properly
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
Expand All @@ -49,7 +50,7 @@ endif()
# it's really important that the following is called at the directory-level
# BEFORE we declare any targets (and after we make sure GRACKLE_IS_TOP_LEVEL
# and CMAKE_EXPORT_COMPILE_COMMANDS are both defined)
include(PrepareClangTidy)
include(LinterHandling)
convenience_prepare_clang_tidy()


Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Building the Core Grackle Library From Source
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Grackle requires a C99 compiler, a Fortran compiler, and HDF5 (1.6 or newer).
On most platforms, compilation with the CMake build system (3.16 or newer) is as simple as:
On most platforms, compilation with the CMake build system (3.22 or newer) is as simple as:

.. code-block:: shell-session

Expand Down
171 changes: 171 additions & 0 deletions cmake/Backport_FetchContent.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# This module defines the wrappers:
# wrapper-name | drop-in replacement for
# --------------------------------------|-------------------------------------
# GrBackport_FetchContent_Declare | FetchContent_Declare
# GrBackport_FetchContent_MakeAvailable | FetchContent_MakeAvailable
#
# By using the wrappers, you can call GrBackport_FetchContent_Declare with the
# FIND_PACKAGE_ARGS and then GrBackport_FetchContent_MakeAvailable does the
# "right thing"
#
# In more detail:
# - when using a cmake version before 3.24, the GrBackport_FetchContent_Declare
# wrapper intercepts the FIND_PACKAGE_ARGS kwarg, slightly modifies behavior,
# and the GrBackport_FetchContent_MakeAvailable wrapper does the "right thing"
# - compared to the CMake =>3.24 implementation, our versions:
# - don't understand the OVERRIDE_FIND_PACKAGE kwarg
# - are a little more "eager" (i.e. internal find_package calls that we do
# in GrBackport_FetchContent_Declare should technically happen in
# GrBackport_FetchContent_MakeAvailable backported versions.
# - don't support dependency-provider machinery
# - this is all "good enough" for our purposes
# - when using a cmake version >= 3.24, the wrappers just directly forwards all
# arguments onto the canonical implementations of FetchContent_Declare &
# FetchContent_MakeAvailable
#
# Motivation:
# -> this is extremely useful for projects that assume CMake >= 3.24 (CMake 3.24
# made some changes to streamline and unify dependency management in CMake
# and we now do things "properly")
# -> when we eventually bump Grackle's minimum required CMake version to 3.24
# it will be trivial to delete this file

include_guard()

include(FetchContent)

# ASIDE: perfect function arg-forwarding is a little clunky in CMake
# -> the way that variable expansion works produces surprising results if you
# aren't careful. We adopt the technique recommended by one of the CMake
# maintainers (Craig Scott) from his book "Professional CMake"
# -> the author is very clear at the start of the book that readers are free
# to reuse sample code without attribution or licensing
# -> for the argument forward that we are doing, we could **probably** do
# something simpler, but it's better to be safe than sorry

if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)
# the wrappers simply forward args to FetchContent

function(GrBackport_FetchContent_Declare)
cmake_parse_arguments(PARSE_ARGV 0 FWD "" "" "")
set(quotedArgs "")
foreach(arg IN LISTS FWD_UNPARSED_ARGUMENTS)
string(APPEND quotedArgs " [===[${arg}]===]")
endforeach()
cmake_language(EVAL CODE "FetchContent_Declare(${quotedArgs})")
endfunction()

function(GrBackport_FetchContent_MakeAvailable)
cmake_parse_arguments(PARSE_ARGV 0 FWD "" "" "")
set(quotedArgs "")
foreach(arg IN LISTS FWD_UNPARSED_ARGUMENTS)
string(APPEND quotedArgs " [===[${arg}]===]")
endforeach()
cmake_language(EVAL CODE "FetchContent_MakeAvailable(${quotedArgs})")
endfunction()

else()

# we make use of _GRACKLE_Backport_FetchContent_BYPASS_DOWNLOAD to communicate
# names to Backport_FetchContent_MakeAvailable that we have already found via
# a call to find_package from within Backport_FetchContent_Declare
#
# For the uninitiated: a comparison b/t GLOBAL property & a CACHE variable
# - similarity: both make it sense to store information at global scope
# - difference: a CACHE variable is saved between CMake runs
# - difference: the way you get and access data is slightly different
#
# I'm choosing to use a GLOBAL property in this case b/c it's plausible that
# caching this information could cause problems (it probably would be fine, but
# I don't want to take that chance)

function(GrBackport_FetchContent_Declare content_name)

# build up quotedNormalArgs variables (it holds args that we forward)
# -> if we encounter FIND_PACKAGE_ARGS, create and build-up a variable
# called quotedFindPackageArgs with all following args (if any)
# -> otherwise, quotedFindPackageArgs is undefined
cmake_parse_arguments(PARSE_ARGV 1 FWD "" "" "")
set(quotedNormalArgs "[===[${content_name}]===]")
foreach(arg IN LISTS FWD_UNPARSED_ARGUMENTS)
if (DEFINED quotedFindPackageArgs)
string(APPEND quotedFindPackageArgs " [===[${arg}]===]")
elseif("${arg}" STREQUAL "OVERRIDE_FIND_PACKAGE")
message(FATAL_ERROR "Our backport can't handle the `${arg}` keyword")
elseif("${arg}" STREQUAL "FIND_PACKAGE_ARGS")
set(quotedFindPackageArgs "")
else()
string(APPEND quotedNormalArgs " [===[${arg}]===]")
endif()
endforeach()

# store effective val of FETCHCONTENT_TRY_FIND_PACKAGE_MODE in tfpmode
string(TOUPPER "${content_name}" UPPER_CONTENT_NAME)
if (NOT("${FETCHCONTENT_SOURCE_DIR_${UPPER_CONTENT_NAME}}" STREQUAL ""))
set(tfpmode NEVER)
elseif(NOT DEFINED FETCHCONTENT_TRY_FIND_PACKAGE_MODE)
set(tfpmode OPT_IN)
elseif(FETCHCONTENT_TRY_FIND_PACKAGE_MODE MATCHES "^OPT_IN|ALWAYS|NEVER$")
set(tfpmode ${FETCHCONTENT_TRY_FIND_PACKAGE_MODE})
else()
message(FATAL_ERRROR
"FETCHCONTENT_TRY_FIND_PACKAGE_MODE was set to a value other than "
"OPT_IN, ALWAYS, or NEVER")
endif()

# possibly modify quotedFindPackageArgs
if ("${tfpmode}" STREQUAL "ALWAYS" AND NOT DEFINED quotedFindPackageArgs)
set(quotedFindPackageArgs "")
elseif("${tfpmode}" STREQUAL "NEVER" AND DEFINED quotedFindPackageArgs)
unset(quotedFindPackageArgs)
endif()


if (DEFINED quotedFindPackageArgs)
cmake_language(EVAL CODE
"find_package(${content_name} QUIET ${quotedFindPackageArgs})")
set(found_var_name "${content_name}_FOUND")

if (NOT DEFINED ${found_var_name})
message(FATAL_ERROR "sanity-check: ${found_var_name} is not defined")
elseif("${${found_var_name}}")
# record that GrBackport_FetchContent_MakeAvailable shouldn't download
# data for ${content_name}
set_property(GLOBAL APPEND
PROPERTY _GRACKLE_Backport_FetchContent_BYPASS_DOWNLOAD
"${content_name}"
)
return()
endif()
endif()

cmake_language(EVAL CODE
"FetchContent_Declare(${content_name} ${quotedNormalArgs})")
endfunction()

function(GrBackport_FetchContent_MakeAvailable)
if ("${ARGC}" EQUAL 0)
message(FATAL_ERROR "GrBackport_FetchContent_MakeAvailable passed no arg")
endif()

# store the list of each content_name in the skip_list variable that was
# found with find_package
get_property(skip_list GLOBAL
PROPERTY _GRACKLE_Backport_FetchContent_BYPASS_DOWNLOAD
)

# build up quotedArgs with every content_name not in skip_list
cmake_parse_arguments(PARSE_ARGV 0 FWD "" "" "")
set(quotedArgs "")
foreach(arg IN LISTS FWD_UNPARSED_ARGUMENTS)
if(NOT("${arg}" IN_LIST skip_list))
string(APPEND quotedArgs " [===[${arg}]===]")
endif()
endforeach()

if (NOT ("${quotedArgs}" STREQUAL ""))
cmake_language(EVAL CODE "FetchContent_MakeAvailable(${quotedArgs})")
endif()
endfunction()

endif()
Loading