Files
CoolProp/wrappers/Python/CMakeLists.txt
Ian Bell f0b988236f build: replace git submodules with CPM.cmake (#2728)
* build: replace git submodules with CPM.cmake

All 11 submodules (Eigen, fmtlib, msgpack-c, rapidjson, IF97,
REFPROP-headers, multicomplex, Catch2, pybind11, ExcelAddinInstaller,
FindMathematica) are now fetched by CPM.cmake at configure time.

Set CPM_SOURCE_CACHE (e.g. ~/.cache/CPM) to share the download cache
across git worktrees and build directories — no more per-worktree
`git submodule update --init --recursive`.

Vendored deps that have no upstream release cycle (miniz, nlohmann-json,
incbin) remain in externals/ as before.

Source-level changes: angle-bracket includes for rapidjson, IF97, and
REFPROP-headers now that their directories are on the include path via
CPM-provided source dirs rather than relative paths from the repo root.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(python): wire up CPM.cmake in Python wrapper, fix include paths

The Python wrapper CMakeLists.txt was still referencing submodule paths
(externals/Eigen, externals/fmtlib, externals/msgpack-c) removed by the
CPM migration. Include CPM.cmake + dependencies.cmake from the root and
use the ${Pkg_SOURCE_DIR} variables instead.  Also adds missing
rapidjson, IF97, and REFPROP_headers include dirs required by CoolProp
sources.

CI workflows drop the now-meaningless `submodules: recursive` checkout
option and add a CPM source-cache step to avoid re-downloading on each
macOS/Windows runner.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: remove git submodule references after CPM.cmake migration

Dependencies are now managed by CPM.cmake (fetched automatically at
CMake configure time), so git submodules no longer exist.

- Drop `--recursive` from all `git clone` commands in Web docs and
  wrapper READMEs (26 .rst/.md files)
- Remove `submodules: recursive` from all CI workflow checkout steps
  (13 workflow files)
- Remove `git submodule foreach/update` calls from release.bsh and
  delete the now-dead pybind11 security-workaround lines
- Drop `--recursive` from build_swigged_matlab.sh and gitMirror.bsh
- Update CONTRIBUTING.md: drop "and its submodules" phrasing

Changelog entries referencing old submodule PRs are left intact as
historical records. The --recursive in buildbot.rst is for the
Dockerfiles repo (unrelated) and is also left unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ci): remove empty 'with:' blocks after submodule removal, apply clang-format

After removing 'submodules: recursive' from checkout steps, some workflow
files were left with dangling empty 'with:' blocks that GitHub Actions
rejects as workflow file errors. Remove the empty 'with:' in 9 workflows.

Also apply clang-format to fix spacing in REFPROPMixtureBackend.cpp,
HumidAirProp.cpp, and Helmholtz.cpp.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 11:45:10 -04:00

265 lines
8.3 KiB
CMake

cmake_minimum_required(VERSION 3.15...3.27)
project(${SKBUILD_PROJECT_NAME} LANGUAGES C CXX)
# Set C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Set position independent code (required for shared libraries)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# Add cmake directory to module path
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# Find Python
find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
# Find Cython
find_package(Cython REQUIRED)
# Set root directory
set(ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../..")
# Use CPM.cmake for dependency management (consistent with the main build)
include("${ROOT_DIR}/cmake/CPM.cmake")
include("${ROOT_DIR}/cmake/dependencies.cmake")
# ============================================================================
# Generate headers and constants (only when dependencies change)
# ============================================================================
# Collect all JSON files that trigger header regeneration
file(GLOB FLUID_JSON_FILES "${ROOT_DIR}/dev/fluids/*.json")
file(GLOB INCOMP_JSON_FILES "${ROOT_DIR}/dev/incompressible_liquids/json/*.json")
file(GLOB CUBIC_JSON_FILES "${ROOT_DIR}/dev/cubics/*.json")
file(GLOB PCSAFT_JSON_FILES "${ROOT_DIR}/dev/pcsaft/*.json")
file(GLOB MIXTURE_JSON_FILES "${ROOT_DIR}/dev/mixtures/*.json")
# Generate C++ headers from JSON files (only when inputs change)
# The generate_headers.py script has its own timestamp checking, so this
# won't unnecessarily regenerate files
add_custom_command(
OUTPUT
"${ROOT_DIR}/include/all_fluids_JSON.h"
"${ROOT_DIR}/include/all_fluids_JSON_z.h"
"${ROOT_DIR}/include/cpversion.h"
"${ROOT_DIR}/include/gitrevision.h"
COMMAND ${Python_EXECUTABLE} "${ROOT_DIR}/dev/generate_headers.py"
WORKING_DIRECTORY "${ROOT_DIR}/dev"
DEPENDS
"${ROOT_DIR}/dev/generate_headers.py"
"${ROOT_DIR}/CMakeLists.txt"
${FLUID_JSON_FILES}
${INCOMP_JSON_FILES}
${CUBIC_JSON_FILES}
${PCSAFT_JSON_FILES}
${MIXTURE_JSON_FILES}
COMMENT "Generating CoolProp headers from JSON files..."
VERBATIM
)
# Create a custom target that depends on generated headers
add_custom_target(generate_headers_target
DEPENDS
"${ROOT_DIR}/include/all_fluids_JSON.h"
"${ROOT_DIR}/include/all_fluids_JSON_z.h"
"${ROOT_DIR}/include/cpversion.h"
"${ROOT_DIR}/include/gitrevision.h"
)
# Generate Cython constants module (only when dependencies change)
add_custom_command(
OUTPUT
"${CMAKE_CURRENT_SOURCE_DIR}/CoolProp/_constants.pyx"
"${CMAKE_CURRENT_SOURCE_DIR}/CoolProp/constants_header.pxd"
"${CMAKE_CURRENT_SOURCE_DIR}/CoolProp/constants.py"
COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/generate_constants_module.py"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/generate_constants_module.py"
"${ROOT_DIR}/include/DataStructures.h"
"${ROOT_DIR}/include/Configuration.h"
COMMENT "Generating Cython constants module..."
VERBATIM
)
# Create a custom target for constants generation
add_custom_target(generate_constants_target
DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/CoolProp/_constants.pyx"
"${CMAKE_CURRENT_SOURCE_DIR}/CoolProp/constants_header.pxd"
"${CMAKE_CURRENT_SOURCE_DIR}/CoolProp/constants.py"
)
# ============================================================================
# Headers are used directly from ROOT_DIR for building (better dependency tracking)
# They will be copied to the package during the install phase
# ============================================================================
# Add the main CoolProp sources
file(GLOB_RECURSE COOLPROP_SOURCES
"${ROOT_DIR}/src/*.cpp"
)
# Remove any test files or unwanted sources
list(FILTER COOLPROP_SOURCES EXCLUDE REGEX ".*tests?/.*")
# Include directories
set(COOLPROP_INCLUDE_DIRS
${ROOT_DIR}
${ROOT_DIR}/include
${ROOT_DIR}/src
${ROOT_DIR}/dev
${Eigen_SOURCE_DIR}
${fmt_SOURCE_DIR}/include
${ROOT_DIR}/boost_CoolProp
${ROOT_DIR}/externals/incbin
${ROOT_DIR}/externals/nlohmann-json
${ROOT_DIR}/externals/miniz-3.1.1
${msgpack-c_SOURCE_DIR}/include
${rapidjson_SOURCE_DIR}/include
${IF97_SOURCE_DIR}
${REFPROP_headers_SOURCE_DIR}
)
# Expand boost if needed
if(NOT EXISTS "${ROOT_DIR}/boost_CoolProp/boost/version.hpp")
message(STATUS "Expanding boost sources...")
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xzf "${ROOT_DIR}/dev/docker/boost_bcp_docker/boost_CoolProp.tar.xz"
WORKING_DIRECTORY ${ROOT_DIR}
)
endif()
# Build miniz as a static library
add_library(miniz STATIC "${ROOT_DIR}/externals/miniz-3.1.1/miniz.c")
target_include_directories(miniz PUBLIC "${ROOT_DIR}/externals/miniz-3.1.1")
# Cythonize the .pyx files
set(CYTHON_FLAGS
--cplus
--directive embedsignature=True
--directive language_level=3
--directive c_string_type=unicode
--directive c_string_encoding=ascii
)
# Generate CoolProp module
add_custom_command(
OUTPUT CoolProp/CoolProp.cpp
COMMAND ${Python_EXECUTABLE} -m cython ${CYTHON_FLAGS}
-o "${CMAKE_CURRENT_BINARY_DIR}/CoolProp/CoolProp.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/CoolProp/CoolProp.pyx"
DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/CoolProp/CoolProp.pyx"
"${CMAKE_CURRENT_SOURCE_DIR}/CoolProp/constants_header.pxd"
generate_constants_target
COMMENT "Cythonizing CoolProp.pyx"
VERBATIM
)
# Generate _constants module
add_custom_command(
OUTPUT CoolProp/_constants.cpp
COMMAND ${Python_EXECUTABLE} -m cython ${CYTHON_FLAGS}
-o "${CMAKE_CURRENT_BINARY_DIR}/CoolProp/_constants.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/CoolProp/_constants.pyx"
DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/CoolProp/_constants.pyx"
"${CMAKE_CURRENT_SOURCE_DIR}/CoolProp/constants_header.pxd"
generate_constants_target
COMMENT "Cythonizing _constants.pyx"
VERBATIM
)
# Create CoolProp extension module
Python_add_library(CoolProp_module MODULE WITH_SOABI
"${CMAKE_CURRENT_BINARY_DIR}/CoolProp/CoolProp.cpp"
${COOLPROP_SOURCES}
)
# Make sure generated headers and constants exist before compiling
add_dependencies(CoolProp_module generate_headers_target generate_constants_target)
target_include_directories(CoolProp_module PRIVATE
${COOLPROP_INCLUDE_DIRS}
${Python_INCLUDE_DIRS}
)
target_link_libraries(CoolProp_module PRIVATE miniz)
# Set output name to CoolProp (not CoolProp_module)
set_target_properties(CoolProp_module PROPERTIES
OUTPUT_NAME "CoolProp"
PREFIX ""
)
if(WIN32)
target_compile_options(CoolProp_module PRIVATE /utf-8 /std:c++17)
else()
target_compile_options(CoolProp_module PRIVATE -std=c++17)
endif()
# Create _constants extension module
Python_add_library(_constants_module MODULE WITH_SOABI
"${CMAKE_CURRENT_BINARY_DIR}/CoolProp/_constants.cpp"
)
target_include_directories(_constants_module PRIVATE
${COOLPROP_INCLUDE_DIRS}
${Python_INCLUDE_DIRS}
)
set_target_properties(_constants_module PROPERTIES
OUTPUT_NAME "_constants"
PREFIX ""
)
if(WIN32)
target_compile_options(_constants_module PRIVATE /utf-8 /std:c++17)
else()
target_compile_options(_constants_module PRIVATE -std=c++17)
endif()
# Install the modules to the CoolProp package
install(TARGETS CoolProp_module _constants_module
LIBRARY DESTINATION CoolProp
RUNTIME DESTINATION CoolProp
)
# Install Python package files
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/CoolProp/"
DESTINATION CoolProp
FILES_MATCHING
PATTERN "*.py"
PATTERN "*.pxd"
PATTERN "*.bib"
PATTERN "psyrc"
PATTERN "__pycache__" EXCLUDE
PATTERN "*.pyc" EXCLUDE
)
# Install header files directly from ROOT_DIR (for packaging)
# These are copied at install time, not during build, to avoid
# triggering unnecessary rebuilds
install(DIRECTORY "${ROOT_DIR}/include/"
DESTINATION CoolProp/include
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.hpp"
PATTERN "*_JSON.h" EXCLUDE
PATTERN "*_JSON_z.h" EXCLUDE
)
# Install fmtlib headers (for packaging)
install(DIRECTORY "${ROOT_DIR}/externals/fmtlib/include/fmt"
DESTINATION CoolProp/include
FILES_MATCHING
PATTERN "*.h"
)
# Install BibTeX library
install(FILES "${ROOT_DIR}/CoolPropBibTeXLibrary.bib"
DESTINATION CoolProp
)