From f8c8651c02830cc33bdcd146dbb14b147b588f34 Mon Sep 17 00:00:00 2001 From: David Minton Date: Mon, 28 Aug 2023 12:19:48 -0400 Subject: [PATCH 01/22] Adjusted Mac build scripts --- buildscripts/_build_getopts.sh | 5 +++-- buildscripts/build_swiftest.sh | 1 + buildscripts/set_compilers.sh | 6 +++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/buildscripts/_build_getopts.sh b/buildscripts/_build_getopts.sh index 0c92d1077..7b05d72a3 100755 --- a/buildscripts/_build_getopts.sh +++ b/buildscripts/_build_getopts.sh @@ -14,10 +14,10 @@ SCRIPT_DIR=$(realpath $(dirname $0)) ROOT_DIR=$(realpath ${SCRIPT_DIR}/..) # Parse arguments -USTMT="Usage: ${0} <-d /path/to/dependency/source> [-p /prefix/path|{/usr/local}] [-m MACOSX_DEPLOYMENT_TARGET|{11.0}]" +USTMT="Usage: ${0} <-d /path/to/dependency/source> [-p /prefix/path|{/usr/local}] [-m MACOSX_DEPLOYMENT_TARGET|{10.9}]" PREFIX=/usr/local DEPENDENCY_DIR="${ROOT_DIR}/_dependencies" -MACOSX_DEPLOYMENT_TARGET="13.0" +MACOSX_DEPLOYMENT_TARGET="10.9" while getopts ":d:p:m:h" ARG; do case "${ARG}" in d) @@ -62,6 +62,7 @@ if [ -z ${DEPENDENCY_ENV_VARS+x} ]; then NCDIR="${PREFIX}" NFDIR="${PREFIX}" NETCDF_FORTRAN_HOME=${NFDIR} + NETCDF_INCLUDE=${NFDIR}/include NETCDF_HOME=${NCDIR} DEPENDENCY_ENV_VARS=true diff --git a/buildscripts/build_swiftest.sh b/buildscripts/build_swiftest.sh index c4f06bb4c..147814642 100755 --- a/buildscripts/build_swiftest.sh +++ b/buildscripts/build_swiftest.sh @@ -53,6 +53,7 @@ printf "CPATH: ${CPATH}\n" printf "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}\n" printf "LDFLAGS: ${LDFLAGS}\n" printf "NETCDF_FORTRAN_HOME: ${NETCDF_FORTRAN_HOME}\n" +printf "NETCDF_INCLUDE: ${NETCDF_INCLUDE}\n" printf "SKBUILD_CONFIGURE_OPTIONS: ${SKBUILD_CONFIGURE_OPTIONS}\n" if [ $OS = "MacOSX" ]; then printf "MACOSX_DEPLOYMENT_TARGET: ${MACOSX_DEPLOYMENT_TARGET}\n" diff --git a/buildscripts/set_compilers.sh b/buildscripts/set_compilers.sh index 3ff88f8b1..0a47cae81 100755 --- a/buildscripts/set_compilers.sh +++ b/buildscripts/set_compilers.sh @@ -115,7 +115,7 @@ case $OS in CFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -Wno-deprecated-non-prototype ${CFLAGS}" else if $(brew --version &> /dev/null); then - brew install gcc + brew install gcc libomp else echo \"Please install Homebrew first\" exit 1 @@ -129,9 +129,9 @@ case $OS in RANLIB=${RANLIB:-${COMPILER_PREFIX}/bin/gcc-ranlib-13} FC=${FC:-${COMPILER_PREFIX}/bin/gfortran-13} LD_LIBRARY_PATH="${COMPILER_PREFIX}/lib/gcc/13:${LD_LIBRARY_PATH}" - LDFLAGS="-L${HOMEBREW_PREFIX}/opt/llvm/lib/c++ -Wl,-rpath,${HOMEBREW_PREFIX}/opt/llvm/lib/c+ -Wl,-no_compact_unwind" + LDFLAGS="-L${HOMEBREW_PREFIX}/opt/llvm/lib/c++ -Wl,-rpath,${HOMEBREW_PREFIX}/opt/llvm/lib/c+ -L${HOMEBREW_PREFIX}/opt/libomp/lib -Wl,-no_compact_unwind" CPPFLAGS="-isystem ${HOMEBREW_PREFIX}/opt/libomp/include" - LIBS="-lgomp ${LIBS}" + LIBS="-lomp ${LIBS}" CPATH="${FROOT}/include:${CPATH}" CXXFLAGS="${CFLAGS} ${CXXFLAGS}" FCFLAGS="${CFLAGS} ${FCFLAGS}" From 06833e0dbce455fe259666dcc3ddb7e7310844b8 Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Mon, 28 Aug 2023 13:12:20 -0400 Subject: [PATCH 02/22] Made adjustments to python dependency package lists --- environment.yml | 4 ++-- requirements.txt | 1 + setup.py | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/environment.yml b/environment.yml index 015c642f1..933cb3fe1 100644 --- a/environment.yml +++ b/environment.yml @@ -7,9 +7,9 @@ channels: dependencies: - python>=3.8 - numpy>=1.24.3 - - pandas>=1.5.3 - scipy>=1.10.1 - xarray>=2022.11.0 + - distributed>=2022.1 - dask>=2022.1 - bottleneck>=1.3.5 - h5netcdf>=1.0.2 @@ -20,4 +20,4 @@ dependencies: - tqdm>=4.65.0 - x264>=1!157.20191217 - ffmpeg>=4.3.2 - - py>=1.11 \ No newline at end of file + - cython>=3.0.0 diff --git a/requirements.txt b/requirements.txt index e8492468c..79d85b58b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,7 @@ scipy>=1.10.1 xarray>=2022.11.0 dask>=2022.1 bottleneck>=1.3.5 +distributed>=2022.1 h5netcdf>=1.0.2 netcdf4>=1.6.2 matplotlib>=3.7.1 diff --git a/setup.py b/setup.py index a327a2cce..2d6141ffa 100644 --- a/setup.py +++ b/setup.py @@ -49,6 +49,7 @@ 'scipy>=1.10.1', 'xarray>=2022.11.0', 'dask>=2022.1', + 'distributed>=2022.1', 'bottleneck>=1.3.5', 'h5netcdf>=1.0.2', 'netcdf4>=1.6.2', From 8dbecd6c93e4b3697fa192124aca4bd45956a6bb Mon Sep 17 00:00:00 2001 From: David Minton Date: Mon, 28 Aug 2023 17:17:28 -0400 Subject: [PATCH 03/22] Made a number of improvements to the Windows build --- CMakeLists.txt | 8 + cmake/Modules/FindNETCDF.cmake | 61 +- cmake/Modules/SetCompileFlag.cmake | 5 +- cmake/Modules/SetFortranFlags.cmake | 894 ++++++++++++++++------------ src/CMakeLists.txt | 15 +- 5 files changed, 596 insertions(+), 387 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cb2aa413c..8ad7dc92c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,14 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.6.0...3.27.1) FILE(READ "version.txt" VERSION) PROJECT(swiftest VERSION ${VERSION} LANGUAGES C Fortran) +IF (CMAKE_Fortran_COMPILER_ID MATCHES "^Intel") + SET(COMPILER_OPTIONS "Intel" CACHE STRING "Compiler identified as Intel") +ELSEIF (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") + SET(COMPILER_OPTIONS "GNU" CACHE STRING "Compiler identified as gfortran") +ELSE () + MESSAGE(FATAL_ERROR "Compiler ${CMAKE_Fortran_COMPILER_ID} not recognized!") +ENDIF () + # Set some options the user may choose OPTION(USE_COARRAY "Use Coarray Fortran for parallelization of test particles" OFF) OPTION(USE_OPENMP "Use OpenMP for parallelization" ON) diff --git a/cmake/Modules/FindNETCDF.cmake b/cmake/Modules/FindNETCDF.cmake index c93c81e75..d6a3c4868 100644 --- a/cmake/Modules/FindNETCDF.cmake +++ b/cmake/Modules/FindNETCDF.cmake @@ -9,7 +9,14 @@ # - Finds the NetCDF libraries -IF (NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") +FILE(TO_CMAKE_PATH "${CMAKE_SOURCE_DIR}/_dependencies/${CMAKE_SYSTEM_NAME}_${CMAKE_SYSTEM_PROCESSOR}_${COMPILER_OPTIONS}" NXPREFIX_CANDIDATE) +IF (EXISTS ${NXPREFIX_CANDIDATE}) + SET(NCPREFIX_DIR ${NXPREFIX_CANDIDATE} CACHE PATH "Location of provided NetCDF-C dependencies") + SET(NFPREFIX_DIR ${NXPREFIX_CANDIDATE} CACHE PATH "Location of provided NetCDF-Fortran dependencies") + SET(H5PREFIX_DIR ${NXPREFIX_CANDIDATE} CACHE PATH "Location of provided HDF5 dependencies") + SET(ZPREFIX_DIR ${NXPREFIX_CANDIDATE} CACHE PATH "Location of provided zlib dependencies") + SET(NFINCLUDE_DIR "${NFPREFIX_DIR}/include" CACHE PATH "Location of provided netcdf.mod") +ELSEIF(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") FIND_PATH(NFBIN NAMES nf-config HINTS @@ -67,14 +74,19 @@ MESSAGE(STATUS "NetCDF-Fortran include directory: ${NETCDF_INCLUDE_DIR}") IF (BUILD_SHARED_LIBS) SET(NETCDFF "netcdff") - SET(NETCDF "netcdf") ELSE () IF (CMAKE_SYSTEM_NAME STREQUAL "Windows") SET(NETCDFF "netcdff.lib") SET(NETCDF "netcdf.lib") + SET(HDF5 "libhdf5.lib") + SET(HDF5_HL "libhdf5_hl.lib") + SET(ZLIB "zlibstatic.lib") ELSE () SET(NETCDFF "libnetcdff.a") SET(NETCDF "libnetcdf.a") + SET(HDF5 "libhdf5.a") + SET(HDF5_HL "libhdf5_hl.a") + SET(ZLIB "libz.a") ENDIF() ENDIF() @@ -99,6 +111,7 @@ ELSE () FIND_LIBRARY(NETCDF_LIBRARY NAMES ${NETCDF} HINTS + ${NCPREFIX_DIR} ENV NETCDF_HOME ENV LD_LIBRARY_PATH PATH_SUFFIXES @@ -108,7 +121,46 @@ ELSE () ) MESSAGE(STATUS "NetCDF-C Library: ${NETCDF_LIBRARY}") - IF (NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") + IF (CMAKE_SYSTEM_NAME STREQUAL "Windows") + FIND_LIBRARY(HDF5_LIBRARY + NAMES ${HDF5} + HINTS + ${H5PREFIX_DIR} + ENV HDF5_ROOT + ENV LD_LIBRARY_PATH + PATH_SUFFIXES + lib + ${CMAKE_LIBRARY_ARCHITECTURE} + REQUIRED + ) + + FIND_LIBRARY(HDF5_HL_LIBRARY + NAMES ${HDF5_HL} + HINTS + ${H5PREFIX_DIR} + ENV HDF5_ROOT + ENV LD_LIBRARY_PATH + PATH_SUFFIXES + lib + ${CMAKE_LIBRARY_ARCHITECTURE} + REQUIRED + ) + + FIND_LIBRARY(Z_LIBRARY + NAMES ${ZLIB} + HINTS + ${ZPREFIX_DIR} + ENV ZLIB_ROOT + ENV LD_LIBRARY_PATH + PATH_SUFFIXES + lib + ${CMAKE_LIBRARY_ARCHITECTURE} + REQUIRED + ) + + LIST(APPEND EXTRA_FLAGS ${HDF5_LIBRARY} ${HDF5_HL_LIBRARY} ${Z_LIBRARY}) + + ELSE () FIND_PATH(NCBIN NAMES nc-config HINTS @@ -143,13 +195,14 @@ ELSE () IF (DEFINED ENV{LIBS}) STRING(STRIP "$ENV{LIBS}" LIBS) - SEPARATE_ARGUMENTS(LIBS NATIVE_COMMAND "$LIBS") + SEPARATE_ARGUMENTS(LIBS NATIVE_COMMAND "${LIBS}") LIST(APPEND EXTRA_FLAGS ${LIBS}) ENDIF() # Note for posterity: When building static libraries, NETCDF_FORTRAN_LIBRARY must come *before* NETCDF_LIBRARY. Otherwise you get a bunch of "undefined reference to" errors SET(NETCDF_LIBRARIES ${NETCDF_FORTRAN_LIBRARY} ${NETCDF_LIBRARY} ${EXTRA_FLAGS} CACHE STRING "NetCDF Fortran and dependant static libraries") ENDIF () +MESSAGE(STATUS "NetCDF dependencies: ${NETCDF_LIBRARIES}") SET(NETCDF_FOUND TRUE) MARK_AS_ADVANCED(NETCDF_LIBRARIES NETCDF_INCLUDE_DIR) \ No newline at end of file diff --git a/cmake/Modules/SetCompileFlag.cmake b/cmake/Modules/SetCompileFlag.cmake index d094009ed..69e3526f8 100644 --- a/cmake/Modules/SetCompileFlag.cmake +++ b/cmake/Modules/SetCompileFlag.cmake @@ -71,7 +71,7 @@ FUNCTION(SET_COMPILE_FLAG FLAGVAR FLAGVAL LANG) # Now, loop over each flag FOREACH(flag ${FLAGLIST}) - + EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E echo_append "Checking compiler option ${flag}: ") UNSET(FLAG_WORKS) # Check the flag for the given language IF(LANG STREQUAL "C") @@ -105,11 +105,14 @@ end program dummyprog # If this worked, use these flags, otherwise use other flags IF(FLAG_WORKS) + EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E echo "OK") # Append this flag to the end of the list that already exists SET(${FLAGVAR} "${FLAGVAL} ${flag}" CACHE STRING "Set the ${FLAGVAR} flags" FORCE) SET(FLAG_FOUND TRUE) BREAK() # We found something that works, so exit + ELSE(FLAG_WORKS) + EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E echo "NO") ENDIF(FLAG_WORKS) ENDFOREACH(flag ${FLAGLIST}) diff --git a/cmake/Modules/SetFortranFlags.cmake b/cmake/Modules/SetFortranFlags.cmake index 5d319f5d4..360edda2b 100644 --- a/cmake/Modules/SetFortranFlags.cmake +++ b/cmake/Modules/SetFortranFlags.cmake @@ -63,311 +63,393 @@ ENDIF(CMAKE_Fortran_FLAGS_RELEASE AND CMAKE_Fortran_FLAGS_TESTING AND CMAKE_Fort # flag is given in the call). This way unknown compiles are supported. ####################################################################### +IF (CMAKE_SYSTEM_NAME STREQUAL "Windows") + SET(WINOPT True) +ELSE () + SET(WINOPT False) +ENDIF () ##################### ### GENERAL FLAGS ### ##################### + # Free form IF (COMPILER_OPTIONS STREQUAL "GNU") + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-ffree-form" # GNU + ) + + # Don't add underscores in symbols for C-compatability + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-fno-underscoring" # GNU + ) + # Compile code assuming that IEEE signaling NaNs may generate user-visible traps during floating-point operations. + # Setting this option disables optimizations that may change the number of exceptions visible with signaling NaNs. + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-fsignaling-nans " # GNU + ) + + # Allows for lines longer than 80 characters without truncation + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-ffree-line-length-512" # GNU (gfortran) + ) +ELSEIF (COMPILER_OPTIONS STREQUAL "Intel") + # Disables right margin wrapping in list-directed output + IF (WINOPT) SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" - Fortran "-ffree-form" # GNU - ) - - # Don't add underscores in symbols for C-compatability - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" - Fortran "-fno-underscoring" # GNU - ) - # Compile code assuming that IEEE signaling NaNs may generate user-visible traps during floating-point operations. - # Setting this option disables optimizations that may change the number of exceptions visible with signaling NaNs. + Fortran "/wrap-margin-" # Intel Windows + ) + # Aligns a variable to a specified boundary and offset SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" - Fortran "-fsignaling-nans " # GNU - ) - - # Allows for lines longer than 80 characters without truncation + Fortran "/align:all /align:array64byte" # Intel + ) + # Enables changing the variable and array memory layout SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" - Fortran "-ffree-line-length-512" # GNU (gfortran) - ) -ELSEIF (COMPILER_OPTIONS STREQUAL "Intel") - # Disables right margin wrapping in list-directed output + Fortran "/Qpad" # Intel Windows + ) + ELSE () SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" - Fortran "-no-wrap-margin" # Intel - "/wrap-margin-" # Intel Windows - ) - + Fortran "-no-wrap-margin" # Intel + ) # Aligns a variable to a specified boundary and offset SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" - Fortran "-align all -align array64byte" # Intel - "/align:all /align:array64byte" # Intel Windows - ) - + Fortran "-align all -align array64byte" # Intel + ) # Enables changing the variable and array memory layout SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" - Fortran "-pad" # Intel - "/Qpad" # Intel Windows - ) + Fortran "-pad" # Intel Windows + ) + ENDIF () +ENDIF () + +IF (NOT BUILD_SHARED_LIBS AND NOT WINOPT) + SET_COMPILE_FLAG(CMAKE_FORTRAN_FLAGS "${CMAKE_FORTRAN_FLAGS}" + Fortran "-fPIC" + ) + + IF (COMPILER_OPTIONS STREQUAL "Intel") + # Use static Intel libraries + SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + Fortran "-static-intel" # Intel + ) + # Use static Intel MPI libraries + SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + Fortran "-static_mpi" # Intel + ) + + IF (USE_OPENMP) + SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + Fortran "-qopenmp-link=static" # Intel + ) + ENDIF (USE_OPENMP) + + ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") + # Set GNU static libraries + SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + Fortran "-static-libgfortran" + ) + SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + Fortran "-static-libgcc" + ) + SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + Fortran "-static-libstdc++" + ) + SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + Fortran "-static-libquadmath" + ) + + IF (USE_OPENMP) + SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + Fortran "-lgomp" + ) + ENDIF (USE_OPENMP) + ENDIF () ENDIF () -IF (NOT BUILD_SHARED_LIBS) - SET_COMPILE_FLAG(CMAKE_FORTRAN_FLAGS "${CMAKE_FORTRAN_FLAGS}" - Fortran "-fPIC" - ) +IF (USE_SIMD) + IF (COMPILER_OPTIONS STREQUAL "Intel") + SET(MACHINE_CODE_VALUE "Host" CACHE STRING "Tells the compiler which processor features it may target, including which instruction sets and optimizations it may generate.") + + IF (MACHINE_CODE_VALUE STREQUAL "generic") + SET(MACHINE_CODE_VALUE "SSE2" CACHE STRING "SSE2 is the safest option when compiling for non-host compatibility" FORCE) + ENDIF() - IF (COMPILER_OPTIONS STREQUAL "Intel") - # Use static Intel libraries - SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" - Fortran "-static-intel" # Intel + # Enables OpenMP SIMD compilation when OpenMP parallelization is disabled. + IF (NOT USE_OPENMP) + IF (WINOPT) + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "/Qopenmp- /Qopenmp-simd" # Intel ) - # Use static Intel MPI libraries - SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" - Fortran "-static_mpi" # Intel + ELSE () + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-qno-openmp -qopenmp-simd>" # Intel ) + ENDIF () + ENDIF (NOT USE_OPENMP) - IF (USE_OPENMP) - SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" - Fortran "-qopenmp-link=static" # Intel - ) - ENDIF (USE_OPENMP) - ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") - # Set GNU static libraries - SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" - Fortran "-static-libgfortran" + # Optimize for an old enough processor that it should run on most computers + IF (WINOPT) + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "/Qx${MACHINE_CODE_VALUE}" # Intel ) - SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" - Fortran "-static-libgcc" + # Generate an extended set of vector functions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "/Qvecabi:cmdtarget" # Intel Windows ) - SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" - Fortran "-static-libstdc++" + ELSE () + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-x${MACHINE_CODE_VALUE}" # Intel ) - SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" - Fortran "-static-libquadmath" + # Generate an extended set of vector functions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-vecabi=cmdtarget" # Intel ) - IF (USE_OPENMP) - SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" - Fortran "-lgomp" - ) - ENDIF (USE_OPENMP) ENDIF () -ENDIF (NOT BUILD_SHARED_LIBS) - -IF (USE_SIMD) - - IF (COMPILER_OPTIONS STREQUAL "Intel") - SET(MACHINE_CODE_VALUE "Host" CACHE STRING "Tells the compiler which processor features it may target, including which instruction sets and optimizations it may generate.") - - IF (MACHINE_CODE_VALUE STREQUAL "generic") - SET(MACHINE_CODE_VALUE "SSE2" CACHE STRING "SSE2 is the safest option when compiling for non-host compatibility" FORCE) - ENDIF() + ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") + SET(MACHINE_CODE_VALUE "native" CACHE STRING "Tells the compiler which processor features it may target, including which instruction sets and optimizations it may generate.") - # Enables OpenMP SIMD compilation when OpenMP parallelization is disabled. - IF (NOT USE_OPENMP) - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" - Fortran "-qno-openmp -qopenmp-simd" # Intel - Fortran "/Qopenmp- /Qopenmp-simd" # Intel Windows - ) - ENDIF (NOT USE_OPENMP) + # Enables OpenMP SIMD compilation when OpenMP parallelization is disabled. + IF (NOT USE_OPENMP) + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-fno-openmp -fopenmp-simd" # GNU + ) + ENDIF (NOT USE_OPENMP) - # Optimize for an old enough processor that it should run on most computers + IF (MACHINE_CODE_VALUE STREQUAL "Host") + SET(MACHINE_CODE_VALUE "native" CACHE STRING "native is the GNU equivalent of Host" FORCE) + ENDIF () + + IF (APPLE) SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" - Fortran "-x${MACHINE_CODE_VALUE}" # Intel - "/Qx${MACHINE_CODE_VALUE}" # Intel Windows + Fortran "-mtune=${MACHINE_CODE_VALUE}" ) - - # Generate an extended set of vector functions + ELSE () SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" - Fortran "-vecabi=cmdtarget" # Intel - "/Qvecabi:cmdtarget" # Intel Windows - ) - ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") - SET(MACHINE_CODE_VALUE "native" CACHE STRING "Tells the compiler which processor features it may target, including which instruction sets and optimizations it may generate.") - - # Enables OpenMP SIMD compilation when OpenMP parallelization is disabled. - IF (NOT USE_OPENMP) - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" - Fortran "-fno-openmp -fopenmp-simd" # GNU - ) - ENDIF (NOT USE_OPENMP) - - IF (MACHINE_CODE_VALUE STREQUAL "Host") - SET(MACHINE_CODE_VALUE "native" CACHE STRING "native is the GNU equivalent of Host" FORCE) - ENDIF () - - IF (APPLE) - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" - Fortran "-mtune=${MACHINE_CODE_VALUE}" - ) - ELSE () - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" - Fortran "-march=${MACHINE_CODE_VALUE}" - ) - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" - Fortran "-mtune=${MACHINE_CODE_VALUE}" - ) - ENDIF () - + Fortran "-march=${MACHINE_CODE_VALUE}" + ) + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-mtune=${MACHINE_CODE_VALUE}" + ) ENDIF () - SET(MACHINE_CODE_VALUE ${MACHINE_CODE_VALUE} CACHE STRING "Tells the compiler which processor features it may target, including which instruction sets and optimizations it may generate.") -ENDIF (USE_SIMD) + + ENDIF () + SET(MACHINE_CODE_VALUE ${MACHINE_CODE_VALUE} CACHE STRING "Tells the compiler which processor features it may target, including which instruction sets and optimizations it may generate.") +ENDIF (USE_SIMD) ################### ### DEBUG FLAGS ### ################### IF (CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "TESTING" ) - # Disable optimizations - IF (COMPILER_OPTIONS STREQUAL "Intel") - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran REQUIRED "-O0" # All compilers not on Windows - "/Od" # Intel Windows - ) - - # Turn on all warnings - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-warn all" # Intel - "/warn:all" # Intel Windows - ) - - # Tells the compiler to issue compile-time messages for nonstandard language elements (Fortran 2018). - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-stand f18" # Intel - "/stand:f18" # Intel Windows - ) - - # Traceback - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-traceback" # Intel Group - "/traceback" # Intel Windows - ) - - # Check everything - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-check all" # Intel - "/check:all" # Intel Windows - ) - - # Initializes matrices/arrays with NaN values - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-init=snan,arrays" # Intel - "/Qinit:snan,arrays" # Intel Windows - ) - - # Does not generate an interface block for each routine in a source file - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-nogen-interfaces" # Intel - "/nogen-interfaces" # Intel Windows - ) - - # Does not generate aposition independent executable - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-no-pie" # Intel - ) - - # Does not set denormal results from floating-point calculations to zero - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-no-ftz" # Intel - "/Qftz-" # Intel Windows - ) - - # Enables floating-point invalid, divide-by-zero, and overflow exceptions - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-fpe-all=0" # Intel - "/fpe-all:0" # Intel Windows - ) - - # Enables floating-point invalid, divide-by-zero, and overflow exceptions - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-fpe0" # Intel - "/fpe:0" # Intel Windows - ) - - # Enables debug info - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-debug all" # Intel - "/debug:all" # Intel Windows - ) - - # Disables additional interprocedural optimizations for a single file compilation - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-no-ip" # Intel - "/Qip-" # Intel Windows - ) - - # Disables prefetch insertion optimization - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-qno-opt-prefetch" # Intel - "/Qopt-prefetch-" # Intel Windows - ) - - ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran REQUIRED "-Og" # GNU (gfortran) - ) - - # Turn on all warnings - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-Wall" # GNU - ) - # This enables some extra warning flags that are not enabled by -Wall - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-Wextra" # GNU - ) - - # Disable the warning that arrays may be uninitialized, which comes up due to a known bug in gfortran - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-Wno-maybe-uninitialized" # GNU - ) - # Disable the warning about unused dummy arguments. These primarily occur due to interface rules for type-bound procedures used in extendable types. - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-Wno-unused-dummy-argument" # GNU - ) - - # Tells the compiler to issue compile-time messages for nonstandard language elements (Fortran 2018). - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-fstd=f2018" # GNU - ) - - # Traceback - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-fbacktrace" # GNU (gfortran) - ) - - # Sanitize - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-fsanitize=address, undefined" # Gnu - ) - - # Check everything - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-fcheck=all" # GNU - ) - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-fstack-check" # GNU - ) - - # Initializes matrices/arrays with NaN values - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-finit-real=snan" # GNU - ) - - # Generates non position-independent code - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-fno-PIE" # GNU - ) - - # Enables floating-point invalid, divide-by-zero, and overflow exceptions - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-ffpe-trap=zero,overflow,underflow" # GNU - ) - - # List of floating-point exceptions, whose flag status is printed to ERROR_UNIT when invoking STOP and ERROR STOP - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-ffpe-summary=all" # GNU - ) + # Disable optimizations + IF (COMPILER_OPTIONS STREQUAL "Intel") + IF (WINOPT) + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran REQUIRED "/Od" # Intel Windows + ) + + # Turn on all warnings + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/warn:all" # Intel Windows + ) + + # Tells the compiler to issue compile-time messages for nonstandard language elements (Fortran 2018). + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/stand:f18" # Intel Windows + ) + + # Traceback + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/traceback" # Intel Windows + ) + + # Check everything + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/check:all" # Intel Windows + ) + + # Initializes matrices/arrays with NaN values + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/Qinit:snan,arrays" # Intel Windows + ) + + # Does not generate an interface block for each routine in a source file + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/nogen-interfaces" # Intel Windows + ) + + # Does not set denormal results from floating-point calculations to zero + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/Qftz-" # Intel Windows + ) + + # Enables floating-point invalid, divide-by-zero, and overflow exceptions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/fpe-all:0" # Intel Windows + ) + + # Enables floating-point invalid, divide-by-zero, and overflow exceptions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/fpe:0" # Intel Windows + ) + + # Enables debug info + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/debug:all" # Intel Windows + ) + + # Disables additional interprocedural optimizations for a single file compilation + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/Qip-" # Intel Windows + ) + + # Disables prefetch insertion optimization + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "/Qopt-prefetch-" # Intel Windows + ) + ELSE () + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran REQUIRED "-O0" # All compilers not on Windows + ) + + # Turn on all warnings + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-warn all" # Intel + ) + + # Tells the compiler to issue compile-time messages for nonstandard language elements (Fortran 2018). + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-stand f18" # Intel + ) + + # Traceback + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-traceback" # Intel Group + ) + + # Check everything + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-check all" # Intel + ) + + # Initializes matrices/arrays with NaN values + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-init=snan,arrays" # Intel + ) + + # Does not generate an interface block for each routine in a source file + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-nogen-interfaces" # Intel + ) + + # Does not generate aposition independent executable + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-no-pie" # Intel + ) + + # Does not set denormal results from floating-point calculations to zero + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-no-ftz" # Intel + ) + + # Enables floating-point invalid, divide-by-zero, and overflow exceptions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-fpe-all=0" # Intel + ) + + # Enables floating-point invalid, divide-by-zero, and overflow exceptions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-fpe0" # Intel + ) + + # Enables debug info + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-debug all" # Intel + ) + + # Disables additional interprocedural optimizations for a single file compilation + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-no-ip" # Intel + ) + + # Disables prefetch insertion optimization + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-qno-opt-prefetch" # Intel + ) - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran "-fstack-check" # GNU - ) ENDIF () + + ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran REQUIRED "-Og" # GNU (gfortran) + ) + + # Turn on all warnings + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-Wall" # GNU + ) + # This enables some extra warning flags that are not enabled by -Wall + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-Wextra" # GNU + ) + + # Disable the warning that arrays may be uninitialized, which comes up due to a known bug in gfortran + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-Wno-maybe-uninitialized" # GNU + ) + # Disable the warning about unused dummy arguments. These primarily occur due to interface rules for type-bound procedures used in extendable types. + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-Wno-unused-dummy-argument" # GNU + ) + + # Tells the compiler to issue compile-time messages for nonstandard language elements (Fortran 2018). + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-fstd=f2018" # GNU + ) + + # Traceback + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-fbacktrace" # GNU (gfortran) + ) + + # Sanitize + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-fsanitize=address, undefined" # Gnu + ) + + # Check everything + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-fcheck=all" # GNU + ) + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-fstack-check" # GNU + ) + + # Initializes matrices/arrays with NaN values + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-finit-real=snan" # GNU + ) + + # Generates non position-independent code + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-fno-PIE" # GNU + ) + + # Enables floating-point invalid, divide-by-zero, and overflow exceptions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-ffpe-trap=zero,overflow,underflow" # GNU + ) + + # List of floating-point exceptions, whose flag status is printed to ERROR_UNIT when invoking STOP and ERROR STOP + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-ffpe-summary=all" # GNU + ) + + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" + Fortran "-fstack-check" # GNU + ) + ENDIF () ENDIF () @@ -377,11 +459,16 @@ ENDIF () IF (CMAKE_BUILD_TYPE STREQUAL "TESTING" ) - # Optimizations + # Optimizations + IF (WINOPT) SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_TESTING "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran REQUIRED "-O3" # All compilers not on Windows - "/O3" # Intel Windows - ) + REQUIRED "/O3" # Intel Windows + ) + ELSE () + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_TESTING "${CMAKE_Fortran_FLAGS_DEBUG}" + REQUIRED "-O3" # All compilers not on Windows + ) + ENDIF () ENDIF () ##################### @@ -392,69 +479,102 @@ ENDIF () IF (CMAKE_BUILD_TYPE STREQUAL "RELEASE" OR CMAKE_BUILD_TYPE STREQUAL "PROFILE") - IF (COMPILER_OPTIONS STREQUAL "Intel") - # Unroll loops - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" - Fortran "-unroll" # Intel - "/unroll" # Intel Windows - - ) - - # Inline functions - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" - Fortran "-inline" # Intel - "/Qinline" # Intel Windows - ) - - # Calls the Matrix Multiply library - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" - Fortran "-qopt-matmul" # Intel - "/Qopt-matmul" # Intel Windows - ) - - # Aligns a variable to a specified boundary and offset - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" - Fortran "-align all" # Intel - "/align:all" # Intel Windows - ) - - # No floating-point exceptions - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" - Fortran "-fp-model no-except" # Intel - "/fp:no-except" # Intel Windows - ) - - # Generate fused multiply-add instructions - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" - Fortran "-fma" # Intel - "/Qfma" # Intel Windows - ) - - # Tells the compiler to link to certain libraries in the Intel oneAPI Math Kernel Library (oneMKL). - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" - Fortran "-qmkl=cluster" # Intel - "-qmkl" # Intel - "/Qmkl:cluster" # Intel Windows - "/Qmkl" # Intel Windows - ) - - # Enables additional interprocedural optimizations for a single file compilation - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" - Fortran "-ip" # Intel - "/Qip" # Intel Windows - ) - - ELSEIF(COMPILER_OPTIONS STREQUAL "GNU") - # Unroll loops - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" - Fortran "-funroll-loops" # GNU - ) - - # Inline functions - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" - Fortran "-finline-functions" # GNU - ) - ENDIF () + IF (COMPILER_OPTIONS STREQUAL "Intel") + IF (WINOPT) + # Unroll loops + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "/unroll" # Intel Windows + ) + + # Inline functions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "/Qinline" # Intel Windows + ) + + # Calls the Matrix Multiply library + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "/Qopt-matmul" # Intel Windows + ) + + # Aligns a variable to a specified boundary and offset + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "/align:all" # Intel Windows + ) + + # No floating-point exceptions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "/fp:no-except" # Intel Windows + ) + + # Generate fused multiply-add instructions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "/Qfma" # Intel Windows + ) + + # Tells the compiler to link to certain libraries in the Intel oneAPI Math Kernel Library (oneMKL). + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "/Qmkl:cluster" # Intel Windows + "/Qmkl" # Intel Windows + ) + + # Enables additional interprocedural optimizations for a single file compilation + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "/Qip" # Intel Windows + ) + ELSE () + # Unroll loops + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-unroll" # Intel + ) + + # Inline functions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-inline" # Intel + ) + + # Calls the Matrix Multiply library + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-qopt-matmul" # Intel + ) + + # Aligns a variable to a specified boundary and offset + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-align all" # Intel + ) + + # No floating-point exceptions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-fp-model no-except" # Intel + ) + + # Generate fused multiply-add instructions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-fma" # Intel + ) + + # Tells the compiler to link to certain libraries in the Intel oneAPI Math Kernel Library (oneMKL). + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-qmkl=cluster" # Intel + "-qmkl" # Intel + ) + + # Enables additional interprocedural optimizations for a single file compilation + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-ip" # Intel + ) + ENDIF () + + ELSEIF(COMPILER_OPTIONS STREQUAL "GNU") + # Unroll loops + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-funroll-loops" # GNU + ) + + # Inline functions + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-finline-functions" # GNU + ) + ENDIF () ENDIF () @@ -463,60 +583,83 @@ ENDIF () ##################### IF (COMPILER_OPTIONS STREQUAL "Intel") + IF (WINOPT) # Some subroutines require more strict floating point operation optimizations for repeatability SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" - Fortran "-fp-model=precise" # Intel - "/fp:precise" # Intel Windows - ) + Fortran "/fp:precise" # Intel Windows + ) SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" - Fortran "-prec-div" # Intel - "/Qprec-div" # Intel Windows - ) + Fortran "/Qprec-div" # Intel Windows + ) SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" - Fortran "-prec-sqrt" # Intel - "/Qprec-sqrt" # Intel Windows - ) + Fortran "/Qprec-sqrt" # Intel Windows + ) SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" - Fortran "-assume protect-parens" # Intel - "/assume:protect-parens" # Intel Windows - ) + Fortran "/assume:protect-parens" # Intel Windows + ) # Improves floating-point precision and consistency SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" - Fortran "-mp1" # Intel - "/Qprec" # Intel Windows - ) + Fortran "/Qprec" # Intel Windows + ) - # Most subroutines can use aggressive optimization of floating point operations without problems. + # Most subroutines can use aggressive optimization of floating point operations without problems. SET_COMPILE_FLAG(FASTMATH_FLAGS "${FASTMATH_FLAGS}" - Fortran "-fp-model=fast" # Intel - "/fp:fast" # Intel Windows - ) + Fortran "/fp:fast" # Intel Windows + ) + ELSE () + # Some subroutines require more strict floating point operation optimizations for repeatability + SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" + Fortran "-fp-module=precise" # Intel + ) + SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" + Fortran "-prec-div" # Intel + ) -ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") + SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" + Fortran "-prec-sqrt" # Intel + ) - # Some subroutines require more strict floating point operation optimizations for repeatability SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" - Fortran "-fno-unsafe-math-optimizations" # GNU - ) - # Disable transformations and optimizations that assume default floating-point rounding behavior. + Fortran "-assume protect-parens" # Intel + ) + + # Improves floating-point precision and consistency SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" - Fortran "-frounding-math" - ) + Fortran "-mp1" # Intel Windows + ) - # Most subroutines can use aggressive optimization of floating point operations without problems. + # Most subroutines can use aggressive optimization of floating point operations without problems. SET_COMPILE_FLAG(FASTMATH_FLAGS "${FASTMATH_FLAGS}" - Fortran "-ffast-math" # GNU - ) + Fortran "-fp-model=fast" # Intel Windows + ) + + ENDIF () + +ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") + + # Some subroutines require more strict floating point operation optimizations for repeatability + SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" + Fortran "-fno-unsafe-math-optimizations" # GNU + ) + # Disable transformations and optimizations that assume default floating-point rounding behavior. + SET_COMPILE_FLAG(STRICTMATH_FLAGS "${STRICTMATH_FLAGS}" + Fortran "-frounding-math" + ) + + # Most subroutines can use aggressive optimization of floating point operations without problems. + SET_COMPILE_FLAG(FASTMATH_FLAGS "${FASTMATH_FLAGS}" + Fortran "-ffast-math" # GNU + ) ENDIF () # Debug mode always uses strict math SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" - Fortran ${STRICTMATH_FLAGS} + Fortran ${STRICTMATH_FLAGS} ) ##################### @@ -524,16 +667,21 @@ SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}" ##################### IF (CMAKE_BUILD_TYPE STREQUAL "PROFILE") - IF (COMPILER_OPTIONS STREQUAL "Intel") - # Enables the optimization reports to be generated - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_PROFILE "${CMAKE_Fortran_FLAGS_RELEASE}" - Fortran "-O2 -pg -qopt-report=5 -traceback -p -g3" # Intel - "/O2 /Qopt-report:5 /traceback /Z7" # Intel Windows - ) - ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") - # Enables the optimization reports to be generated - SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_PROFILE "${CMAKE_Fortran_FLAGS_RELEASE}" - Fortran "-O2 -pg -fbacktrace" # GNU - ) + IF (COMPILER_OPTIONS STREQUAL "Intel") + # Enables the optimization reports to be generated + IF (WINOPT) + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_PROFILE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "/O2 /Qopt-report:5 /traceback /Z7" # Intel Windows + ) + ELSE () + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_PROFILE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-O2 -pg -qopt-report=5 -traceback -p -g3" # Intel + ) ENDIF () + ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") + # Enables the optimization reports to be generated + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS_PROFILE "${CMAKE_Fortran_FLAGS_RELEASE}" + Fortran "-O2 -pg -fbacktrace" # GNU + ) + ENDIF () ENDIF () diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 403336a8f..d86e2eedd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,17 +16,9 @@ IF(NOT CMAKE_Fortran_COMPILER_SUPPORTS_F90) MESSAGE(FATAL_ERROR "Fortran compiler does not support F90") ENDIF(NOT CMAKE_Fortran_COMPILER_SUPPORTS_F90) -IF (CMAKE_Fortran_COMPILER_ID MATCHES "^Intel") - SET(COMPILER_OPTIONS "Intel" CACHE STRING "Compiler identified as Intel") -ELSEIF (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") - SET(COMPILER_OPTIONS "GNU" CACHE STRING "Compiler identified as gfortran") -ELSE () - MESSAGE(FATAL_ERROR "Compiler not recognized!") -ENDIF () - INCLUDE(SetParallelizationLibrary) INCLUDE(SetUpNetCDF) -IF (COMPILER_OPTIONS STREQUAL "Intel") +IF (COMPILER_OPTIONS STREQUAL "Intel" AND NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") INCLUDE(SetMKL) ENDIF () @@ -164,6 +156,11 @@ IF(USE_OPENMP OR USE_SIMD) SET_PROPERTY(TARGET ${SWIFTEST_LIBRARY} ${SWIFTEST_DRIVER} APPEND_STRING PROPERTY LINK_FLAGS "${OpenMP_Fortran_FLAGS} ") ENDIF() +IF (CMAKE_SYSTEM_NAME STREQUAL "Windows") + SET_PROPERTY(TARGET ${SWIFTEST_LIBRARY} ${SWIFTEST_DRIVER} APPEND_STRING PROPERTY LINK_FLAGS "/NODEFAULTLIB") +ENDIF() + + IF(USE_COARRAY) TARGET_COMPILE_DEFINITIONS(${SWIFTEST_LIBRARY} PUBLIC -DCOARRAY) TARGET_COMPILE_DEFINITIONS(${SWIFTEST_DRIVER} PUBLIC -DCOARRAY) From 1551c0984c17b2ff371ee2c76437cd277a268fa1 Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Tue, 29 Aug 2023 11:11:42 -0400 Subject: [PATCH 04/22] Updated version number and made a number of changes aimed at getting a stable MacOS build --- CMakeLists.txt | 3 ++ buildscripts/_build_getopts.sh | 2 +- buildscripts/build_swiftest.sh | 62 ++++++++++++++------------------ buildscripts/set_compilers.sh | 65 +++++++++------------------------- src/CMakeLists.txt | 1 - src/globals/globals_module.f90 | 2 +- swiftest/CMakeLists.txt | 6 ++-- version.txt | 2 +- 8 files changed, 52 insertions(+), 91 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ad7dc92c..01aa4d8eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,9 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BIN}) # Have the .mod files placed in the lib folder SET(CMAKE_Fortran_MODULE_DIRECTORY ${MOD}) +# Set the name of the swiftest library +SET(SWIFTEST_LIBRARY swiftest) + # The source for the SWIFTEST binary and have it placed in the bin folder ADD_SUBDIRECTORY(${SRC} ${BIN}) diff --git a/buildscripts/_build_getopts.sh b/buildscripts/_build_getopts.sh index 7b05d72a3..9ccfde135 100755 --- a/buildscripts/_build_getopts.sh +++ b/buildscripts/_build_getopts.sh @@ -53,7 +53,7 @@ if [ -z ${DEPENDENCY_ENV_VARS+x} ]; then LD_LIBRARY_PATH="${PREFIX}/lib:${LD_LIBRARY_PATH}" CPPFLAGS="${CPPFLAGS} -isystem ${PREFIX}/include" LDFLAGS="${LDFLAGS} -L${PREFIX}/lib" - CPATH="${CPATH} ${PREFIX}/include}" + CPATH="${PREFIX}/include:${CPATH}" HDF5_ROOT="${PREFIX}" HDF5_LIBDIR="${HDF5_ROOT}/lib" diff --git a/buildscripts/build_swiftest.sh b/buildscripts/build_swiftest.sh index 147814642..d2da64c91 100755 --- a/buildscripts/build_swiftest.sh +++ b/buildscripts/build_swiftest.sh @@ -21,49 +21,39 @@ if [ ! -f "${ROOT_DIR}/setup.py" ]; then exit 1 fi +read -r OS ARCH < <($SCRIPT_DIR/get_platform.sh) +echo $OS $ARCH + printf "Using ${OS} compilers:\nFC: ${FC}\nCC: ${CC}\nCXX: ${CXX}\n\n" printf "Installing to ${PREFIX}\n" printf "Dependency libraries in ${PREFIX}\n" - -SKBUILD_CONFIGURE_OPTIONS="-DBUILD_SHARED_LIBS=OFF" - -if [ $OS = "Intel" ]; then - FCFLAGS="${CFLAGS} -standard-semantics" - SKBUILD_CONFIGURE_OPTIONS="${SKBUILD_CONFIGURE_OPTIONS} -DMACHINE_CODE_VALUE=\"SSE2\"" +if [ $OS = "Linux" ]; then + cibuildwheel --platform linux else + SKBUILD_CONFIGURE_OPTIONS="-DBUILD_SHARED_LIBS=OFF" SKBUILD_CONFIGURE_OPTIONS="${SKBUILD_CONFIGURE_OPTIONS} -DMACHINE_CODE_VALUE=\"generic\"" -fi - -read -r OS ARCH < <($SCRIPT_DIR/get_platform.sh) -echo $OS $ARCH - -cd $ROOT_DIR - -printf "\n" -printf "*********************************************************\n" -printf "* BUILDING SWIFTEST *\n" -printf "*********************************************************\n" -printf "LIBS: ${LIBS}\n" -printf "CFLAGS: ${CFLAGS}\n" -printf "FFLAGS: ${FFLAGS}\n" -printf "FCFLAGS: ${FCFLAGS}\n" -printf "CPPFLAGS: ${CPPFLAGS}\n" -printf "CPATH: ${CPATH}\n" -printf "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}\n" -printf "LDFLAGS: ${LDFLAGS}\n" -printf "NETCDF_FORTRAN_HOME: ${NETCDF_FORTRAN_HOME}\n" -printf "NETCDF_INCLUDE: ${NETCDF_INCLUDE}\n" -printf "SKBUILD_CONFIGURE_OPTIONS: ${SKBUILD_CONFIGURE_OPTIONS}\n" -if [ $OS = "MacOSX" ]; then + cd $ROOT_DIR + + printf "\n" + printf "*********************************************************\n" + printf "* BUILDING SWIFTEST *\n" + printf "*********************************************************\n" + printf "LIBS: ${LIBS}\n" + printf "CFLAGS: ${CFLAGS}\n" + printf "FFLAGS: ${FFLAGS}\n" + printf "FCFLAGS: ${FCFLAGS}\n" + printf "CPPFLAGS: ${CPPFLAGS}\n" + printf "CPATH: ${CPATH}\n" + printf "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}\n" + printf "LDFLAGS: ${LDFLAGS}\n" + printf "NETCDF_FORTRAN_HOME: ${NETCDF_FORTRAN_HOME}\n" + printf "NETCDF_INCLUDE: ${NETCDF_INCLUDE}\n" + printf "SKBUILD_CONFIGURE_OPTIONS: ${SKBUILD_CONFIGURE_OPTIONS}\n" printf "MACOSX_DEPLOYMENT_TARGET: ${MACOSX_DEPLOYMENT_TARGET}\n" -fi -printf "*********************************************************\n" + printf "*********************************************************\n" -python3 -m pip install build pip -python3 -m build --sdist -if [ $OS = "MacOSX" ]; then + python3 -m pip install build pip + python3 -m build --sdist cibuildwheel --platform macos -elif [ $OS = "Linux" ]; then - cibuildwheel --platform linux fi \ No newline at end of file diff --git a/buildscripts/set_compilers.sh b/buildscripts/set_compilers.sh index 0a47cae81..10d3fac67 100755 --- a/buildscripts/set_compilers.sh +++ b/buildscripts/set_compilers.sh @@ -89,54 +89,23 @@ case $OS in CPP=${CPP:-$(command -v cpp)} ;; MacOSX) - if [ $ARCH = "arm64" ]; then - if $(brew --version &> /dev/null); then - brew install llvm@16 libomp - else - echo \"Please install Homebrew first\" - exit 1 - fi - COMPILER_PREFIX=${COMPILER_PREFIX:-"${HOMEBREW_PREFIX}/opt/llvm"} - CC=${CC:-${COMPILER_PREFIX}/bin/clang} - CXX=${CXX:-${COMPILER_PREFIX}/bin/clang++} - CPP=${CPP:-${COMPILER_PREFIX}/bin/clang-cpp} - AR=${AR:-${COMPILER_PREFIX}/bin/llvm-ar} - NM=${NM:-${COMPILER_PREFIX}/bin/llvm-nm} - RANLIB=${RANLIB:-${COMPILER_PREFIX}/bin/llvm-ranlib} - FROOT=$(realpath $(dirname $(command -v gfortran))/..) - FC=$(command -v gfortran) - LD_LIBRARY_PATH="${COMPILER_PREFIX}/lib:${FROOT}/lib:${LD_LIBRARY_PATH}" - LDFLAGS="-L${HOMEBREW_PREFIX}/opt/llvm/lib/c++ -Wl,-rpath,${HOMEBREW_PREFIX}/opt/llvm/lib/c+ -L${HOMEBREW_PREFIX}/opt/libomp/lib -Wl,-no_compact_unwind" - CPPFLAGS="-isystem ${HOMEBREW_PREFIX}/opt/libomp/include" - LIBS="-lomp ${LIBS}" - CPATH="${FROOT}/include:${CPATH}" - CXXFLAGS="${CFLAGS} ${CXXFLAGS}" - FCFLAGS="${CFLAGS} ${FCFLAGS}" - CFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -Wno-deprecated-non-prototype ${CFLAGS}" - else - if $(brew --version &> /dev/null); then - brew install gcc libomp - else - echo \"Please install Homebrew first\" - exit 1 - fi - COMPILER_PREFIX=${COMPILER_PREFIX:-"${HOMEBREW_PREFIX}/Cellar/gcc/13.1.0/"} - CC=${CC:-${COMPILER_PREFIX}/bin/gcc-13} - CXX=${CXX:-${COMPILER_PREFIX}/bin/g++-13} - CPP=${CPP:-${COMPILER_PREFIX}/bin/cpp-13} - AR=${AR:-${COMPILER_PREFIX}/bin/gcc-ar-13} - NM=${NM:-${COMPILER_PREFIX}/bin/gcc-nm-13} - RANLIB=${RANLIB:-${COMPILER_PREFIX}/bin/gcc-ranlib-13} - FC=${FC:-${COMPILER_PREFIX}/bin/gfortran-13} - LD_LIBRARY_PATH="${COMPILER_PREFIX}/lib/gcc/13:${LD_LIBRARY_PATH}" - LDFLAGS="-L${HOMEBREW_PREFIX}/opt/llvm/lib/c++ -Wl,-rpath,${HOMEBREW_PREFIX}/opt/llvm/lib/c+ -L${HOMEBREW_PREFIX}/opt/libomp/lib -Wl,-no_compact_unwind" - CPPFLAGS="-isystem ${HOMEBREW_PREFIX}/opt/libomp/include" - LIBS="-lomp ${LIBS}" - CPATH="${FROOT}/include:${CPATH}" - CXXFLAGS="${CFLAGS} ${CXXFLAGS}" - FCFLAGS="${CFLAGS} ${FCFLAGS}" - CFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -Wno-deprecated-non-prototype ${CFLAGS}" - fi + COMPILER_PREFIX=${COMPILER_PREFIX:-"/usr"} + CC=${CC:-${COMPILER_PREFIX}/bin/clang} + CXX=${CXX:-${COMPILER_PREFIX}/bin/clang++} + CPP=${CPP:-${COMPILER_PREFIX}/bin/cpp} + AR=${AR:-${COMPILER_PREFIX}/bin/ar} + NM=${NM:-${COMPILER_PREFIX}/bin/nm} + RANLIB=${RANLIB:-${COMPILER_PREFIX}/bin/ranlib} + FC=${FC:-$(command -v gfortran)} + FROOT=$(realpath $(dirname $(command -v $FC))/..) + LD_LIBRARY_PATH="${COMPILER_PREFIX}/lib:${FROOT}/lib:${LD_LIBRARY_PATH}" + LDFLAGS="${LDFLAGS} -Wl,-rpath,${COMPILER_PREFIX}/lib -Wl,-no_compact_unwind" + CPPFLAGS="${CPPFLAGS} -isystem ${COMPILER_PREFIX}/include" + LIBS="${LIBS}" + CPATH="${FROOT}/include:${CPATH}" + CXXFLAGS="${CFLAGS} ${CXXFLAGS}" + FCFLAGS="${CFLAGS} ${FCFLAGS}" + CFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -Wno-deprecated-non-prototype ${CFLAGS}" ;; *) printf "Unknown compiler type: ${OS}\n" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d86e2eedd..082d881f4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -140,7 +140,6 @@ ADD_EXECUTABLE(${SWIFTEST_DRIVER} ${DRIVER_src}) # Add the needed libraries ##################################################### # Create a library from the source files, except the driver -SET(SWIFTEST_LIBRARY swiftest) ADD_LIBRARY(${SWIFTEST_LIBRARY} ${SWIFTEST_src}) IF (NOT BUILD_SHARED_LIBS) SET_PROPERTY(TARGET ${SWIFTEST_LIBRARY} PROPERTY POSITION_INDEPENDENT_CODE) diff --git a/src/globals/globals_module.f90 b/src/globals/globals_module.f90 index 309a5d14e..183c21b09 100644 --- a/src/globals/globals_module.f90 +++ b/src/globals/globals_module.f90 @@ -44,7 +44,7 @@ module globals integer(I4B), parameter :: UPPERCASE_OFFSET = iachar('A') - iachar('a') !! ASCII character set parameter for lower to upper !! conversion - offset between upper and lower - character(*), parameter :: VERSION = "2023.8.0" !! Swiftest version + character(*), parameter :: VERSION = "2023.8.1" !! Swiftest version !> Symbolic name for integrator types character(*), parameter :: UNKNOWN_INTEGRATOR = "UKNOWN INTEGRATOR" diff --git a/swiftest/CMakeLists.txt b/swiftest/CMakeLists.txt index 9a73977af..6bdf332d1 100644 --- a/swiftest/CMakeLists.txt +++ b/swiftest/CMakeLists.txt @@ -33,11 +33,11 @@ ADD_LIBRARY(${SWIFTEST_BINDINGS} MODULE ${SWIFTEST_BINDINGS}) IF (NOT BUILD_SHARED_LIBS) SET_PROPERTY(TARGET ${SWIFTEST_BINDINGS} PROPERTY POSITION_INDEPENDENT_CODE) ENDIF () + +TARGET_LINK_LIBRARIES(${SWIFTEST_BINDINGS} ${SWIFTEST_LIBRARY} ${NETCDF_LIBRARIES}) IF(USE_OPENMP OR USE_SIMD) - SET_PROPERTY(TARGET ${SWIFTEST_BINDINGS} APPEND_STRING PROPERTY COMPILE_FLAGS "${OpenMP_Fortran_FLAGS} ") + SET_PROPERTY(TARGET ${SWIFTEST_BINDINGS} APPEND_STRING PROPERTY LINK_FLAGS "${OpenMP_Fortran_FLAGS} ") ENDIF() - -TARGET_LINK_LIBRARIES(${SWIFTEST_BINDINGS} swiftest ${NETCDF_LIBRARIES}) PYTHON_EXTENSION_MODULE(${SWIFTEST_BINDINGS}) TARGET_INCLUDE_DIRECTORIES(${SWIFTEST_BINDINGS} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${MOD} ${NETCDF_INCLUDE_DIR}) INSTALL(TARGETS ${SWIFTEST_BINDINGS} LIBRARY DESTINATION swiftest) \ No newline at end of file diff --git a/version.txt b/version.txt index a4fb2c126..4d449f4ac 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -2023.8.0 \ No newline at end of file +2023.8.1 \ No newline at end of file From 93e69a47fb4ffae861533abf956b8264a4d78a8c Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Tue, 29 Aug 2023 16:06:06 -0400 Subject: [PATCH 05/22] Made a number of changes aimed at getting it to compile using older gfortran versions that don't support quad precision. Also fixed the version statement. --- buildscripts/build_swiftest.sh | 8 ++++++ cmake/Modules/SetFortranFlags.cmake | 31 +++++++++++++---------- src/CMakeLists.txt | 38 +++++++++++++++++++++-------- src/coarray/coarray_clone.f90 | 2 ++ src/coarray/coarray_module.f90 | 2 ++ src/globals/globals_module.f90 | 6 ++++- src/globals/globals_module.f90.in | 6 ++++- src/misc/solver_module.f90 | 6 +++-- src/operator/operator_cross.f90 | 4 +++ src/operator/operator_mag.f90 | 2 ++ src/operator/operator_module.f90 | 14 ++++++++++- src/operator/operator_unit.f90 | 6 +++-- src/swiftest/swiftest_io.f90 | 4 +-- src/swiftest/swiftest_module.f90 | 2 ++ src/swiftest/swiftest_util.f90 | 32 ++++++++++++------------ 15 files changed, 115 insertions(+), 48 deletions(-) diff --git a/buildscripts/build_swiftest.sh b/buildscripts/build_swiftest.sh index d2da64c91..b3e3cdc87 100755 --- a/buildscripts/build_swiftest.sh +++ b/buildscripts/build_swiftest.sh @@ -33,12 +33,19 @@ if [ $OS = "Linux" ]; then else SKBUILD_CONFIGURE_OPTIONS="-DBUILD_SHARED_LIBS=OFF" SKBUILD_CONFIGURE_OPTIONS="${SKBUILD_CONFIGURE_OPTIONS} -DMACHINE_CODE_VALUE=\"generic\"" + OMPROOT=${DEVTOOLDIR}/MacOSX${MACOSX_DEPLOYMENT_TARGET}/${ARCH}/usr/local + CPPFLAGS="${CPPFLAGS} -Xclang -fopenmp" + LIBS="${LIBS} -lomp" + LDFLAGS="-Wl,-rpath,${OMPROOT}/lib" + CPATH="${OMPROOT}/include:${CPATH}" + LD_LIBRARY_PATH="${OMPROOT}/lib:${LD_LIBRARY_PATH}" cd $ROOT_DIR printf "\n" printf "*********************************************************\n" printf "* BUILDING SWIFTEST *\n" printf "*********************************************************\n" + printf "OMPROOT: ${OMPROOT}\n" printf "LIBS: ${LIBS}\n" printf "CFLAGS: ${CFLAGS}\n" printf "FFLAGS: ${FFLAGS}\n" @@ -47,6 +54,7 @@ else printf "CPATH: ${CPATH}\n" printf "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}\n" printf "LDFLAGS: ${LDFLAGS}\n" + printf "LIBS: ${LIBS}\n" printf "NETCDF_FORTRAN_HOME: ${NETCDF_FORTRAN_HOME}\n" printf "NETCDF_INCLUDE: ${NETCDF_INCLUDE}\n" printf "SKBUILD_CONFIGURE_OPTIONS: ${SKBUILD_CONFIGURE_OPTIONS}\n" diff --git a/cmake/Modules/SetFortranFlags.cmake b/cmake/Modules/SetFortranFlags.cmake index 360edda2b..610a428ec 100644 --- a/cmake/Modules/SetFortranFlags.cmake +++ b/cmake/Modules/SetFortranFlags.cmake @@ -93,6 +93,11 @@ IF (COMPILER_OPTIONS STREQUAL "GNU") SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" Fortran "-ffree-line-length-512" # GNU (gfortran) ) + + # Sets the dialect standard + SET_COMPILE_FLAG(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" + Fortran "-std=f2018" + ) ELSEIF (COMPILER_OPTIONS STREQUAL "Intel") # Disables right margin wrapping in list-directed output IF (WINOPT) @@ -144,19 +149,19 @@ IF (NOT BUILD_SHARED_LIBS AND NOT WINOPT) ENDIF (USE_OPENMP) ELSEIF (COMPILER_OPTIONS STREQUAL "GNU") - # Set GNU static libraries - SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" - Fortran "-static-libgfortran" - ) - SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" - Fortran "-static-libgcc" - ) - SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" - Fortran "-static-libstdc++" - ) - SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" - Fortran "-static-libquadmath" - ) + # # Set GNU static libraries + # SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + # Fortran "-static-libgfortran" + # ) + # SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + # Fortran "-static-libgcc" + # ) + # SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + # Fortran "-static-libstdc++" + # ) + # SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" + # Fortran "-static-libquadmath" + # ) IF (USE_OPENMP) SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 082d881f4..661c72cb8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -168,10 +168,9 @@ IF(USE_COARRAY) ENDIF(USE_COARRAY) # Check to see if the compiler allows for local-spec in do concurrent statements. Set a preprocessor variable if it does -IF (USE_OPENMP) - SET(TESTFILE "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}") - SET(TESTFILE "${TESTFILE}/CMakeTmp/testFortranDoConcurrentLoc.f90") - FILE(WRITE "${TESTFILE}" +SET(TESTFILE "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}") +SET(TESTFILE "${TESTFILE}/CMakeTmp/testFortranDoConcurrentLoc.f90") +FILE(WRITE "${TESTFILE}" " program TestDoConcurrentLoc integer :: i @@ -181,12 +180,31 @@ do concurrent(i = 1:10) shared(a) end do end program TestDoConcurrentLoc ") - TRY_COMPILE(DOCONLOC_WORKS ${CMAKE_BINARY_DIR} ${TESTFILE} - COMPILE_DEFINITIONS "${CMAKE_Fortran_FLAGS}" OUTPUT_VARIABLE OUTPUT) - IF (DOCONLOC_WORKS) - TARGET_COMPILE_DEFINITIONS(${SWIFTEST_DRIVER} PRIVATE -DDOCONLOC) - ENDIF (DOCONLOC_WORKS) -ENDIF (USE_OPENMP) +TRY_COMPILE(DOCONLOC_WORKS ${CMAKE_BINARY_DIR} ${TESTFILE} COMPILE_DEFINITIONS "${CMAKE_Fortran_FLAGS}" OUTPUT_VARIABLE OUTPUT) +IF (DOCONLOC_WORKS) + MESSAGE(STATUS "DO CONCURRENT supports locality-spec") + TARGET_COMPILE_DEFINITIONS(${SWIFTEST_DRIVER} PRIVATE -DDOCONLOC) +ELSE () + MESSAGE(STATUS "DO CONCURRENT does not support locality-spec") +ENDIF (DOCONLOC_WORKS) + +# Check to see if quad precision is supported +SET(TESTFILE "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}") +SET(TESTFILE "${TESTFILE}/CMakeTmp/testFortranQuadPrecisionReal.f90") +FILE(WRITE "${TESTFILE}" +" +program TestQuadPrecisionReal +integer, parameter :: QP = selected_Real_kind(30) +real(QP) :: x +end program TestQuadPrecisionReal +") +TRY_COMPILE(QUADPREC ${CMAKE_BINARY_DIR} ${TESTFILE} COMPILE_DEFINITIONS "${CMAKE_Fortran_FLAGS}" OUTPUT_VARIABLE OUTPUT) +IF (QUADPREC) + MESSAGE(STATUS "Quad precision real is supported") + TARGET_COMPILE_DEFINITIONS(${SWIFTEST_DRIVER} PRIVATE -DQUADPREC) +ELSE () + MESSAGE(STATUS "Quad precision real is not supported") +ENDIF () ##################################### diff --git a/src/coarray/coarray_clone.f90 b/src/coarray/coarray_clone.f90 index 893cff147..ea33f8544 100644 --- a/src/coarray/coarray_clone.f90 +++ b/src/coarray/coarray_clone.f90 @@ -469,6 +469,7 @@ module subroutine coarray_component_clone_lgt_arr1D(var,src_img) end subroutine coarray_component_clone_lgt_arr1D +#ifdef QUADPREC module subroutine coarray_component_clone_QP(var,src_img) !! author: David A. Minton !! @@ -503,5 +504,6 @@ module subroutine coarray_component_clone_QP(var,src_img) return end subroutine coarray_component_clone_QP +#endif end submodule s_coarray_clone \ No newline at end of file diff --git a/src/coarray/coarray_module.f90 b/src/coarray/coarray_module.f90 index b034f8786..22ce10c55 100644 --- a/src/coarray/coarray_module.f90 +++ b/src/coarray/coarray_module.f90 @@ -71,11 +71,13 @@ module subroutine coarray_component_clone_lgt_arr1D(var,src_img) integer(I4B), intent(in),optional :: src_img end subroutine coarray_component_clone_lgt_arr1D +#ifdef QUADPREC module subroutine coarray_component_clone_QP(var,src_img) implicit none real(QP), intent(inout) :: var integer(I4B), intent(in),optional :: src_img end subroutine coarray_component_clone_QP +#endif end interface diff --git a/src/globals/globals_module.f90 b/src/globals/globals_module.f90 index 183c21b09..ece47b07f 100644 --- a/src/globals/globals_module.f90 +++ b/src/globals/globals_module.f90 @@ -24,7 +24,11 @@ module globals integer, parameter :: SP = real32 !! Symbolic name for kind types of single-precision reals integer, parameter :: DP = real64 !! Symbolic name for kind types of double-precision reals - integer, parameter :: QP = real128 !! Symbolic name for kind types of quad-precision reals +#ifdef QUADPREC + integer, parameter :: QP = selected_Real_kind(30) !! Symbolic name for kind types of quad-precision reals +#else + integer, parameter :: QP = real64 !! Stick to DP +#endif real(DP), parameter :: PIBY2 = 1.570796326794896619231321691639751442099_DP !! Definition of /(\pi / 2\) real(DP), parameter :: PI = 3.141592653589793238462643383279502884197_DP !! Definition of /(\pi\) diff --git a/src/globals/globals_module.f90.in b/src/globals/globals_module.f90.in index 8d107af1e..ef22ab97a 100644 --- a/src/globals/globals_module.f90.in +++ b/src/globals/globals_module.f90.in @@ -24,7 +24,11 @@ module globals integer, parameter :: SP = real32 !! Symbolic name for kind types of single-precision reals integer, parameter :: DP = real64 !! Symbolic name for kind types of double-precision reals - integer, parameter :: QP = real128 !! Symbolic name for kind types of quad-precision reals +#ifdef QUADPREC + integer, parameter :: QP = selected_Real_kind(30) !! Symbolic name for kind types of quad-precision reals +#else + integer, parameter :: QP = real64 !! Stick to DP +#endif real(DP), parameter :: PIBY2 = 1.570796326794896619231321691639751442099_DP !! Definition of /(\pi / 2\) real(DP), parameter :: PI = 3.141592653589793238462643383279502884197_DP !! Definition of /(\pi\) diff --git a/src/misc/solver_module.f90 b/src/misc/solver_module.f90 index 872db6428..81f2cab40 100644 --- a/src/misc/solver_module.f90 +++ b/src/misc/solver_module.f90 @@ -20,7 +20,9 @@ module solver interface solve_linear_system module procedure solve_linear_system_dp +#ifdef QUADPREC module procedure solve_linear_system_qp +#endif end interface interface solve_roots @@ -81,7 +83,7 @@ function solve_linear_system_dp(A,b,n,lerr) result(x) return end function solve_linear_system_dp - +#ifdef QUADPREC function solve_linear_system_qp(A,b,n,lerr) result(x) !! Author: David A. Minton !! @@ -115,7 +117,7 @@ function solve_linear_system_qp(A,b,n,lerr) result(x) return end function solve_linear_system_qp - +#endif function solve_wbs(u) result(x) ! solve with backward substitution !! Based on code available on Rosetta Code: https://rosettacode.org/wiki/Gaussian_elimination#Fortran diff --git a/src/operator/operator_cross.f90 b/src/operator/operator_cross.f90 index 72c24a176..3ca3e28cf 100644 --- a/src/operator/operator_cross.f90 +++ b/src/operator/operator_cross.f90 @@ -42,6 +42,7 @@ pure module function operator_cross_dp(A, B) result(C) return end function operator_cross_dp +#ifdef QUADPREC pure module function operator_cross_qp(A, B) result(C) implicit none real(QP), dimension(:), intent(in) :: A, B @@ -53,6 +54,7 @@ pure module function operator_cross_qp(A, B) result(C) C(3) = A(1) * B(2) - A(2) * B(1) return end function operator_cross_qp +#endif pure module function operator_cross_i1b(A, B) result(C) implicit none @@ -124,6 +126,7 @@ pure module function operator_cross_el_dp(A, B) result(C) return end function operator_cross_el_dp +#ifdef QUADPREC pure module function operator_cross_el_qp(A, B) result(C) implicit none real(QP), dimension(:,:), intent(in) :: A, B @@ -137,6 +140,7 @@ pure module function operator_cross_el_qp(A, B) result(C) end do return end function operator_cross_el_qp +#endif pure module function operator_cross_el_i1b(A, B) result(C) implicit none diff --git a/src/operator/operator_mag.f90 b/src/operator/operator_mag.f90 index 721e4a930..5c3d6538e 100644 --- a/src/operator/operator_mag.f90 +++ b/src/operator/operator_mag.f90 @@ -65,6 +65,7 @@ pure module function operator_mag_el_dp(A) result(B) return end function operator_mag_el_dp +#ifdef QUADPREC pure module function operator_mag_el_qp(A) result(B) implicit none real(QP), dimension(:,:), intent(in) :: A @@ -79,6 +80,7 @@ pure module function operator_mag_el_qp(A) result(B) end do return end function operator_mag_el_qp +#endif end submodule s_operator_mag diff --git a/src/operator/operator_module.f90 b/src/operator/operator_module.f90 index 8c351236b..93879117a 100644 --- a/src/operator/operator_module.f90 +++ b/src/operator/operator_module.f90 @@ -37,12 +37,14 @@ pure module function operator_cross_dp(A, B) result(C) real(DP), dimension(NDIM) :: C end function operator_cross_dp +#ifdef QUADPREC pure module function operator_cross_qp(A, B) result(C) !$omp declare simd(operator_cross_qp) implicit none real(QP), dimension(:), intent(in) :: A, B real(QP), dimension(NDIM) :: C end function operator_cross_qp +#endif pure module function operator_cross_i1b(A, B) result(C) !$omp declare simd(operator_cross_i1b) @@ -84,11 +86,13 @@ pure module function operator_cross_el_dp(A, B) result(C) real(DP), dimension(:,:), allocatable :: C end function operator_cross_el_dp +#ifdef QUADPREC pure module function operator_cross_el_qp(A, B) result(C) implicit none real(QP), dimension(:,:), intent(in) :: A, B real(QP), dimension(:,:), allocatable :: C end function operator_cross_el_qp +#endif pure module function operator_cross_el_i1b(A, B) result(C) implicit none @@ -134,13 +138,14 @@ pure module function operator_mag_dp(A) result(B) real(DP) :: B end function operator_mag_dp +#ifdef QUADPREC pure module function operator_mag_qp(A) result(B) !$omp declare simd(operator_mag_qp) implicit none real(QP), dimension(:), intent(in) :: A real(QP) :: B end function operator_mag_qp - +#endif pure module function operator_mag_el_sp(A) result(B) implicit none real(SP), dimension(:,:), intent(in) :: A @@ -153,11 +158,14 @@ pure module function operator_mag_el_dp(A) result(B) real(DP), dimension(:), allocatable :: B end function operator_mag_el_dp +#ifdef QUADPREC pure module function operator_mag_el_qp(A) result(B) implicit none real(QP), dimension(:,:), intent(in) :: A real(QP), dimension(:), allocatable :: B end function operator_mag_el_qp +#endif + end interface @@ -180,12 +188,14 @@ pure module function operator_unit_dp(A) result(B) real(DP), dimension(NDIM) :: B end function operator_unit_dp +#ifdef QUADPREC pure module function operator_unit_qp(A) result(B) !$omp declare simd(operator_unit_qp) implicit none real(QP), dimension(:), intent(in) :: A real(QP), dimension(NDIM) :: B end function operator_unit_qp +#endif pure module function operator_unit_el_sp(A) result(B) implicit none @@ -199,11 +209,13 @@ pure module function operator_unit_el_dp(A) result(B) real(DP), dimension(:,:), allocatable :: B end function operator_unit_el_dp +#ifdef QUADPREC pure module function operator_unit_el_qp(A) result(B) implicit none real(QP), dimension(:,:), intent(in) :: A real(QP), dimension(:,:), allocatable :: B end function operator_unit_el_qp +#endif end interface diff --git a/src/operator/operator_unit.f90 b/src/operator/operator_unit.f90 index 2a14f6645..067df74eb 100644 --- a/src/operator/operator_unit.f90 +++ b/src/operator/operator_unit.f90 @@ -56,7 +56,7 @@ pure module function operator_unit_dp(A) result(B) return end function operator_unit_dp - +#ifdef QUADPREC pure module function operator_unit_qp(A) result(B) implicit none ! Arguments @@ -75,7 +75,7 @@ pure module function operator_unit_qp(A) result(B) return end function operator_unit_qp - +#endif pure module function operator_unit_el_sp(A) result(B) implicit none @@ -116,6 +116,7 @@ pure module function operator_unit_el_dp(A) result(B) return end function operator_unit_el_dp +#ifdef QUADPREC pure module function operator_unit_el_qp(A) result(B) implicit none ! Arguments @@ -134,6 +135,7 @@ pure module function operator_unit_el_qp(A) result(B) return end function operator_unit_el_qp +#endif end submodule s_operator_unit diff --git a/src/swiftest/swiftest_io.f90 b/src/swiftest/swiftest_io.f90 index 9eb3bed2c..9a8095116 100644 --- a/src/swiftest/swiftest_io.f90 +++ b/src/swiftest/swiftest_io.f90 @@ -2774,7 +2774,7 @@ module subroutine swiftest_io_param_writer_one_logical(param_name, param_value, return end subroutine swiftest_io_param_writer_one_logical - +#ifdef QUADPREC module subroutine swiftest_io_param_writer_one_QP(param_name, param_value, unit) !! author: David A. Minton !! @@ -2794,7 +2794,7 @@ module subroutine swiftest_io_param_writer_one_QP(param_name, param_value, unit) return end subroutine swiftest_io_param_writer_one_QP - +#endif module subroutine swiftest_io_read_in_body(self, param) !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott diff --git a/src/swiftest/swiftest_module.f90 b/src/swiftest/swiftest_module.f90 index 7437c49bc..acddf4d04 100644 --- a/src/swiftest/swiftest_module.f90 +++ b/src/swiftest/swiftest_module.f90 @@ -850,12 +850,14 @@ module subroutine swiftest_io_param_writer_one_logical(param_name, param_value, integer(I4B), intent(in) :: unit !! Open file unit number to print parameter to end subroutine swiftest_io_param_writer_one_logical +#ifdef QUADPREC module subroutine swiftest_io_param_writer_one_QP(param_name, param_value, unit) implicit none character(len=*), intent(in) :: param_name !! Name of parameter to print real(QP), intent(in) :: param_value !! Value of parameter to print integer(I4B), intent(in) :: unit !! Open file unit number to print parameter to end subroutine swiftest_io_param_writer_one_QP +#endif end interface io_param_writer_one interface diff --git a/src/swiftest/swiftest_util.f90 b/src/swiftest/swiftest_util.f90 index 6659bf69e..94813be38 100644 --- a/src/swiftest/swiftest_util.f90 +++ b/src/swiftest/swiftest_util.f90 @@ -3331,22 +3331,22 @@ module subroutine swiftest_util_version() !! Adapted from David E. Kaufmann's Swifter routine: util_version.f90 implicit none write(*, 200) VERSION - 200 format(/, "************* Swiftest: Version ", f3.1, " *************", //, & - "Based off of Swifter:", //, & - "Authors:", //, & - " The Purdue University Swiftest Development team ", /, & - " Lead by David A. Minton ", /, & - " Carlisle Wishard, Jennifer Pouplin, Jacob Elliott, Dana Singh." & - "Please address comments and questions to:", //, & - " David A. Minton", /, & - " Department Earth, Atmospheric, & Planetary Sciences ",/, & - " Purdue University", /, & - " 550 Stadium Mall Drive", /, & - " West Lafayette, Indiana 47907", /, & - " 765-250-8034 ", /, & - " daminton@purdue.edu", /, & - "Special thanks to Hal Levison and Martin Duncan for the original",/,& - "SWIFTER and SWIFT codes that made this possible.", //, & + 200 format(/, "************* Swiftest: Version ", f3.1, " *************",/, & + "Based off of Swifter:",/, & + "Authors:",/, & + " The Purdue University Swiftest Development team ",/, & + " Lead by David A. Minton ",/, & + " Carlisle Wishard, Jennifer Pouplin, Jacob Elliott, Dana Singh.",/,& + "Please address comments and questions to:",/, & + " David A. Minton",/, & + " Department Earth, Atmospheric, & Planetary Sciences ",/, & + " Purdue University",/, & + " 550 Stadium Mall Drive",/, & + " West Lafayette, Indiana 47907", /, & + " 765-494-3292 ",/, & + " daminton@purdue.edu",/, & + "Special thanks to Hal Levison, Martin Duncan, and David Kaufmann",/, & + "for the original SWIFTER and SWIFT codes that made this possible.",/, & "************************************************", /) From 2c5b37763c046495f4e5f395a272fd79f8c7829e Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Wed, 30 Aug 2023 12:14:02 -0400 Subject: [PATCH 06/22] Made several changes to get a working version of the code on MacOS 11.0. Switched back to a shared library build for portability --- buildscripts/_build_getopts.sh | 24 +++++++++--- buildscripts/build_all.sh | 22 ----------- buildscripts/build_hdf5.sh | 5 ++- buildscripts/build_netcdf-c.sh | 11 +++--- buildscripts/build_netcdf-fortran.sh | 5 ++- buildscripts/build_swiftest.sh | 9 +++-- buildscripts/build_zlib.sh | 5 ++- buildscripts/set_compilers.sh | 56 +--------------------------- pyproject.toml | 11 +----- 9 files changed, 43 insertions(+), 105 deletions(-) delete mode 100755 buildscripts/build_all.sh diff --git a/buildscripts/_build_getopts.sh b/buildscripts/_build_getopts.sh index 9ccfde135..3d82f380e 100755 --- a/buildscripts/_build_getopts.sh +++ b/buildscripts/_build_getopts.sh @@ -14,10 +14,19 @@ SCRIPT_DIR=$(realpath $(dirname $0)) ROOT_DIR=$(realpath ${SCRIPT_DIR}/..) # Parse arguments -USTMT="Usage: ${0} <-d /path/to/dependency/source> [-p /prefix/path|{/usr/local}] [-m MACOSX_DEPLOYMENT_TARGET|{10.9}]" -PREFIX=/usr/local -DEPENDENCY_DIR="${ROOT_DIR}/_dependencies" -MACOSX_DEPLOYMENT_TARGET="10.9" +USTMT="Usage: ${0} [-d /path/to/dependency/source] [-p /prefix/path] [-m MACOSX_DEPLOYMENT_TARGET|{11.0}]" +MACOSX_DEPLOYMENT_TARGET="11.0" + +read -r OS ARCH < <($SCRIPT_DIR/get_platform.sh) +BUILD_DIR=${BUILD_DIR:-$(mktemp -ut swiftest_build)} +if [ $OS = "MacOSX" ]; then + PREFIX=${PREFIX:-${BUILD_DIR}/${OS}${MACOSX_DEPLOYMENT_TARGET}/${ARCH}} +else + PREFIX=${PREFIX:-${BUILD_DIR}/${OS}/${ARCH}} +fi + +DEPENDENCY_DIR=${DEPENDENCY_DIR:-${BUILD_DIR}/downloads} + while getopts ":d:p:m:h" ARG; do case "${ARG}" in d) @@ -45,7 +54,12 @@ while getopts ":d:p:m:h" ARG; do esac done -read -r OS ARCH < <($SCRIPT_DIR/get_platform.sh) +if [ $OS = "MacOSX" ]; then + printf "MACOSX_DEPLOYMENT_TARGET: ${MACOSX_DEPLOYMENT_TARGET}\n" +fi +printf "DEPENDENCY_DIR: ${DEPENDENCY_DIR}\n" +printf "PREFIX : ${PREFIX}\n" + if [ -z ${DEPENDENCY_ENV_VARS+x} ]; then . ${SCRIPT_DIR}/set_compilers.sh diff --git a/buildscripts/build_all.sh b/buildscripts/build_all.sh deleted file mode 100755 index d93933abe..000000000 --- a/buildscripts/build_all.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# This script will generate cross-platform wheels for the Swiftest Python package using Docker. If it is called from MacOS it will -# also generate a Mac build. -# -# Copyright 2023 - David Minton -# This file is part of Swiftest. -# Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -# Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -# You should have received a copy of the GNU General Public License along with Swiftest. -# If not, see: https://www.gnu.org/licenses. - -# Determine the platform and architecture -set -a -SCRIPT_DIR=$(realpath $(dirname $0)) -ARGS=$@ -. ${SCRIPT_DIR}/_build_getopts.sh ${ARGS} - -set -e -${SCRIPT_DIR}/build_dependencies.sh ${ARGS} -${SCRIPT_DIR}/build_swiftest.sh ${ARGS} \ No newline at end of file diff --git a/buildscripts/build_hdf5.sh b/buildscripts/build_hdf5.sh index 9f170e0a1..fffd91b47 100755 --- a/buildscripts/build_hdf5.sh +++ b/buildscripts/build_hdf5.sh @@ -17,7 +17,7 @@ ARGS=$@ printf "\n" printf "*********************************************************\n" -printf "* BUILDING HDF5 STATIC LIBRARY *\n" +printf "* BUILDING HDF5 LIBRARY *\n" printf "*********************************************************\n" printf "LIBS: ${LIBS}\n" printf "CFLAGS: ${CFLAGS}\n" @@ -35,7 +35,8 @@ if [ $OS = "MacOSX" ]; then printf "echo arm-apple-darwin" > bin/config.sub fi fi -COPTS="--disable-shared --enable-build-mode=production --enable-tests=no --enable-tools=no --disable-fortran --disable-java --disable-cxx --prefix=${PREFIX} --with-zlib=${PREFIX}" +#COPTS="--disable-shared --enable-build-mode=production --enable-tests=no --enable-tools=no --disable-fortran --disable-java --disable-cxx --prefix=${PREFIX} --with-zlib=${PREFIX}" +COPTS="--enable-build-mode=production --enable-tests=no --enable-tools=no --disable-fortran --disable-java --disable-cxx --prefix=${PREFIX} --with-zlib=${PREFIX}" ./configure ${COPTS} make if [ -w ${PREFIX} ]; then diff --git a/buildscripts/build_netcdf-c.sh b/buildscripts/build_netcdf-c.sh index 82bc78380..9fe7a913e 100755 --- a/buildscripts/build_netcdf-c.sh +++ b/buildscripts/build_netcdf-c.sh @@ -18,7 +18,7 @@ ARGS=$@ printf "\n" printf "*********************************************************\n" -printf "* BUILDING NETCDF-C STATIC LIBRARY *\n" +printf "* BUILDING NETCDF-C LIBRARY *\n" printf "*********************************************************\n" printf "LIBS: ${LIBS}\n" printf "CFLAGS: ${CFLAGS}\n" @@ -30,10 +30,11 @@ printf "HDF5_ROOT: ${HDF5_ROOT}\n" printf "*********************************************************\n" cd ${DEPENDENCY_DIR}/netcdf-c-* -COPTS="--disable-shared --disable-dap --disable-byterange --disable-testsets --prefix=${PREFIX}" -if [ ! $OS = "MacOSX" ]; then - COPTS="${COPTS} --disable-libxml2" -fi +#COPTS="--disable-shared --disable-dap --disable-byterange --disable-testsets --prefix=${PREFIX}" +COPTS="--disable-testsets --prefix=${PREFIX}" +#if [ ! $OS = "MacOSX" ]; then +# COPTS="${COPTS} --disable-libxml2" +#fi printf "COPTS: ${COPTS}\n" ./configure $COPTS make && make check diff --git a/buildscripts/build_netcdf-fortran.sh b/buildscripts/build_netcdf-fortran.sh index 9e9a877cd..cb2ad8a8e 100755 --- a/buildscripts/build_netcdf-fortran.sh +++ b/buildscripts/build_netcdf-fortran.sh @@ -19,7 +19,7 @@ LIBS="$(${PREFIX}/bin/nc-config --libs --static)" printf "\n" printf "*********************************************************\n" -printf "* BUILDING NETCDF-FORTRAN STATIC LIBRARY *\n" +printf "* BUILDING NETCDF-FORTRAN LIBRARY *\n" printf "*********************************************************\n" printf "LIBS: ${LIBS}\n" printf "CFLAGS: ${CFLAGS}\n" @@ -30,7 +30,8 @@ printf "LDFLAGS: ${LDFLAGS}\n" printf "*********************************************************\n" cd ${DEPENDENCY_DIR}/netcdf-fortran-* -./configure --disable-shared --with-pic --disable-zstandard-plugin --enable-large-file-tests=no --enable-filter-test=no --prefix=${PREFIX} +#./configure --disable-shared --with-pic --disable-zstandard-plugin --enable-large-file-tests=no --enable-filter-test=no --prefix=${PREFIX} +./configure --enable-large-file-tests=no --enable-filter-test=no --prefix=${PREFIX} make && make check i if [ -w ${PREFIX} ]; then make install diff --git a/buildscripts/build_swiftest.sh b/buildscripts/build_swiftest.sh index b3e3cdc87..41411762a 100755 --- a/buildscripts/build_swiftest.sh +++ b/buildscripts/build_swiftest.sh @@ -13,6 +13,7 @@ set -a if [ -z ${SCRIPT_DIR+x} ]; then SCRIPT_DIR=$(realpath $(dirname $0)); fi ARGS=$@ . ${SCRIPT_DIR}/_build_getopts.sh ${ARGS} +ARGS="-p ${PREFIX} -d ${DEPENDENCY_DIR} -m ${MACOSX_DEPLOYMENT_TARGET}" # Determine if we are in the correct directory (the script can either be run from the Swiftest project root directory or the # buildscripts directory) @@ -27,18 +28,20 @@ echo $OS $ARCH printf "Using ${OS} compilers:\nFC: ${FC}\nCC: ${CC}\nCXX: ${CXX}\n\n" printf "Installing to ${PREFIX}\n" printf "Dependency libraries in ${PREFIX}\n" +${SCRIPT_DIR}/build_dependencies.sh ${ARGS} if [ $OS = "Linux" ]; then cibuildwheel --platform linux else - SKBUILD_CONFIGURE_OPTIONS="-DBUILD_SHARED_LIBS=OFF" + SKBUILD_CONFIGURE_OPTIONS="-DBUILD_SHARED_LIBS=ON -DUSE_SIMD=OFF" SKBUILD_CONFIGURE_OPTIONS="${SKBUILD_CONFIGURE_OPTIONS} -DMACHINE_CODE_VALUE=\"generic\"" OMPROOT=${DEVTOOLDIR}/MacOSX${MACOSX_DEPLOYMENT_TARGET}/${ARCH}/usr/local CPPFLAGS="${CPPFLAGS} -Xclang -fopenmp" LIBS="${LIBS} -lomp" - LDFLAGS="-Wl,-rpath,${OMPROOT}/lib" + LDFLAGS="-Wl,-rpath,${OMPROOT}/lib -Wl,-rpath,${ROOT_DIR}/lib" CPATH="${OMPROOT}/include:${CPATH}" - LD_LIBRARY_PATH="${OMPROOT}/lib:${LD_LIBRARY_PATH}" + LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" + LIBRARY_PATH="${LD_LIBRARY_PATH}" cd $ROOT_DIR printf "\n" diff --git a/buildscripts/build_zlib.sh b/buildscripts/build_zlib.sh index d65cad4f6..928d07fe3 100755 --- a/buildscripts/build_zlib.sh +++ b/buildscripts/build_zlib.sh @@ -16,7 +16,7 @@ ARGS=$@ . ${SCRIPT_DIR}/_build_getopts.sh ${ARGS} printf "*********************************************************\n" -printf "* BUILDING ZLIB STATIC LIBRARY *\n" +printf "* BUILDING ZLIB LIBRARY *\n" printf "*********************************************************\n" printf "LIBS: ${LIBS}\n" printf "CFLAGS: ${CFLAGS}\n" @@ -27,7 +27,8 @@ printf "LDFLAGS: ${LDFLAGS}\n" printf "*********************************************************\n" cd ${DEPENDENCY_DIR}/zlib-* -./configure --prefix=${PREFIX} --static +#./configure --prefix=${PREFIX} --static +./configure --prefix=${PREFIX} make if [ -w ${PREFIX} ]; then make install diff --git a/buildscripts/set_compilers.sh b/buildscripts/set_compilers.sh index 10d3fac67..fff90cba5 100755 --- a/buildscripts/set_compilers.sh +++ b/buildscripts/set_compilers.sh @@ -15,7 +15,7 @@ # If not, see: https://www.gnu.org/licenses. # Parse arguments case "$OS" in - Intel|Linux|MacOSX) + Linux|MacOSX) ;; *) echo "Unknown compiler type: $OS" @@ -28,60 +28,6 @@ esac set -a # Only replace compiler definitions if they are not already set case $OS in - Intel) - if [ ! -v FC ]; then - if command -v ifx &> /dev/null; then - FC=$(command -v ifx) - elif command -v ifort &> /dev/null; then - FC=$(command -v mpiifort) - else - printf "Error. Cannot find valid Intel Fortran compiler.\n" - exit 1 - fi - fi - if [ ! -v F77 ]; then - F77="${FC}" - fi - - if [ ! -v CC ]; then - if command -v icx &> /dev/null; then - CC=$(command -v icx) - elif command -v icc &> /dev/null; then - CC=$(command -v icc) - else - printf "Error. Cannot find valid Intel C compiler.\n" - exit 1 - fi - fi - - if [ ! -v CXX ]; then - if command -v icpx &> /dev/null; then - CXX=$(command -v icpx) - elif command -v icpc &> /dev/null; then - CXX=$(command -v icpc) - else - printf "Error. Cannot find valid Intel C++ compiler.\n" - exit 1 - fi - fi - - if command -v mpiifort &> /dev/null; then - I_MPI_F90=${FC} - FC=$(command -v mpiifort) - fi - - if command -v mpiicc &> /dev/null; then - I_MPI_CC =${CC} - CC=$(command -v mpiicc) - fi - - if command -v mpiicpc &> /dev/null; then - I_MPI_CXX =${CXX} - CXX=$(command -v mpiicpc) - fi - - CPP=${CPP:-$HOMEBRE_PREFIX/bin/cpp-13} - ;; Linux) FC=${FC:-$(command -v gfortran)} CC=${CC:-$(command -v gcc)} diff --git a/pyproject.toml b/pyproject.toml index d81ff9775..c8bb85fb8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ requires = [ build-backend = "setuptools.build_meta" [tool.cibuildwheel] -environment = {SKBUILD_CONFIGURE_OPTIONS="-DBUILD_SHARED_LIBS=OFF"} +environment = {SKBUILD_CONFIGURE_OPTIONS="-DBUILD_SHARED_LIBS=ON"} test-command = "pytest {package}/tests" test-requires = ['pytest','cython'] test-skip = "cp312-*" @@ -20,12 +20,5 @@ skip = "pp* *i686 *-manylinux_i686 *_ppc64le *_s390x *-musllinux* *-win32" environment = {FFLAGS="${FFLAGS} -fPIC", CFLAGS="${CFLAGS} -fPIC", LDFLAGS="${LDFLAGS} -fPIE", LIBS="-lgomp"} before-all = [ "yum install doxygen -y || apt-get install doxygen -y", - "buildscripts/build_dependencies.sh -d /_dependencies -p /usr/local", + "buildscripts/build_dependencies.sh -p /usr/local", ] - -[tool.cibuildwheel.macos] -before-all = [ - "buildscripts/build_dependencies.sh -d ${TMPDIR} -p ${TMPDIR} -m ${MACOSX_DEPLOYMENT_TARGET}" -] - - \ No newline at end of file From 0d7c71270ac1a9755e704d0281df6fe60cc91c7b Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Wed, 30 Aug 2023 14:16:27 -0400 Subject: [PATCH 07/22] More changes to improve the robustness of the buildscripts --- buildscripts/_build_getopts.sh | 23 ++++++++++------------- buildscripts/build_swiftest.sh | 3 +++ buildscripts/set_compilers.sh | 15 +++++++++++++-- pyproject.toml | 2 +- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/buildscripts/_build_getopts.sh b/buildscripts/_build_getopts.sh index 3d82f380e..f9356684a 100755 --- a/buildscripts/_build_getopts.sh +++ b/buildscripts/_build_getopts.sh @@ -14,18 +14,8 @@ SCRIPT_DIR=$(realpath $(dirname $0)) ROOT_DIR=$(realpath ${SCRIPT_DIR}/..) # Parse arguments -USTMT="Usage: ${0} [-d /path/to/dependency/source] [-p /prefix/path] [-m MACOSX_DEPLOYMENT_TARGET|{11.0}]" -MACOSX_DEPLOYMENT_TARGET="11.0" - -read -r OS ARCH < <($SCRIPT_DIR/get_platform.sh) -BUILD_DIR=${BUILD_DIR:-$(mktemp -ut swiftest_build)} -if [ $OS = "MacOSX" ]; then - PREFIX=${PREFIX:-${BUILD_DIR}/${OS}${MACOSX_DEPLOYMENT_TARGET}/${ARCH}} -else - PREFIX=${PREFIX:-${BUILD_DIR}/${OS}/${ARCH}} -fi - -DEPENDENCY_DIR=${DEPENDENCY_DIR:-${BUILD_DIR}/downloads} +USTMT="Usage: ${0} [-d /path/to/dependency/source] [-p /prefix/path] [-m MACOSX_DEPLOYMENT_TARGET]" +MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET:-"11.0"} while getopts ":d:p:m:h" ARG; do case "${ARG}" in @@ -54,13 +44,20 @@ while getopts ":d:p:m:h" ARG; do esac done +read -r OS ARCH < <($SCRIPT_DIR/get_platform.sh) +BUILD_DIR=${BUILD_DIR:-$(mktemp -ut swiftest_build)} if [ $OS = "MacOSX" ]; then printf "MACOSX_DEPLOYMENT_TARGET: ${MACOSX_DEPLOYMENT_TARGET}\n" + PREFIX=${PREFIX:-${BUILD_DIR}/${OS}${MACOSX_DEPLOYMENT_TARGET}/${ARCH}} +else + PREFIX=${PREFIX:-${BUILD_DIR}/${OS}/${ARCH}} fi + +DEPENDENCY_DIR=${DEPENDENCY_DIR:-${BUILD_DIR}/downloads} + printf "DEPENDENCY_DIR: ${DEPENDENCY_DIR}\n" printf "PREFIX : ${PREFIX}\n" - if [ -z ${DEPENDENCY_ENV_VARS+x} ]; then . ${SCRIPT_DIR}/set_compilers.sh diff --git a/buildscripts/build_swiftest.sh b/buildscripts/build_swiftest.sh index 41411762a..7cc9130ff 100755 --- a/buildscripts/build_swiftest.sh +++ b/buildscripts/build_swiftest.sh @@ -28,8 +28,11 @@ echo $OS $ARCH printf "Using ${OS} compilers:\nFC: ${FC}\nCC: ${CC}\nCXX: ${CXX}\n\n" printf "Installing to ${PREFIX}\n" printf "Dependency libraries in ${PREFIX}\n" +read -rsn1 -p"Press any key to continue";echo + ${SCRIPT_DIR}/build_dependencies.sh ${ARGS} + if [ $OS = "Linux" ]; then cibuildwheel --platform linux else diff --git a/buildscripts/set_compilers.sh b/buildscripts/set_compilers.sh index fff90cba5..f0588f935 100755 --- a/buildscripts/set_compilers.sh +++ b/buildscripts/set_compilers.sh @@ -42,8 +42,19 @@ case $OS in AR=${AR:-${COMPILER_PREFIX}/bin/ar} NM=${NM:-${COMPILER_PREFIX}/bin/nm} RANLIB=${RANLIB:-${COMPILER_PREFIX}/bin/ranlib} - FC=${FC:-$(command -v gfortran)} - FROOT=$(realpath $(dirname $(command -v $FC))/..) + + # Use custom gfortran location for a given MacOS Target version if vailable + FROOT=${DEVTOOLDIR}/MacOSX${MACOSX_DEPLOYMENT_TARGET}/${ARCH}/usr/local + if [ -f ${FROOT}/bin/gfortran ]; then + FC=${FROOT}/bin/gfortran + else + FC=${FC:-$(command -v gfortran)} + FROOT=$(realpath $(dirname $(command -v $FC))/..) + fi + if [ ! -f ${FC} ]; then + printf "No working fortran compiler found!\n" + exit 1 + fi LD_LIBRARY_PATH="${COMPILER_PREFIX}/lib:${FROOT}/lib:${LD_LIBRARY_PATH}" LDFLAGS="${LDFLAGS} -Wl,-rpath,${COMPILER_PREFIX}/lib -Wl,-no_compact_unwind" CPPFLAGS="${CPPFLAGS} -isystem ${COMPILER_PREFIX}/include" diff --git a/pyproject.toml b/pyproject.toml index c8bb85fb8..0a7efb357 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ requires = [ build-backend = "setuptools.build_meta" [tool.cibuildwheel] -environment = {SKBUILD_CONFIGURE_OPTIONS="-DBUILD_SHARED_LIBS=ON"} +environment = {SKBUILD_CONFIGURE_OPTIONS="-DBUILD_SHARED_LIBS=ON -DUSE_SIMD=OFF"} test-command = "pytest {package}/tests" test-requires = ['pytest','cython'] test-skip = "cp312-*" From 4ac2275ac31edb928c2103a0f46c6a44231d5b14 Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Wed, 30 Aug 2023 16:29:30 -0400 Subject: [PATCH 08/22] More tweaks to the build scripts to get the right libraries into the right place --- buildscripts/build_dependencies.sh | 30 ++++++---------------------- buildscripts/build_hdf5.sh | 3 ++- buildscripts/build_netcdf-c.sh | 5 +---- buildscripts/build_netcdf-fortran.sh | 3 ++- buildscripts/build_swiftest.sh | 9 ++++++++- buildscripts/build_zlib.sh | 2 +- 6 files changed, 20 insertions(+), 32 deletions(-) diff --git a/buildscripts/build_dependencies.sh b/buildscripts/build_dependencies.sh index f1eb625c3..5fc544450 100755 --- a/buildscripts/build_dependencies.sh +++ b/buildscripts/build_dependencies.sh @@ -67,33 +67,15 @@ printf "Installing to ${PREFIX}\n" printf "\n" set -e -if [ ! -f ${PREFIX}/lib/libz.a ]; then - ${SCRIPT_DIR}/build_zlib.sh ${ARGS} -else - echo "Found: ${PREFIX}/lib/libz.a" -fi - -if [ ! -f ${PREFIX}/lib/libhdf5.a ]; then - ${SCRIPT_DIR}/build_hdf5.sh ${ARGS} -else - echo "Found: ${PREFIX}/lib/libhdf5.a" -fi - - -if [ ! -f ${PREFIX}/lib/libnetcdf.a ]; then - ${SCRIPT_DIR}/build_netcdf-c.sh ${ARGS} -else - echo "Found: ${PREFIX}/lib/libnetcdf.a" -fi - -if [ ! -f ${PREFIX}/lib/libnetcdff.a ]; then - ${SCRIPT_DIR}/build_netcdf-fortran.sh ${ARGS} -else - echo "Found: ${PREFIX}/lib/libnetcdff.a" -fi +${SCRIPT_DIR}/build_zlib.sh ${ARGS} +${SCRIPT_DIR}/build_hdf5.sh ${ARGS} +${SCRIPT_DIR}/build_netcdf-c.sh ${ARGS} +${SCRIPT_DIR}/build_netcdf-fortran.sh ${ARGS} printf "\n" printf "*********************************************************\n" printf "* DEPENDENCIES ARE BUILT *\n" printf "*********************************************************\n" printf "Dependencys are installed to: ${PREFIX}\n\n" + + diff --git a/buildscripts/build_hdf5.sh b/buildscripts/build_hdf5.sh index fffd91b47..072c7b689 100755 --- a/buildscripts/build_hdf5.sh +++ b/buildscripts/build_hdf5.sh @@ -35,7 +35,6 @@ if [ $OS = "MacOSX" ]; then printf "echo arm-apple-darwin" > bin/config.sub fi fi -#COPTS="--disable-shared --enable-build-mode=production --enable-tests=no --enable-tools=no --disable-fortran --disable-java --disable-cxx --prefix=${PREFIX} --with-zlib=${PREFIX}" COPTS="--enable-build-mode=production --enable-tests=no --enable-tools=no --disable-fortran --disable-java --disable-cxx --prefix=${PREFIX} --with-zlib=${PREFIX}" ./configure ${COPTS} make @@ -45,6 +44,8 @@ else sudo make install fi +rsync -va ${PREFIX}/lib/libhdf5* ${ROOT_DIR}/lib/ + if [ $? -ne 0 ]; then printf "hdf5 could not be compiled.\n" exit 1 diff --git a/buildscripts/build_netcdf-c.sh b/buildscripts/build_netcdf-c.sh index 9fe7a913e..fc17313c6 100755 --- a/buildscripts/build_netcdf-c.sh +++ b/buildscripts/build_netcdf-c.sh @@ -30,11 +30,7 @@ printf "HDF5_ROOT: ${HDF5_ROOT}\n" printf "*********************************************************\n" cd ${DEPENDENCY_DIR}/netcdf-c-* -#COPTS="--disable-shared --disable-dap --disable-byterange --disable-testsets --prefix=${PREFIX}" COPTS="--disable-testsets --prefix=${PREFIX}" -#if [ ! $OS = "MacOSX" ]; then -# COPTS="${COPTS} --disable-libxml2" -#fi printf "COPTS: ${COPTS}\n" ./configure $COPTS make && make check @@ -44,6 +40,7 @@ if [ -w ${PREFIX} ]; then else sudo make install fi +rsync -va ${PREFIX}/lib/libnetcdf* ${ROOT_DIR}/lib/ if [ $? -ne 0 ]; then printf "netcdf-c could not be compiled."\n diff --git a/buildscripts/build_netcdf-fortran.sh b/buildscripts/build_netcdf-fortran.sh index cb2ad8a8e..2f51f9813 100755 --- a/buildscripts/build_netcdf-fortran.sh +++ b/buildscripts/build_netcdf-fortran.sh @@ -30,7 +30,6 @@ printf "LDFLAGS: ${LDFLAGS}\n" printf "*********************************************************\n" cd ${DEPENDENCY_DIR}/netcdf-fortran-* -#./configure --disable-shared --with-pic --disable-zstandard-plugin --enable-large-file-tests=no --enable-filter-test=no --prefix=${PREFIX} ./configure --enable-large-file-tests=no --enable-filter-test=no --prefix=${PREFIX} make && make check i if [ -w ${PREFIX} ]; then @@ -38,6 +37,8 @@ if [ -w ${PREFIX} ]; then else sudo make install fi +rsync -a ${PREFIX}/lib/libnetcdff* ${ROOT_DIR}/lib/ +rsync -a ${PREFIX}/include/netcdf.mod ${ROOT_DIR}/include/ if [ $? -ne 0 ]; then printf "netcdf-fortran could not be compiled.\n" diff --git a/buildscripts/build_swiftest.sh b/buildscripts/build_swiftest.sh index 7cc9130ff..10acbfae7 100755 --- a/buildscripts/build_swiftest.sh +++ b/buildscripts/build_swiftest.sh @@ -32,13 +32,20 @@ read -rsn1 -p"Press any key to continue";echo ${SCRIPT_DIR}/build_dependencies.sh ${ARGS} - if [ $OS = "Linux" ]; then cibuildwheel --platform linux else SKBUILD_CONFIGURE_OPTIONS="-DBUILD_SHARED_LIBS=ON -DUSE_SIMD=OFF" SKBUILD_CONFIGURE_OPTIONS="${SKBUILD_CONFIGURE_OPTIONS} -DMACHINE_CODE_VALUE=\"generic\"" OMPROOT=${DEVTOOLDIR}/MacOSX${MACOSX_DEPLOYMENT_TARGET}/${ARCH}/usr/local + rsync -a ${OMPROOT}/lib/libgfortran*dylib ${ROOT_DIR}/lib/ + rsync -a ${OMPROOT}/lib/libgomp*dylib ${ROOT_DIR}/lib/ + rsync -a ${OMPROOT}/lib/libomp*dylib ${ROOT_DIR}/lib/ + rsync -a ${OMPROOT}/lib/libquadmath*dylib ${ROOT_DIR}/lib/ + + NETCDF_FORTRAN_HOME=${ROOT_DIR} + NETCDF_INCLUDE=${ROOT_DIR}/include + CPPFLAGS="${CPPFLAGS} -Xclang -fopenmp" LIBS="${LIBS} -lomp" LDFLAGS="-Wl,-rpath,${OMPROOT}/lib -Wl,-rpath,${ROOT_DIR}/lib" diff --git a/buildscripts/build_zlib.sh b/buildscripts/build_zlib.sh index 928d07fe3..2a7313a13 100755 --- a/buildscripts/build_zlib.sh +++ b/buildscripts/build_zlib.sh @@ -27,7 +27,6 @@ printf "LDFLAGS: ${LDFLAGS}\n" printf "*********************************************************\n" cd ${DEPENDENCY_DIR}/zlib-* -#./configure --prefix=${PREFIX} --static ./configure --prefix=${PREFIX} make if [ -w ${PREFIX} ]; then @@ -35,6 +34,7 @@ if [ -w ${PREFIX} ]; then else sudo make install fi +rsync -va ${PREFIX}/lib/libz* ${ROOT_DIR}/lib/ if [ $? -ne 0 ]; then printf "zlib could not be compiled.\n" From be7283ea7cf07aacf5533947626504c47d87281b Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Thu, 31 Aug 2023 13:30:06 -0400 Subject: [PATCH 09/22] More updates to build scripts for more stable Mac build --- buildscripts/_build_getopts.sh | 11 +-------- buildscripts/build_macwheels.sh | 35 ++++++++++++++++++++++++++ buildscripts/build_swiftest.sh | 21 ++++++---------- buildscripts/set_compilers.sh | 38 ++++++++++++++--------------- cmake/Modules/SetFortranFlags.cmake | 4 +-- distclean.cmake | 4 ++- 6 files changed, 66 insertions(+), 47 deletions(-) create mode 100755 buildscripts/build_macwheels.sh diff --git a/buildscripts/_build_getopts.sh b/buildscripts/_build_getopts.sh index f9356684a..4380b4ad7 100755 --- a/buildscripts/_build_getopts.sh +++ b/buildscripts/_build_getopts.sh @@ -46,18 +46,9 @@ done read -r OS ARCH < <($SCRIPT_DIR/get_platform.sh) BUILD_DIR=${BUILD_DIR:-$(mktemp -ut swiftest_build)} -if [ $OS = "MacOSX" ]; then - printf "MACOSX_DEPLOYMENT_TARGET: ${MACOSX_DEPLOYMENT_TARGET}\n" - PREFIX=${PREFIX:-${BUILD_DIR}/${OS}${MACOSX_DEPLOYMENT_TARGET}/${ARCH}} -else - PREFIX=${PREFIX:-${BUILD_DIR}/${OS}/${ARCH}} -fi - +PREFIX=${PREFIX:-${ROOT_DIR}} DEPENDENCY_DIR=${DEPENDENCY_DIR:-${BUILD_DIR}/downloads} -printf "DEPENDENCY_DIR: ${DEPENDENCY_DIR}\n" -printf "PREFIX : ${PREFIX}\n" - if [ -z ${DEPENDENCY_ENV_VARS+x} ]; then . ${SCRIPT_DIR}/set_compilers.sh diff --git a/buildscripts/build_macwheels.sh b/buildscripts/build_macwheels.sh new file mode 100755 index 000000000..97997bed4 --- /dev/null +++ b/buildscripts/build_macwheels.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# This script will build all versions of the MacOS wheels, for both Apple Silicon (arm64) and Intel (x86_64) and for a variety +# of OS versions. +# +# Copyright 2023 - David Minton +# This file is part of Swiftest. +# Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with Swiftest. +# If not, see: https://www.gnu.org/licenses. +set -a +SCRIPT_DIR=$(realpath $(dirname $0)) +ROOT_DIR=$(realpath ${SCRIPT_DIR}/..) +BUILD_DIR=$(mktemp -ut swiftest_build) +PREFIX=${ROOT_DIR} +DEPENDENCY_DIR=${BUILD_DIR}/downloads + +# The versions of MacOS that we have development tools for +declare -a MACVER=("10.13" "11.0" "12.4" "13.0") + +for MACOSX_DEPLOYMENT_TARGET in "${MACVER[@]}"; do + ARGS="-p ${PREFIX} -d ${DEPENDENCY_DIR} -m ${MACOSX_DEPLOYMENT_TARGET}" + if [ "${MACOSX_DEPLOYMENT_TARGET}" != "10.13" ]; then + ${SCRIPT_DIR}/build_swiftest.sh ${ARGS} + cmake -P distclean.cmake + fi + arch -x86_64 /bin/bash -c "${SCRIPT_DIR}/build_swiftest.sh ${ARGS}" + cmake -P distclean.cmake +done +python3 -m build --sdist + + + diff --git a/buildscripts/build_swiftest.sh b/buildscripts/build_swiftest.sh index 10acbfae7..5fac4b0b2 100755 --- a/buildscripts/build_swiftest.sh +++ b/buildscripts/build_swiftest.sh @@ -12,6 +12,7 @@ set -a if [ -z ${SCRIPT_DIR+x} ]; then SCRIPT_DIR=$(realpath $(dirname $0)); fi ARGS=$@ + . ${SCRIPT_DIR}/_build_getopts.sh ${ARGS} ARGS="-p ${PREFIX} -d ${DEPENDENCY_DIR} -m ${MACOSX_DEPLOYMENT_TARGET}" @@ -28,8 +29,6 @@ echo $OS $ARCH printf "Using ${OS} compilers:\nFC: ${FC}\nCC: ${CC}\nCXX: ${CXX}\n\n" printf "Installing to ${PREFIX}\n" printf "Dependency libraries in ${PREFIX}\n" -read -rsn1 -p"Press any key to continue";echo - ${SCRIPT_DIR}/build_dependencies.sh ${ARGS} if [ $OS = "Linux" ]; then @@ -38,19 +37,16 @@ else SKBUILD_CONFIGURE_OPTIONS="-DBUILD_SHARED_LIBS=ON -DUSE_SIMD=OFF" SKBUILD_CONFIGURE_OPTIONS="${SKBUILD_CONFIGURE_OPTIONS} -DMACHINE_CODE_VALUE=\"generic\"" OMPROOT=${DEVTOOLDIR}/MacOSX${MACOSX_DEPLOYMENT_TARGET}/${ARCH}/usr/local - rsync -a ${OMPROOT}/lib/libgfortran*dylib ${ROOT_DIR}/lib/ - rsync -a ${OMPROOT}/lib/libgomp*dylib ${ROOT_DIR}/lib/ - rsync -a ${OMPROOT}/lib/libomp*dylib ${ROOT_DIR}/lib/ - rsync -a ${OMPROOT}/lib/libquadmath*dylib ${ROOT_DIR}/lib/ + rsync -va ${OMPROOT}/* ${ROOT_DIR}/ NETCDF_FORTRAN_HOME=${ROOT_DIR} NETCDF_INCLUDE=${ROOT_DIR}/include - CPPFLAGS="${CPPFLAGS} -Xclang -fopenmp" - LIBS="${LIBS} -lomp" - LDFLAGS="-Wl,-rpath,${OMPROOT}/lib -Wl,-rpath,${ROOT_DIR}/lib" - CPATH="${OMPROOT}/include:${CPATH}" - LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" + CPPFLAGS="-Xclang -fopenmp" + LIBS="-lomp" + LDFLAGS="-Wl,-rpath,${ROOT_DIR}/lib" + CPATH="${ROOT_DIR}/include" + LD_LIBRARY_PATH="${ROOT_DIR}/lib" LIBRARY_PATH="${LD_LIBRARY_PATH}" cd $ROOT_DIR @@ -58,7 +54,6 @@ else printf "*********************************************************\n" printf "* BUILDING SWIFTEST *\n" printf "*********************************************************\n" - printf "OMPROOT: ${OMPROOT}\n" printf "LIBS: ${LIBS}\n" printf "CFLAGS: ${CFLAGS}\n" printf "FFLAGS: ${FFLAGS}\n" @@ -74,7 +69,5 @@ else printf "MACOSX_DEPLOYMENT_TARGET: ${MACOSX_DEPLOYMENT_TARGET}\n" printf "*********************************************************\n" - python3 -m pip install build pip - python3 -m build --sdist cibuildwheel --platform macos fi \ No newline at end of file diff --git a/buildscripts/set_compilers.sh b/buildscripts/set_compilers.sh index f0588f935..8659af8bb 100755 --- a/buildscripts/set_compilers.sh +++ b/buildscripts/set_compilers.sh @@ -25,44 +25,42 @@ case "$OS" in ;; esac + set -a # Only replace compiler definitions if they are not already set case $OS in Linux) - FC=${FC:-$(command -v gfortran)} - CC=${CC:-$(command -v gcc)} - CXX=${CXX:-$(command -v g++)} - CPP=${CPP:-$(command -v cpp)} + FC=${$(command -v gfortran)} + CC=${$(command -v gcc)} + CXX=${$(command -v g++)} + CPP=${$(command -v cpp)} ;; MacOSX) - COMPILER_PREFIX=${COMPILER_PREFIX:-"/usr"} - CC=${CC:-${COMPILER_PREFIX}/bin/clang} - CXX=${CXX:-${COMPILER_PREFIX}/bin/clang++} - CPP=${CPP:-${COMPILER_PREFIX}/bin/cpp} - AR=${AR:-${COMPILER_PREFIX}/bin/ar} - NM=${NM:-${COMPILER_PREFIX}/bin/nm} - RANLIB=${RANLIB:-${COMPILER_PREFIX}/bin/ranlib} + COMPILER_PREFIX="/usr" + CC=${COMPILER_PREFIX}/bin/clang + CXX=${COMPILER_PREFIX}/bin/clang++ + CPP=${COMPILER_PREFIX}/bin/cpp + AR=${COMPILER_PREFIX}/bin/ar + NM=${COMPILER_PREFIX}/bin/nm + RANLIB=${COMPILER_PREFIX}/bin/ranlib # Use custom gfortran location for a given MacOS Target version if vailable FROOT=${DEVTOOLDIR}/MacOSX${MACOSX_DEPLOYMENT_TARGET}/${ARCH}/usr/local + printf "FROOT: ${FROOT}\n" if [ -f ${FROOT}/bin/gfortran ]; then FC=${FROOT}/bin/gfortran else - FC=${FC:-$(command -v gfortran)} + FC=$(command -v gfortran) FROOT=$(realpath $(dirname $(command -v $FC))/..) fi if [ ! -f ${FC} ]; then printf "No working fortran compiler found!\n" exit 1 fi - LD_LIBRARY_PATH="${COMPILER_PREFIX}/lib:${FROOT}/lib:${LD_LIBRARY_PATH}" - LDFLAGS="${LDFLAGS} -Wl,-rpath,${COMPILER_PREFIX}/lib -Wl,-no_compact_unwind" - CPPFLAGS="${CPPFLAGS} -isystem ${COMPILER_PREFIX}/include" - LIBS="${LIBS}" - CPATH="${FROOT}/include:${CPATH}" - CXXFLAGS="${CFLAGS} ${CXXFLAGS}" - FCFLAGS="${CFLAGS} ${FCFLAGS}" - CFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -Wno-deprecated-non-prototype ${CFLAGS}" + LDFLAGS="-Wl,-no_compact_unwind" + CFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -Wno-deprecated-non-prototype" + LD_LIBRARY_PATH="" + CPATH="" ;; *) printf "Unknown compiler type: ${OS}\n" diff --git a/cmake/Modules/SetFortranFlags.cmake b/cmake/Modules/SetFortranFlags.cmake index 610a428ec..c5514e749 100644 --- a/cmake/Modules/SetFortranFlags.cmake +++ b/cmake/Modules/SetFortranFlags.cmake @@ -162,10 +162,10 @@ IF (NOT BUILD_SHARED_LIBS AND NOT WINOPT) # SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" # Fortran "-static-libquadmath" # ) - IF (USE_OPENMP) SET_COMPILE_FLAG(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS}" - Fortran "-lgomp" + Fortran "-lomp" + "-lgomp" ) ENDIF (USE_OPENMP) ENDIF () diff --git a/distclean.cmake b/distclean.cmake index d01195c6c..c0ce74642 100644 --- a/distclean.cmake +++ b/distclean.cmake @@ -19,7 +19,7 @@ ELSE() SET(TOPDIR "${CMAKE_SOURCE_DIR}") ENDIF() -SET(CIBW_DIR "_skbuild" "swiftest.egg-info") +SET(CIBW_DIR "_skbuild" "swiftest.egg-info" "_cmake_test_compile") MACRO(GET_PARENT_DIRECTORIES search_string return_list grandparents) FILE(GLOB_RECURSE new_list ${search_string}) @@ -46,8 +46,10 @@ FILE(GLOB_RECURSE CMAKEINSTALL "${TOPDIR}/*cmake_install.cmake" FILE(GLOB_RECURSE MAKEFILE "${TOPDIR}/*Makefile") FILE(GLOB_RECURSE CMAKETESTFILES "${TOPDIR}/*CTestTestfile.cmake") SET(TOPDIRECTORIES "${TOPDIR}/lib" + "${TOPDIR}/libexec" "${TOPDIR}/bin" "${TOPDIR}/include" + "${TOPDIR}/share" ) # CMake has trouble finding directories recursively, so locate these From abe9c52fd96336ecfb621efb19b65f663727bc2a Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Fri, 1 Sep 2023 11:05:01 -0400 Subject: [PATCH 10/22] Switched back to using Homebrew, as it is a much more reliable way to get a build that actually works --- buildscripts/build_hdf5.sh | 2 - buildscripts/build_macwheels.sh | 10 ++++- buildscripts/build_netcdf-c.sh | 3 +- buildscripts/build_netcdf-fortran.sh | 4 +- buildscripts/build_swiftest.sh | 7 --- buildscripts/build_zlib.sh | 1 - buildscripts/set_compilers.sh | 66 +++++++++++++++++----------- 7 files changed, 50 insertions(+), 43 deletions(-) diff --git a/buildscripts/build_hdf5.sh b/buildscripts/build_hdf5.sh index 072c7b689..ae05be413 100755 --- a/buildscripts/build_hdf5.sh +++ b/buildscripts/build_hdf5.sh @@ -44,8 +44,6 @@ else sudo make install fi -rsync -va ${PREFIX}/lib/libhdf5* ${ROOT_DIR}/lib/ - if [ $? -ne 0 ]; then printf "hdf5 could not be compiled.\n" exit 1 diff --git a/buildscripts/build_macwheels.sh b/buildscripts/build_macwheels.sh index 97997bed4..366bead2e 100755 --- a/buildscripts/build_macwheels.sh +++ b/buildscripts/build_macwheels.sh @@ -22,12 +22,18 @@ declare -a MACVER=("10.13" "11.0" "12.4" "13.0") for MACOSX_DEPLOYMENT_TARGET in "${MACVER[@]}"; do ARGS="-p ${PREFIX} -d ${DEPENDENCY_DIR} -m ${MACOSX_DEPLOYMENT_TARGET}" + if [ "${MACOSX_DEPLOYMENT_TARGET}" != "10.13" ]; then + ${SCRIPT_DIR}/build_dependencies.sh ${ARGS} ${SCRIPT_DIR}/build_swiftest.sh ${ARGS} cmake -P distclean.cmake fi - arch -x86_64 /bin/bash -c "${SCRIPT_DIR}/build_swiftest.sh ${ARGS}" - cmake -P distclean.cmake + + if [ "${MACOSX_DEPLOYMENT_TARGET}" != "13.0" ]; then + arch -x86_64 /bin/bash -c "${SCRIPT_DIR}/build_dependencies.sh ${ARGS}" + arch -x86_64 /bin/bash -c "${SCRIPT_DIR}/build_swiftest.sh ${ARGS}" + cmake -P distclean.cmake + fi done python3 -m build --sdist diff --git a/buildscripts/build_netcdf-c.sh b/buildscripts/build_netcdf-c.sh index fc17313c6..7df72d91b 100755 --- a/buildscripts/build_netcdf-c.sh +++ b/buildscripts/build_netcdf-c.sh @@ -30,7 +30,7 @@ printf "HDF5_ROOT: ${HDF5_ROOT}\n" printf "*********************************************************\n" cd ${DEPENDENCY_DIR}/netcdf-c-* -COPTS="--disable-testsets --prefix=${PREFIX}" +COPTS="--disable-testsets --disable-nczarr --prefix=${PREFIX}" printf "COPTS: ${COPTS}\n" ./configure $COPTS make && make check @@ -40,7 +40,6 @@ if [ -w ${PREFIX} ]; then else sudo make install fi -rsync -va ${PREFIX}/lib/libnetcdf* ${ROOT_DIR}/lib/ if [ $? -ne 0 ]; then printf "netcdf-c could not be compiled."\n diff --git a/buildscripts/build_netcdf-fortran.sh b/buildscripts/build_netcdf-fortran.sh index 2f51f9813..103ebbfc7 100755 --- a/buildscripts/build_netcdf-fortran.sh +++ b/buildscripts/build_netcdf-fortran.sh @@ -30,15 +30,13 @@ printf "LDFLAGS: ${LDFLAGS}\n" printf "*********************************************************\n" cd ${DEPENDENCY_DIR}/netcdf-fortran-* -./configure --enable-large-file-tests=no --enable-filter-test=no --prefix=${PREFIX} +./configure --enable-large-file-tests=no --enable-static=no --enable-filter-test=no --prefix=${PREFIX} make && make check i if [ -w ${PREFIX} ]; then make install else sudo make install fi -rsync -a ${PREFIX}/lib/libnetcdff* ${ROOT_DIR}/lib/ -rsync -a ${PREFIX}/include/netcdf.mod ${ROOT_DIR}/include/ if [ $? -ne 0 ]; then printf "netcdf-fortran could not be compiled.\n" diff --git a/buildscripts/build_swiftest.sh b/buildscripts/build_swiftest.sh index 5fac4b0b2..3f0af181d 100755 --- a/buildscripts/build_swiftest.sh +++ b/buildscripts/build_swiftest.sh @@ -26,18 +26,11 @@ fi read -r OS ARCH < <($SCRIPT_DIR/get_platform.sh) echo $OS $ARCH -printf "Using ${OS} compilers:\nFC: ${FC}\nCC: ${CC}\nCXX: ${CXX}\n\n" -printf "Installing to ${PREFIX}\n" -printf "Dependency libraries in ${PREFIX}\n" -${SCRIPT_DIR}/build_dependencies.sh ${ARGS} - if [ $OS = "Linux" ]; then cibuildwheel --platform linux else SKBUILD_CONFIGURE_OPTIONS="-DBUILD_SHARED_LIBS=ON -DUSE_SIMD=OFF" SKBUILD_CONFIGURE_OPTIONS="${SKBUILD_CONFIGURE_OPTIONS} -DMACHINE_CODE_VALUE=\"generic\"" - OMPROOT=${DEVTOOLDIR}/MacOSX${MACOSX_DEPLOYMENT_TARGET}/${ARCH}/usr/local - rsync -va ${OMPROOT}/* ${ROOT_DIR}/ NETCDF_FORTRAN_HOME=${ROOT_DIR} NETCDF_INCLUDE=${ROOT_DIR}/include diff --git a/buildscripts/build_zlib.sh b/buildscripts/build_zlib.sh index 2a7313a13..a07e9ea75 100755 --- a/buildscripts/build_zlib.sh +++ b/buildscripts/build_zlib.sh @@ -34,7 +34,6 @@ if [ -w ${PREFIX} ]; then else sudo make install fi -rsync -va ${PREFIX}/lib/libz* ${ROOT_DIR}/lib/ if [ $? -ne 0 ]; then printf "zlib could not be compiled.\n" diff --git a/buildscripts/set_compilers.sh b/buildscripts/set_compilers.sh index 8659af8bb..8a78ade50 100755 --- a/buildscripts/set_compilers.sh +++ b/buildscripts/set_compilers.sh @@ -36,31 +36,43 @@ case $OS in CPP=${$(command -v cpp)} ;; MacOSX) - COMPILER_PREFIX="/usr" - CC=${COMPILER_PREFIX}/bin/clang - CXX=${COMPILER_PREFIX}/bin/clang++ - CPP=${COMPILER_PREFIX}/bin/cpp - AR=${COMPILER_PREFIX}/bin/ar - NM=${COMPILER_PREFIX}/bin/nm - RANLIB=${COMPILER_PREFIX}/bin/ranlib - - # Use custom gfortran location for a given MacOS Target version if vailable - FROOT=${DEVTOOLDIR}/MacOSX${MACOSX_DEPLOYMENT_TARGET}/${ARCH}/usr/local - printf "FROOT: ${FROOT}\n" - if [ -f ${FROOT}/bin/gfortran ]; then - FC=${FROOT}/bin/gfortran - else - FC=$(command -v gfortran) - FROOT=$(realpath $(dirname $(command -v $FC))/..) - fi - if [ ! -f ${FC} ]; then - printf "No working fortran compiler found!\n" - exit 1 - fi - LDFLAGS="-Wl,-no_compact_unwind" - CFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -Wno-deprecated-non-prototype" - LD_LIBRARY_PATH="" - CPATH="" + # For Apple Silicon, use native clang for everything except gfortran, in which case we assume Homebrew + # For Intel, use Homebrew for everything + case $ARCH in + arm64) + COMPILER_PREFIX="/usr" + CC=${COMPILER_PREFIX}/bin/clang + CXX=${COMPILER_PREFIX}/bin/clang++ + CPP=${COMPILER_PREFIX}/bin/cpp + AR=${COMPILER_PREFIX}/bin/ar + NM=${COMPILER_PREFIX}/bin/nm + RANLIB=${COMPILER_PREFIX}/bin/ranlib + + # Use Homebrew gfortran location for a given MacOS Target version if vailable + FROOT=/opt/homebrew + FC=${FROOT}/bin/gfortran + LDFLAGS="-Wl,-no_compact_unwind" + CFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -Wno-deprecated-non-prototype" + LD_LIBRARY_PATH="" + CPATH="" + ;; + x86_64) + COMPILER_PREFIX=/usr/local + CC=${COMPILER_PREFIX}/bin/gcc-13 + CXX=${COMPILER_PREFIX}/bin/g++-13 + CPP=${COMPILER_PREFIX}/bin/cpp-13 + AR=${COMPILER_PREFIX}/bin/gcc-ar-13 + NM=${COMPILER_PREFIX}/bin/gcc-nm-13 + RANLIB=${COMPILER_PREFIX}/bin/gcc-ranlib-13 + + # Use custom gfortran location for a given MacOS Target version if vailable + FC=${COMPILER_PREFIX}/bin/gfortran-13 + LDFLAGS="-Wl,-no_compact_unwind" + CFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -Wno-deprecated-non-prototype" + LD_LIBRARY_PATH="" + CPATH="" + ;; + esac ;; *) printf "Unknown compiler type: ${OS}\n" @@ -69,4 +81,6 @@ case $OS in exit 1 ;; esac -F77=${FC} \ No newline at end of file +F77=${FC} + +printf "Using ${OS} compilers:\nFC: ${FC}\nCC: ${CC}\nCXX: ${CXX}\n\n" \ No newline at end of file From 335731282c6bd88d4ee04d338ded8acca4a2267d Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Sat, 2 Sep 2023 09:36:08 -0400 Subject: [PATCH 11/22] Fixed several issues with build scripts that allow for shared library builds on Mac and Linux --- buildscripts/_build_getopts.sh | 4 +-- buildscripts/build_macwheels.sh | 9 +++-- buildscripts/intelbash.sh | 5 +++ buildscripts/set_compilers.sh | 59 ++++++++++----------------------- pyproject.toml | 2 +- 5 files changed, 32 insertions(+), 47 deletions(-) create mode 100755 buildscripts/intelbash.sh diff --git a/buildscripts/_build_getopts.sh b/buildscripts/_build_getopts.sh index 4380b4ad7..fc9728db7 100755 --- a/buildscripts/_build_getopts.sh +++ b/buildscripts/_build_getopts.sh @@ -45,9 +45,9 @@ while getopts ":d:p:m:h" ARG; do done read -r OS ARCH < <($SCRIPT_DIR/get_platform.sh) -BUILD_DIR=${BUILD_DIR:-$(mktemp -ut swiftest_build)} +BUILD_DIR=${BUILD_DIR:-$(mktemp -ut swiftest_build.XXXXXXXX)} PREFIX=${PREFIX:-${ROOT_DIR}} -DEPENDENCY_DIR=${DEPENDENCY_DIR:-${BUILD_DIR}/downloads} +DEPENDENCY_DIR=${DEPENDENCY_DIR:-${BUILD_DIR}} if [ -z ${DEPENDENCY_ENV_VARS+x} ]; then . ${SCRIPT_DIR}/set_compilers.sh diff --git a/buildscripts/build_macwheels.sh b/buildscripts/build_macwheels.sh index 366bead2e..49acbec91 100755 --- a/buildscripts/build_macwheels.sh +++ b/buildscripts/build_macwheels.sh @@ -18,10 +18,13 @@ PREFIX=${ROOT_DIR} DEPENDENCY_DIR=${BUILD_DIR}/downloads # The versions of MacOS that we have development tools for -declare -a MACVER=("10.13" "11.0" "12.4" "13.0") +declare -a MACVER=("10.13" "11.0" "12.0" "13.0") for MACOSX_DEPLOYMENT_TARGET in "${MACVER[@]}"; do ARGS="-p ${PREFIX} -d ${DEPENDENCY_DIR} -m ${MACOSX_DEPLOYMENT_TARGET}" + printf "**********************************************************************\n" + printf "ARGS: ${ARGS}\n" + printf "**********************************************************************\n" if [ "${MACOSX_DEPLOYMENT_TARGET}" != "10.13" ]; then ${SCRIPT_DIR}/build_dependencies.sh ${ARGS} @@ -30,8 +33,8 @@ for MACOSX_DEPLOYMENT_TARGET in "${MACVER[@]}"; do fi if [ "${MACOSX_DEPLOYMENT_TARGET}" != "13.0" ]; then - arch -x86_64 /bin/bash -c "${SCRIPT_DIR}/build_dependencies.sh ${ARGS}" - arch -x86_64 /bin/bash -c "${SCRIPT_DIR}/build_swiftest.sh ${ARGS}" + ${SCRIPT_DIR}/intelbash.sh ${SCRIPT_DIR}/build_dependencies.sh ${ARGS} + ${SCRIPT_DIR}/intelbash.sh ${SCRIPT_DIR}/build_swiftest.sh ${ARGS} cmake -P distclean.cmake fi done diff --git a/buildscripts/intelbash.sh b/buildscripts/intelbash.sh new file mode 100755 index 000000000..7f42e5534 --- /dev/null +++ b/buildscripts/intelbash.sh @@ -0,0 +1,5 @@ +#!/bin/bash +ARGS=$@ + +eval "$(/usr/local/bin/brew shellenv)" +arch -x86_64 /bin/bash -c "${ARGS}" diff --git a/buildscripts/set_compilers.sh b/buildscripts/set_compilers.sh index 8a78ade50..7523628ee 100755 --- a/buildscripts/set_compilers.sh +++ b/buildscripts/set_compilers.sh @@ -30,49 +30,26 @@ set -a # Only replace compiler definitions if they are not already set case $OS in Linux) - FC=${$(command -v gfortran)} - CC=${$(command -v gcc)} - CXX=${$(command -v g++)} - CPP=${$(command -v cpp)} + FC=$(command -v gfortran) + CC=$(command -v gcc) + CXX=$(command -v g++) + CPP=$(command -v cpp) ;; MacOSX) - # For Apple Silicon, use native clang for everything except gfortran, in which case we assume Homebrew - # For Intel, use Homebrew for everything - case $ARCH in - arm64) - COMPILER_PREFIX="/usr" - CC=${COMPILER_PREFIX}/bin/clang - CXX=${COMPILER_PREFIX}/bin/clang++ - CPP=${COMPILER_PREFIX}/bin/cpp - AR=${COMPILER_PREFIX}/bin/ar - NM=${COMPILER_PREFIX}/bin/nm - RANLIB=${COMPILER_PREFIX}/bin/ranlib - - # Use Homebrew gfortran location for a given MacOS Target version if vailable - FROOT=/opt/homebrew - FC=${FROOT}/bin/gfortran - LDFLAGS="-Wl,-no_compact_unwind" - CFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -Wno-deprecated-non-prototype" - LD_LIBRARY_PATH="" - CPATH="" - ;; - x86_64) - COMPILER_PREFIX=/usr/local - CC=${COMPILER_PREFIX}/bin/gcc-13 - CXX=${COMPILER_PREFIX}/bin/g++-13 - CPP=${COMPILER_PREFIX}/bin/cpp-13 - AR=${COMPILER_PREFIX}/bin/gcc-ar-13 - NM=${COMPILER_PREFIX}/bin/gcc-nm-13 - RANLIB=${COMPILER_PREFIX}/bin/gcc-ranlib-13 - - # Use custom gfortran location for a given MacOS Target version if vailable - FC=${COMPILER_PREFIX}/bin/gfortran-13 - LDFLAGS="-Wl,-no_compact_unwind" - CFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -Wno-deprecated-non-prototype" - LD_LIBRARY_PATH="" - CPATH="" - ;; - esac + FC=${HOMEBREW_PREFIX}/bin/gfortran-12 + CFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -Wno-deprecated-non-prototype -arch ${ARCH}" + FCFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -arch ${ARCH}" + FFLAGS=$FCFLAGS + LD_LIBRARY_PATH="" + CPATH="" + COMPILER_PREFIX="/usr" + CC=${COMPILER_PREFIX}/bin/clang + CXX=${COMPILER_PREFIX}/bin/clang++ + CPP=${COMPILER_PREFIX}/bin/cpp + AR=${COMPILER_PREFIX}/bin/ar + NM=${COMPILER_PREFIX}/bin/nm + RANLIB=${COMPILER_PREFIX}/bin/ranlib + LDFLAGS="-Wl,-no_compact_unwind" ;; *) printf "Unknown compiler type: ${OS}\n" diff --git a/pyproject.toml b/pyproject.toml index 0a7efb357..e445532a6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,6 @@ skip = "pp* *i686 *-manylinux_i686 *_ppc64le *_s390x *-musllinux* *-win32" [tool.cibuildwheel.linux] environment = {FFLAGS="${FFLAGS} -fPIC", CFLAGS="${CFLAGS} -fPIC", LDFLAGS="${LDFLAGS} -fPIE", LIBS="-lgomp"} before-all = [ - "yum install doxygen -y || apt-get install doxygen -y", + "yum install doxygen libxml2-devel -y || apt-get install doxygen libxml2-dev -y", "buildscripts/build_dependencies.sh -p /usr/local", ] From 2eba89b91cedbbdb72fcc00fdc063d4f0813fa8a Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Thu, 7 Sep 2023 09:17:55 -0400 Subject: [PATCH 12/22] Major restructuring of build system. Switched to scikit-build-core for futureproofing, which means getting rid of setup.py and relying on pyproject.toml. Working on making the Linux build more efficient --- CMakeLists.txt | 25 +- buildscripts/build_hdf5.sh | 3 - buildscripts/build_netcdf-c.sh | 4 +- buildscripts/build_netcdf-fortran.sh | 5 +- buildscripts/build_zlib.sh | 4 +- cmake/Modules/FindCython.cmake | 3 +- cmake/Modules/FindNETCDF.cmake | 15 +- cmake/Modules/FindPythonExtensions.cmake | 597 ++++++++++++++++++ cmake/Modules/UseCython.cmake | 383 +++++++++++ cmake/Modules/UsePythonExtensions.cmake | 320 ++++++++++ ...targetLinkLibrariesWithDynamicLookup.cmake | 597 ++++++++++++++++++ pyproject.toml | 65 +- setup.py | 64 -- src/globals/globals_module.f90 | 2 +- version.txt | 2 +- 15 files changed, 1967 insertions(+), 122 deletions(-) create mode 100644 cmake/Modules/FindPythonExtensions.cmake create mode 100644 cmake/Modules/UseCython.cmake create mode 100644 cmake/Modules/UsePythonExtensions.cmake create mode 100644 cmake/Modules/targetLinkLibrariesWithDynamicLookup.cmake delete mode 100644 setup.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 01aa4d8eb..4a21a2d07 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.6.0...3.27.1) # Get version stored in text file FILE(READ "version.txt" VERSION) -PROJECT(swiftest VERSION ${VERSION} LANGUAGES C Fortran) +PROJECT(${SKBUILD_PROJECT_NAME} LANGUAGES C Fortran VERSION ${VERSION}) IF (CMAKE_Fortran_COMPILER_ID MATCHES "^Intel") SET(COMPILER_OPTIONS "Intel" CACHE STRING "Compiler identified as Intel") @@ -37,28 +37,7 @@ IF(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) ENDIF() # Ensure scikit-build modules -FIND_PACKAGE(Python3 COMPONENTS Interpreter Development.Module REQUIRED) -IF (NOT SKBUILD) - EXECUTE_PROCESS( - COMMAND "${Python3_EXECUTABLE}" - -c "import os, skbuild; print(os.path.dirname(skbuild.__file__))" - OUTPUT_VARIABLE SKBLD_DIR - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - FILE(TO_CMAKE_PATH ${SKBLD_DIR} SKBLD_DIR) - LIST(APPEND CMAKE_MODULE_PATH "${SKBLD_DIR}/resources/cmake") - MESSAGE(STATUS "Looking in ${SKBLD_DIR}/resources/cmake for CMake modules") -ENDIF() - -# Detect when building against a conda environment set the _using_conda variable -# for use both in this file and in the parent -GET_FILENAME_COMPONENT(_python_bin_dir ${Python3_EXECUTABLE} DIRECTORY) -IF(EXISTS "${_python_bin_dir}/../conda-meta") - MESSAGE("-- Detected conda environment, setting INSTALL_RPATH_USE_LINK_PATH") - SET(_using_conda On) -ELSE() - SET(_using_conda Off) -ENDIF() +FIND_PACKAGE(Python COMPONENTS Interpreter Development.Module REQUIRED) # Add our local modules to the module path FILE(TO_CMAKE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules" LOCAL_MODULE_PATH) diff --git a/buildscripts/build_hdf5.sh b/buildscripts/build_hdf5.sh index ae05be413..4fa633582 100755 --- a/buildscripts/build_hdf5.sh +++ b/buildscripts/build_hdf5.sh @@ -48,6 +48,3 @@ if [ $? -ne 0 ]; then printf "hdf5 could not be compiled.\n" exit 1 fi - -make distclean - diff --git a/buildscripts/build_netcdf-c.sh b/buildscripts/build_netcdf-c.sh index 7df72d91b..d11f39126 100755 --- a/buildscripts/build_netcdf-c.sh +++ b/buildscripts/build_netcdf-c.sh @@ -44,6 +44,4 @@ fi if [ $? -ne 0 ]; then printf "netcdf-c could not be compiled."\n exit 1 -fi - -make distclean \ No newline at end of file +fi \ No newline at end of file diff --git a/buildscripts/build_netcdf-fortran.sh b/buildscripts/build_netcdf-fortran.sh index 103ebbfc7..064903224 100755 --- a/buildscripts/build_netcdf-fortran.sh +++ b/buildscripts/build_netcdf-fortran.sh @@ -41,7 +41,4 @@ fi if [ $? -ne 0 ]; then printf "netcdf-fortran could not be compiled.\n" exit 1 -fi - -make distclean - +fi \ No newline at end of file diff --git a/buildscripts/build_zlib.sh b/buildscripts/build_zlib.sh index a07e9ea75..99571d8f3 100755 --- a/buildscripts/build_zlib.sh +++ b/buildscripts/build_zlib.sh @@ -38,6 +38,4 @@ fi if [ $? -ne 0 ]; then printf "zlib could not be compiled.\n" exit 1 -fi - -make distclean \ No newline at end of file +fi \ No newline at end of file diff --git a/cmake/Modules/FindCython.cmake b/cmake/Modules/FindCython.cmake index c59f0307c..c8de13112 100644 --- a/cmake/Modules/FindCython.cmake +++ b/cmake/Modules/FindCython.cmake @@ -20,7 +20,6 @@ # #============================================================================= # Copyright 2011 Kitware, Inc. -# Modified 2023 by David A. Minton (daminton@purdue.edu) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -57,7 +56,7 @@ else() endif() if(CYTHON_EXECUTABLE) - set(CYTHON_version_command "${CYTHON_EXECUTABLE} --version") # Added quotes to prevent the string from having a ; inserted in the space + set(CYTHON_version_command ${CYTHON_EXECUTABLE} --version) execute_process(COMMAND ${CYTHON_version_command} OUTPUT_VARIABLE CYTHON_version_output diff --git a/cmake/Modules/FindNETCDF.cmake b/cmake/Modules/FindNETCDF.cmake index d6a3c4868..05f91e77c 100644 --- a/cmake/Modules/FindNETCDF.cmake +++ b/cmake/Modules/FindNETCDF.cmake @@ -9,17 +9,13 @@ # - Finds the NetCDF libraries -FILE(TO_CMAKE_PATH "${CMAKE_SOURCE_DIR}/_dependencies/${CMAKE_SYSTEM_NAME}_${CMAKE_SYSTEM_PROCESSOR}_${COMPILER_OPTIONS}" NXPREFIX_CANDIDATE) -IF (EXISTS ${NXPREFIX_CANDIDATE}) - SET(NCPREFIX_DIR ${NXPREFIX_CANDIDATE} CACHE PATH "Location of provided NetCDF-C dependencies") - SET(NFPREFIX_DIR ${NXPREFIX_CANDIDATE} CACHE PATH "Location of provided NetCDF-Fortran dependencies") - SET(H5PREFIX_DIR ${NXPREFIX_CANDIDATE} CACHE PATH "Location of provided HDF5 dependencies") - SET(ZPREFIX_DIR ${NXPREFIX_CANDIDATE} CACHE PATH "Location of provided zlib dependencies") - SET(NFINCLUDE_DIR "${NFPREFIX_DIR}/include" CACHE PATH "Location of provided netcdf.mod") -ELSEIF(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") +SET(NFPREFIX_DIR ${CMAKE_SOURCE_DIR} CACHE PATH "Location of provided NetCDF-Fortran dependencies") +SET(NFINCLUDE_DIR "${NFPREFIX_DIR}/include" CACHE PATH "Location of provided netcdf.mod") +IF(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") FIND_PATH(NFBIN NAMES nf-config HINTS + NFPREFIX_DIR ENV NETCDF_FORTRAN_HOME ENV PATH PATH_SUFFIXES @@ -75,6 +71,9 @@ MESSAGE(STATUS "NetCDF-Fortran include directory: ${NETCDF_INCLUDE_DIR}") IF (BUILD_SHARED_LIBS) SET(NETCDFF "netcdff") ELSE () + SET(NCPREFIX_DIR ${CMAKE_SOURCE_DIR} CACHE PATH "Location of provided NetCDF-C dependencies") + SET(H5PREFIX_DIR ${CMAKE_SOURCE_DIR} CACHE PATH "Location of provided HDF5 dependencies") + SET(ZPREFIX_DIR ${CMAKE_SOURCE_DIR} CACHE PATH "Location of provided zlib dependencies") IF (CMAKE_SYSTEM_NAME STREQUAL "Windows") SET(NETCDFF "netcdff.lib") SET(NETCDF "netcdf.lib") diff --git a/cmake/Modules/FindPythonExtensions.cmake b/cmake/Modules/FindPythonExtensions.cmake new file mode 100644 index 000000000..59b30c2a2 --- /dev/null +++ b/cmake/Modules/FindPythonExtensions.cmake @@ -0,0 +1,597 @@ +#.rst: +# +# This module defines CMake functions to build Python extension modules and +# stand-alone executables. +# +# The following variables are defined: +# :: +# +# PYTHON_PREFIX - absolute path to the current Python +# distribution's prefix +# PYTHON_SITE_PACKAGES_DIR - absolute path to the current Python +# distribution's site-packages directory +# PYTHON_RELATIVE_SITE_PACKAGES_DIR - path to the current Python +# distribution's site-packages directory +# relative to its prefix +# PYTHON_SEPARATOR - separator string for file path +# components. Equivalent to ``os.sep`` in +# Python. +# PYTHON_PATH_SEPARATOR - separator string for PATH-style +# environment variables. Equivalent to +# ``os.pathsep`` in Python. +# PYTHON_EXTENSION_MODULE_SUFFIX - suffix of the compiled module. For example, on +# Linux, based on environment, it could be ``.cpython-35m-x86_64-linux-gnu.so``. +# +# +# +# The following functions are defined: +# +# .. cmake:command:: python_extension_module +# +# For libraries meant to be used as Python extension modules, either dynamically +# loaded or directly linked. Amend the configuration of the library target +# (created using ``add_library``) with additional options needed to build and +# use the referenced library as a Python extension module. +# +# python_extension_module( +# [LINKED_MODULES_VAR ] +# [FORWARD_DECL_MODULES_VAR ] +# [MODULE_SUFFIX ]) +# +# Only extension modules that are configured to be built as MODULE libraries can +# be runtime-loaded through the standard Python import mechanism. All other +# modules can only be included in standalone applications that are written to +# expect their presence. In addition to being linked against the libraries for +# these modules, such applications must forward declare their entry points and +# initialize them prior to use. To generate these forward declarations and +# initializations, see ``python_modules_header``. +# +# If ```` does not refer to a target, then it is assumed to refer to an +# extension module that is not linked at all, but compiled along with other +# source files directly into an executable. Adding these modules does not cause +# any library configuration modifications, and they are not added to the list of +# linked modules. They still must be forward declared and initialized, however, +# and so are added to the forward declared modules list. +# +# If the associated target is of type ``MODULE_LIBRARY``, the LINK_FLAGS target +# property is used to set symbol visibility and export only the module init function. +# This applies to GNU and MSVC compilers. +# +# Options: +# +# ``LINKED_MODULES_VAR `` +# Name of the variable referencing a list of extension modules whose libraries +# must be linked into the executables of any stand-alone applications that use +# them. By default, the global property ``PY_LINKED_MODULES_LIST`` is used. +# +# ``FORWARD_DECL_MODULES_VAR `` +# Name of the variable referencing a list of extension modules whose entry +# points must be forward declared and called by any stand-alone applications +# that use them. By default, the global property +# ``PY_FORWARD_DECL_MODULES_LIST`` is used. +# +# ``MODULE_SUFFIX `` +# Suffix appended to the python extension module file. +# The default suffix is retrieved using ``sysconfig.get_config_var("SO")"``, +# if not available, the default is then ``.so`` on unix and ``.pyd`` on +# windows. +# Setting the variable ``PYTHON_EXTENSION_MODULE_SUFFIX`` in the caller +# scope defines the value used for all extensions not having a suffix +# explicitly specified using ``MODULE_SUFFIX`` parameter. +# +# +# .. cmake:command:: python_standalone_executable +# +# python_standalone_executable() +# +# For standalone executables that initialize their own Python runtime +# (such as when building source files that include one generated by Cython with +# the --embed option). Amend the configuration of the executable target +# (created using ``add_executable``) with additional options needed to properly +# build the referenced executable. +# +# +# .. cmake:command:: python_modules_header +# +# Generate a header file that contains the forward declarations and +# initialization routines for the given list of Python extension modules. +# ```` is the logical name for the header file (no file extensions). +# ```` is the actual destination filename for the header file +# (e.g.: decl_modules.h). +# +# python_modules_header( [HeaderFilename] +# [FORWARD_DECL_MODULES_LIST ] +# [HEADER_OUTPUT_VAR ] +# [INCLUDE_DIR_OUTPUT_VAR ]) +# +# without the extension is used as the logical name. If only ```` is +# +# If only ```` is provided, and it ends in the ".h" extension, then it +# is assumed to be the ````. The filename of the header file +# provided, and it does not end in the ".h" extension, then the +# ```` is assumed to ``.h``. +# +# The exact contents of the generated header file depend on the logical +# ````. It should be set to a value that corresponds to the target +# application, or for the case of multiple applications, some identifier that +# conveyes its purpose. It is featured in the generated multiple inclusion +# guard as well as the names of the generated initialization routines. +# +# The generated header file includes forward declarations for all listed +# modules, as well as implementations for the following class of routines: +# +# ``int _(void)`` +# Initializes the python extension module, ````. Returns an integer +# handle to the module. +# +# ``void _LoadAllPythonModules(void)`` +# Initializes all listed python extension modules. +# +# ``void CMakeLoadAllPythonModules(void);`` +# Alias for ``_LoadAllPythonModules`` whose name does not depend on +# ````. This function is excluded during preprocessing if the +# preprocessing macro ``EXCLUDE_LOAD_ALL_FUNCTION`` is defined. +# +# ``void Py_Initialize_Wrapper();`` +# Wrapper arpund ``Py_Initialize()`` that initializes all listed python +# extension modules. This function is excluded during preprocessing if the +# preprocessing macro ``EXCLUDE_PY_INIT_WRAPPER`` is defined. If this +# function is generated, then ``Py_Initialize()`` is redefined to a macro +# that calls this function. +# +# Options: +# +# ``FORWARD_DECL_MODULES_LIST `` +# List of extension modules for which to generate forward declarations of +# their entry points and their initializations. By default, the global +# property ``PY_FORWARD_DECL_MODULES_LIST`` is used. +# +# ``HEADER_OUTPUT_VAR `` +# Name of the variable to set to the path to the generated header file. By +# default, ```` is used. +# +# ``INCLUDE_DIR_OUTPUT_VAR `` +# Name of the variable to set to the path to the directory containing the +# generated header file. By default, ``_INCLUDE_DIRS`` is used. +# +# Defined variables: +# +# ```` +# The path to the generated header file +# +# ```` +# Directory containing the generated header file +# +# +# Example usage +# ^^^^^^^^^^^^^ +# +# .. code-block:: cmake +# +# find_package(PythonExtensions) +# find_package(Cython) +# find_package(Boost COMPONENTS python) +# +# # Simple Cython Module -- no executables +# add_cython_target(_module.pyx) +# add_library(_module MODULE ${_module}) +# python_extension_module(_module) +# +# # Mix of Cython-generated code and C++ code using Boost Python +# # Stand-alone executable -- no modules +# include_directories(${Boost_INCLUDE_DIRS}) +# add_cython_target(main.pyx CXX EMBED_MAIN) +# add_executable(main boost_python_module.cxx ${main}) +# target_link_libraries(main ${Boost_LIBRARIES}) +# python_standalone_executable(main) +# +# # stand-alone executable with three extension modules: +# # one statically linked, one dynamically linked, and one loaded at runtime +# # +# # Freely mixes Cython-generated code, code using Boost-Python, and +# # hand-written code using the CPython API. +# +# # module1 -- statically linked +# add_cython_target(module1.pyx) +# add_library(module1 STATIC ${module1}) +# python_extension_module(module1 +# LINKED_MODULES_VAR linked_module_list +# FORWARD_DECL_MODULES_VAR fdecl_module_list) +# +# # module2 -- dynamically linked +# include_directories(${Boost_INCLUDE_DIRS}) +# add_library(module2 SHARED boost_module2.cxx) +# target_link_libraries(module2 ${Boost_LIBRARIES}) +# python_extension_module(module2 +# LINKED_MODULES_VAR linked_module_list +# FORWARD_DECL_MODULES_VAR fdecl_module_list) +# +# # module3 -- loaded at runtime +# add_cython_target(module3a.pyx) +# add_library(module3 MODULE ${module3a} module3b.cxx) +# target_link_libraries(module3 ${Boost_LIBRARIES}) +# python_extension_module(module3 +# LINKED_MODULES_VAR linked_module_list +# FORWARD_DECL_MODULES_VAR fdecl_module_list) +# +# # application executable -- generated header file + other source files +# python_modules_header(modules +# FORWARD_DECL_MODULES_LIST ${fdecl_module_list}) +# include_directories(${modules_INCLUDE_DIRS}) +# +# add_cython_target(mainA) +# add_cython_target(mainC) +# add_executable(main ${mainA} mainB.cxx ${mainC} mainD.c) +# +# target_link_libraries(main ${linked_module_list} ${Boost_LIBRARIES}) +# python_standalone_executable(main) +# +#============================================================================= +# Copyright 2011 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +find_package(PythonInterp REQUIRED) +if(SKBUILD AND NOT PYTHON_LIBRARY) + set(PYTHON_LIBRARY "no-library-required") + find_package(PythonLibs) + unset(PYTHON_LIBRARY) + unset(PYTHON_LIBRARIES) +else() + find_package(PythonLibs) +endif() +include(targetLinkLibrariesWithDynamicLookup) + +set(_command " +import distutils.sysconfig +import itertools +import os +import os.path +import site +import sys + +result = None +rel_result = None +candidate_lists = [] + +try: + candidate_lists.append((distutils.sysconfig.get_python_lib(),)) +except AttributeError: pass + +try: + candidate_lists.append(site.getsitepackages()) +except AttributeError: pass + +try: + candidate_lists.append((site.getusersitepackages(),)) +except AttributeError: pass + +candidates = itertools.chain.from_iterable(candidate_lists) + +for candidate in candidates: + rel_candidate = os.path.relpath( + candidate, sys.prefix) + if not rel_candidate.startswith(\"..\"): + result = candidate + rel_result = rel_candidate + break + +sys.stdout.write(\";\".join(( + os.sep, + os.pathsep, + sys.prefix, + result, + rel_result, + distutils.sysconfig.get_config_var('EXT_SUFFIX') +))) +") + +execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c "${_command}" + OUTPUT_VARIABLE _list + RESULT_VARIABLE _result) + +list(GET _list 0 _item) +set(PYTHON_SEPARATOR "${_item}") +mark_as_advanced(PYTHON_SEPARATOR) + +list(GET _list 1 _item) +set(PYTHON_PATH_SEPARATOR "${_item}") +mark_as_advanced(PYTHON_PATH_SEPARATOR) + +list(GET _list 2 _item) +set(PYTHON_PREFIX "${_item}") +mark_as_advanced(PYTHON_PREFIX) + +list(GET _list 3 _item) +set(PYTHON_SITE_PACKAGES_DIR "${_item}") +mark_as_advanced(PYTHON_SITE_PACKAGES_DIR) + +list(GET _list 4 _item) +set(PYTHON_RELATIVE_SITE_PACKAGES_DIR "${_item}") +mark_as_advanced(PYTHON_RELATIVE_SITE_PACKAGES_DIR) + +if(NOT DEFINED PYTHON_EXTENSION_MODULE_SUFFIX) + list(GET _list 5 _item) + set(PYTHON_EXTENSION_MODULE_SUFFIX "${_item}") +endif() + +function(_set_python_extension_symbol_visibility _target) + if(PYTHON_VERSION_MAJOR VERSION_GREATER 2) + set(_modinit_prefix "PyInit_") + else() + set(_modinit_prefix "init") + endif() + message("_modinit_prefix:${_modinit_prefix}") + if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") + set_target_properties(${_target} PROPERTIES LINK_FLAGS + "/EXPORT:${_modinit_prefix}${_target}" + ) + elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + # Option to not run version script. See https://github.com/scikit-build/scikit-build/issues/668 + if(NOT DEFINED SKBUILD_GNU_SKIP_LOCAL_SYMBOL_EXPORT_OVERRIDE) + set(SKBUILD_GNU_SKIP_LOCAL_SYMBOL_EXPORT_OVERRIDE FALSE) + endif() + set(_script_path + ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_target}-version-script.map + ) + # Export all symbols. See https://github.com/scikit-build/scikit-build/issues/668 + if(SKBUILD_GNU_SKIP_LOCAL_SYMBOL_EXPORT_OVERRIDE) + file(WRITE ${_script_path} + "{global: ${_modinit_prefix}${_target};};" + ) + else() + file(WRITE ${_script_path} + "{global: ${_modinit_prefix}${_target}; local: *;};" + ) + endif() + if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "SunOS") + set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS + " -Wl,--version-script=\"${_script_path}\"" + ) + else() + set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS + " -Wl,-M \"${_script_path}\"" + ) + endif() + endif() +endfunction() + +function(python_extension_module _target) + set(one_ops LINKED_MODULES_VAR FORWARD_DECL_MODULES_VAR MODULE_SUFFIX) + cmake_parse_arguments(_args "" "${one_ops}" "" ${ARGN}) + + set(_lib_type "NA") + if(TARGET ${_target}) + get_property(_lib_type TARGET ${_target} PROPERTY TYPE) + endif() + + set(_is_non_lib TRUE) + + set(_is_static_lib FALSE) + if(_lib_type STREQUAL "STATIC_LIBRARY") + set(_is_static_lib TRUE) + set(_is_non_lib FALSE) + endif() + + set(_is_shared_lib FALSE) + if(_lib_type STREQUAL "SHARED_LIBRARY") + set(_is_shared_lib TRUE) + set(_is_non_lib FALSE) + endif() + + set(_is_module_lib FALSE) + if(_lib_type STREQUAL "MODULE_LIBRARY") + set(_is_module_lib TRUE) + set(_is_non_lib FALSE) + endif() + + if(_is_static_lib OR _is_shared_lib OR _is_non_lib) + + if(_is_static_lib OR _is_shared_lib) + if(_args_LINKED_MODULES_VAR) + set(${_args_LINKED_MODULES_VAR} + ${${_args_LINKED_MODULES_VAR}} ${_target} PARENT_SCOPE) + else() + set_property(GLOBAL APPEND PROPERTY PY_LINKED_MODULES_LIST ${_target}) + endif() + endif() + + if(_args_FORWARD_DECL_MODULES_VAR) + set(${_args_FORWARD_DECL_MODULES_VAR} + ${${_args_FORWARD_DECL_MODULES_VAR}} ${_target} PARENT_SCOPE) + else() + set_property(GLOBAL APPEND PROPERTY + PY_FORWARD_DECL_MODULES_LIST ${_target}) + endif() + endif() + + if(NOT _is_non_lib) + include_directories("${PYTHON_INCLUDE_DIRS}") + endif() + + if(_is_module_lib) + set_target_properties(${_target} PROPERTIES + PREFIX "${PYTHON_MODULE_PREFIX}") + endif() + + if(_is_module_lib OR _is_shared_lib) + if(_is_module_lib) + + if(NOT _args_MODULE_SUFFIX) + set(_args_MODULE_SUFFIX "${PYTHON_EXTENSION_MODULE_SUFFIX}") + endif() + + if(_args_MODULE_SUFFIX STREQUAL "" AND WIN32 AND NOT CYGWIN) + set(_args_MODULE_SUFFIX ".pyd") + endif() + + if(NOT _args_MODULE_SUFFIX STREQUAL "") + set_target_properties(${_target} + PROPERTIES SUFFIX ${_args_MODULE_SUFFIX}) + endif() + endif() + + target_link_libraries_with_dynamic_lookup(${_target} ${PYTHON_LIBRARIES}) + + if(_is_module_lib) + _set_python_extension_symbol_visibility(${_target}) + endif() + endif() +endfunction() + +function(python_standalone_executable _target) + include_directories(${PYTHON_INCLUDE_DIRS}) + target_link_libraries(${_target} ${SKBUILD_LINK_LIBRARIES_KEYWORD} ${PYTHON_LIBRARIES}) +endfunction() + +function(python_modules_header _name) + set(one_ops FORWARD_DECL_MODULES_LIST + HEADER_OUTPUT_VAR + INCLUDE_DIR_OUTPUT_VAR) + cmake_parse_arguments(_args "" "${one_ops}" "" ${ARGN}) + + list(GET _args_UNPARSED_ARGUMENTS 0 _arg0) + # if present, use arg0 as the input file path + if(_arg0) + set(_source_file ${_arg0}) + + # otherwise, must determine source file from name, or vice versa + else() + get_filename_component(_name_ext "${_name}" EXT) + + # if extension provided, _name is the source file + if(_name_ext) + set(_source_file ${_name}) + get_filename_component(_name "${_source_file}" NAME_WE) + + # otherwise, assume the source file is ${_name}.h + else() + set(_source_file ${_name}.h) + endif() + endif() + + if(_args_FORWARD_DECL_MODULES_LIST) + set(static_mod_list ${_args_FORWARD_DECL_MODULES_LIST}) + else() + get_property(static_mod_list GLOBAL PROPERTY PY_FORWARD_DECL_MODULES_LIST) + endif() + + string(REPLACE "." "_" _header_name "${_name}") + string(TOUPPER ${_header_name} _header_name_upper) + set(_header_name_upper "_${_header_name_upper}_H") + set(generated_file ${CMAKE_CURRENT_BINARY_DIR}/${_source_file}) + + set(generated_file_tmp "${generated_file}.in") + file(WRITE ${generated_file_tmp} + "/* Created by CMake. DO NOT EDIT; changes will be lost. */\n") + + set(_chunk "") + set(_chunk "${_chunk}#ifndef ${_header_name_upper}\n") + set(_chunk "${_chunk}#define ${_header_name_upper}\n") + set(_chunk "${_chunk}\n") + set(_chunk "${_chunk}#include \n") + set(_chunk "${_chunk}\n") + set(_chunk "${_chunk}#ifdef __cplusplus\n") + set(_chunk "${_chunk}extern \"C\" {\n") + set(_chunk "${_chunk}#endif /* __cplusplus */\n") + set(_chunk "${_chunk}\n") + set(_chunk "${_chunk}#if PY_MAJOR_VERSION < 3\n") + file(APPEND ${generated_file_tmp} "${_chunk}") + + foreach(_module ${static_mod_list}) + file(APPEND ${generated_file_tmp} + "PyMODINIT_FUNC init${PYTHON_MODULE_PREFIX}${_module}(void);\n") + endforeach() + + file(APPEND ${generated_file_tmp} "#else /* PY_MAJOR_VERSION >= 3*/\n") + + foreach(_module ${static_mod_list}) + file(APPEND ${generated_file_tmp} + "PyMODINIT_FUNC PyInit_${PYTHON_MODULE_PREFIX}${_module}(void);\n") + endforeach() + + set(_chunk "") + set(_chunk "${_chunk}#endif /* PY_MAJOR_VERSION >= 3*/\n\n") + set(_chunk "${_chunk}#ifdef __cplusplus\n") + set(_chunk "${_chunk}}\n") + set(_chunk "${_chunk}#endif /* __cplusplus */\n") + set(_chunk "${_chunk}\n") + file(APPEND ${generated_file_tmp} "${_chunk}") + + foreach(_module ${static_mod_list}) + set(_import_function "${_header_name}_${_module}") + set(_prefixed_module "${PYTHON_MODULE_PREFIX}${_module}") + + set(_chunk "") + set(_chunk "${_chunk}int ${_import_function}(void)\n") + set(_chunk "${_chunk}{\n") + set(_chunk "${_chunk} static char name[] = \"${_prefixed_module}\";\n") + set(_chunk "${_chunk} #if PY_MAJOR_VERSION < 3\n") + set(_chunk "${_chunk} return PyImport_AppendInittab(") + set(_chunk "${_chunk}name, init${_prefixed_module});\n") + set(_chunk "${_chunk} #else /* PY_MAJOR_VERSION >= 3 */\n") + set(_chunk "${_chunk} return PyImport_AppendInittab(") + set(_chunk "${_chunk}name, PyInit_${_prefixed_module});\n") + set(_chunk "${_chunk} #endif /* PY_MAJOR_VERSION >= 3 */\n") + set(_chunk "${_chunk}}\n\n") + file(APPEND ${generated_file_tmp} "${_chunk}") + endforeach() + + file(APPEND ${generated_file_tmp} + "void ${_header_name}_LoadAllPythonModules(void)\n{\n") + foreach(_module ${static_mod_list}) + file(APPEND ${generated_file_tmp} " ${_header_name}_${_module}();\n") + endforeach() + file(APPEND ${generated_file_tmp} "}\n\n") + + set(_chunk "") + set(_chunk "${_chunk}#ifndef EXCLUDE_LOAD_ALL_FUNCTION\n") + set(_chunk "${_chunk}void CMakeLoadAllPythonModules(void)\n") + set(_chunk "${_chunk}{\n") + set(_chunk "${_chunk} ${_header_name}_LoadAllPythonModules();\n") + set(_chunk "${_chunk}}\n") + set(_chunk "${_chunk}#endif /* !EXCLUDE_LOAD_ALL_FUNCTION */\n\n") + + set(_chunk "${_chunk}#ifndef EXCLUDE_PY_INIT_WRAPPER\n") + set(_chunk "${_chunk}static void Py_Initialize_Wrapper()\n") + set(_chunk "${_chunk}{\n") + set(_chunk "${_chunk} ${_header_name}_LoadAllPythonModules();\n") + set(_chunk "${_chunk} Py_Initialize();\n") + set(_chunk "${_chunk}}\n") + set(_chunk "${_chunk}#define Py_Initialize Py_Initialize_Wrapper\n") + set(_chunk "${_chunk}#endif /* !EXCLUDE_PY_INIT_WRAPPER */\n\n") + + set(_chunk "${_chunk}#endif /* !${_header_name_upper} */\n") + file(APPEND ${generated_file_tmp} "${_chunk}") + + # with configure_file() cmake complains that you may not use a file created + # using file(WRITE) as input file for configure_file() + execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${generated_file_tmp}" "${generated_file}" + OUTPUT_QUIET ERROR_QUIET) + + set(_header_output_var ${_name}) + if(_args_HEADER_OUTPUT_VAR) + set(_header_output_var ${_args_HEADER_OUTPUT_VAR}) + endif() + set(${_header_output_var} ${generated_file} PARENT_SCOPE) + + set(_include_dir_var ${_name}_INCLUDE_DIRS) + if(_args_INCLUDE_DIR_OUTPUT_VAR) + set(_include_dir_var ${_args_INCLUDE_DIR_OUTPUT_VAR}) + endif() + set(${_include_dirs_var} ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE) +endfunction() + +include(UsePythonExtensions) diff --git a/cmake/Modules/UseCython.cmake b/cmake/Modules/UseCython.cmake new file mode 100644 index 000000000..4e0fa7907 --- /dev/null +++ b/cmake/Modules/UseCython.cmake @@ -0,0 +1,383 @@ +#.rst: +# +# The following functions are defined: +# +# .. cmake:command:: add_cython_target +# +# Create a custom rule to generate the source code for a Python extension module +# using cython. +# +# add_cython_target( [] +# [EMBED_MAIN] +# [C | CXX] +# [PY2 | PY3] +# [OUTPUT_VAR ]) +# +# ```` is the name of the new target, and ```` +# is the path to a cython source file. Note that, despite the name, no new +# targets are created by this function. Instead, see ``OUTPUT_VAR`` for +# retrieving the path to the generated source for subsequent targets. +# +# If only ```` is provided, and it ends in the ".pyx" extension, then it +# is assumed to be the ````. The name of the input without the +# extension is used as the target name. If only ```` is provided, and it +# does not end in the ".pyx" extension, then the ```` is assumed to +# be ``.pyx``. +# +# The Cython include search path is amended with any entries found in the +# ``INCLUDE_DIRECTORIES`` property of the directory containing the +# ```` file. Use ``include_directories`` to add to the Cython +# include search path. +# +# Options: +# +# ``EMBED_MAIN`` +# Embed a main() function in the generated output (for stand-alone +# applications that initialize their own Python runtime). +# +# ``C | CXX`` +# Force the generation of either a C or C++ file. By default, a C file is +# generated, unless the C language is not enabled for the project; in this +# case, a C++ file is generated by default. +# +# ``PY2 | PY3`` +# Force compilation using either Python-2 or Python-3 syntax and code +# semantics. By default, Python-2 syntax and semantics are used if the major +# version of Python found is 2. Otherwise, Python-3 syntax and semantics are +# used. +# +# ``OUTPUT_VAR `` +# Set the variable ```` in the parent scope to the path to the +# generated source file. By default, ```` is used as the output +# variable name. +# +# Defined variables: +# +# ```` +# The path of the generated source file. +# +# Cache variables that affect the behavior include: +# +# ``CYTHON_ANNOTATE`` +# Whether to create an annotated .html file when compiling. +# +# ``CYTHON_FLAGS`` +# Additional flags to pass to the Cython compiler. +# +# Example usage +# ^^^^^^^^^^^^^ +# +# .. code-block:: cmake +# +# find_package(Cython) +# +# # Note: In this case, either one of these arguments may be omitted; their +# # value would have been inferred from that of the other. +# add_cython_target(cy_code cy_code.pyx) +# +# add_library(cy_code MODULE ${cy_code}) +# target_link_libraries(cy_code ...) +# +#============================================================================= +# Copyright 2011 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +# Configuration options. +set(CYTHON_ANNOTATE OFF + CACHE BOOL "Create an annotated .html file when compiling *.pyx.") + +set(CYTHON_FLAGS "" CACHE STRING + "Extra flags to the cython compiler.") +mark_as_advanced(CYTHON_ANNOTATE CYTHON_FLAGS) + +set(CYTHON_CXX_EXTENSION "cxx") +set(CYTHON_C_EXTENSION "c") + +get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES) + +function(add_cython_target _name) + set(options EMBED_MAIN C CXX PY2 PY3) + set(options1 OUTPUT_VAR) + cmake_parse_arguments(_args "${options}" "${options1}" "" ${ARGN}) + + list(GET _args_UNPARSED_ARGUMENTS 0 _arg0) + + # if provided, use _arg0 as the input file path + if(_arg0) + set(_source_file ${_arg0}) + + # otherwise, must determine source file from name, or vice versa + else() + get_filename_component(_name_ext "${_name}" EXT) + + # if extension provided, _name is the source file + if(_name_ext) + set(_source_file ${_name}) + get_filename_component(_name "${_source_file}" NAME_WE) + + # otherwise, assume the source file is ${_name}.pyx + else() + set(_source_file ${_name}.pyx) + endif() + endif() + + set(_embed_main FALSE) + + if("C" IN_LIST languages) + set(_output_syntax "C") + elseif("CXX" IN_LIST languages) + set(_output_syntax "CXX") + else() + message(FATAL_ERROR "Either C or CXX must be enabled to use Cython") + endif() + + if(_args_EMBED_MAIN) + set(_embed_main TRUE) + endif() + + if(_args_C) + set(_output_syntax "C") + endif() + + if(_args_CXX) + set(_output_syntax "CXX") + endif() + + # Doesn't select an input syntax - Cython + # defaults to 2 for Cython 2 and 3 for Cython 3 + set(_input_syntax "default") + + if(_args_PY2) + set(_input_syntax "PY2") + endif() + + if(_args_PY3) + set(_input_syntax "PY3") + endif() + + set(embed_arg "") + if(_embed_main) + set(embed_arg "--embed") + endif() + + set(cxx_arg "") + set(extension "c") + if(_output_syntax STREQUAL "CXX") + set(cxx_arg "--cplus") + set(extension "cxx") + endif() + + set(py_version_arg "") + if(_input_syntax STREQUAL "PY2") + set(py_version_arg "-2") + elseif(_input_syntax STREQUAL "PY3") + set(py_version_arg "-3") + endif() + + set(generated_file "${CMAKE_CURRENT_BINARY_DIR}/${_name}.${extension}") + set_source_files_properties(${generated_file} PROPERTIES GENERATED TRUE) + + set(_output_var ${_name}) + if(_args_OUTPUT_VAR) + set(_output_var ${_args_OUTPUT_VAR}) + endif() + set(${_output_var} ${generated_file} PARENT_SCOPE) + + file(RELATIVE_PATH generated_file_relative + ${CMAKE_BINARY_DIR} ${generated_file}) + + set(comment "Generating ${_output_syntax} source ${generated_file_relative}") + set(cython_include_directories "") + set(pxd_dependencies "") + set(c_header_dependencies "") + + # Get the include directories. + get_directory_property(cmake_include_directories + DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + INCLUDE_DIRECTORIES) + list(APPEND cython_include_directories ${cmake_include_directories}) + + # Determine dependencies. + # Add the pxd file with the same basename as the given pyx file. + get_source_file_property(pyx_location ${_source_file} LOCATION) + get_filename_component(pyx_path ${pyx_location} PATH) + get_filename_component(pyx_file_basename ${_source_file} NAME_WE) + unset(corresponding_pxd_file CACHE) + find_file(corresponding_pxd_file ${pyx_file_basename}.pxd + PATHS "${pyx_path}" ${cmake_include_directories} + NO_DEFAULT_PATH) + if(corresponding_pxd_file) + list(APPEND pxd_dependencies "${corresponding_pxd_file}") + endif() + + # pxd files to check for additional dependencies + set(pxds_to_check "${_source_file}" "${pxd_dependencies}") + set(pxds_checked "") + set(number_pxds_to_check 1) + while(number_pxds_to_check GREATER 0) + foreach(pxd ${pxds_to_check}) + list(APPEND pxds_checked "${pxd}") + list(REMOVE_ITEM pxds_to_check "${pxd}") + + # look for C headers + file(STRINGS "${pxd}" extern_from_statements + REGEX "cdef[ ]+extern[ ]+from.*$") + foreach(statement ${extern_from_statements}) + # Had trouble getting the quote in the regex + string(REGEX REPLACE + "cdef[ ]+extern[ ]+from[ ]+[\"]([^\"]+)[\"].*" "\\1" + header "${statement}") + unset(header_location CACHE) + find_file(header_location ${header} PATHS ${cmake_include_directories}) + if(header_location) + list(FIND c_header_dependencies "${header_location}" header_idx) + if(${header_idx} LESS 0) + list(APPEND c_header_dependencies "${header_location}") + endif() + endif() + endforeach() + + # check for pxd dependencies + # Look for cimport statements. + set(module_dependencies "") + file(STRINGS "${pxd}" cimport_statements REGEX cimport) + foreach(statement ${cimport_statements}) + if(${statement} MATCHES from) + string(REGEX REPLACE + "from[ ]+([^ ]+).*" "\\1" + module "${statement}") + else() + string(REGEX REPLACE + "cimport[ ]+([^ ]+).*" "\\1" + module "${statement}") + endif() + list(APPEND module_dependencies ${module}) + endforeach() + + # check for pxi dependencies + # Look for include statements. + set(include_dependencies "") + file(STRINGS "${pxd}" include_statements REGEX include) + foreach(statement ${include_statements}) + string(REGEX REPLACE + "include[ ]+[\"]([^\"]+)[\"].*" "\\1" + module "${statement}") + list(APPEND include_dependencies ${module}) + endforeach() + + list(REMOVE_DUPLICATES module_dependencies) + list(REMOVE_DUPLICATES include_dependencies) + + # Add modules to the files to check, if appropriate. + foreach(module ${module_dependencies}) + unset(pxd_location CACHE) + find_file(pxd_location ${module}.pxd + PATHS "${pyx_path}" ${cmake_include_directories} + NO_DEFAULT_PATH) + if(pxd_location) + list(FIND pxds_checked ${pxd_location} pxd_idx) + if(${pxd_idx} LESS 0) + list(FIND pxds_to_check ${pxd_location} pxd_idx) + if(${pxd_idx} LESS 0) + list(APPEND pxds_to_check ${pxd_location}) + list(APPEND pxd_dependencies ${pxd_location}) + endif() # if it is not already going to be checked + endif() # if it has not already been checked + endif() # if pxd file can be found + endforeach() # for each module dependency discovered + + # Add includes to the files to check, if appropriate. + foreach(_include ${include_dependencies}) + unset(pxi_location CACHE) + find_file(pxi_location ${_include} + PATHS "${pyx_path}" ${cmake_include_directories} + NO_DEFAULT_PATH) + if(pxi_location) + list(FIND pxds_checked ${pxi_location} pxd_idx) + if(${pxd_idx} LESS 0) + list(FIND pxds_to_check ${pxi_location} pxd_idx) + if(${pxd_idx} LESS 0) + list(APPEND pxds_to_check ${pxi_location}) + list(APPEND pxd_dependencies ${pxi_location}) + endif() # if it is not already going to be checked + endif() # if it has not already been checked + endif() # if include file can be found + endforeach() # for each include dependency discovered + endforeach() # for each include file to check + + list(LENGTH pxds_to_check number_pxds_to_check) + endwhile() + + # Set additional flags. + set(annotate_arg "") + if(CYTHON_ANNOTATE) + set(annotate_arg "--annotate") + endif() + + set(cython_debug_arg "") + set(line_directives_arg "") + if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR + CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") + set(cython_debug_arg "--gdb") + set(line_directives_arg "--line-directives") + endif() + + # Include directory arguments. + list(REMOVE_DUPLICATES cython_include_directories) + set(include_directory_arg "") + foreach(_include_dir ${cython_include_directories}) + set(include_directory_arg + ${include_directory_arg} "--include-dir" "${_include_dir}") + endforeach() + + list(REMOVE_DUPLICATES pxd_dependencies) + list(REMOVE_DUPLICATES c_header_dependencies) + + string(REGEX REPLACE " " ";" CYTHON_FLAGS_LIST "${CYTHON_FLAGS}") + + # Add the command to run the compiler. + add_custom_command(OUTPUT ${generated_file} + COMMAND ${CYTHON_EXECUTABLE} + ARGS ${cxx_arg} ${include_directory_arg} ${py_version_arg} + ${embed_arg} ${annotate_arg} ${cython_debug_arg} + ${line_directives_arg} ${CYTHON_FLAGS_LIST} ${pyx_location} + --output-file ${generated_file} + DEPENDS ${_source_file} + ${pxd_dependencies} + IMPLICIT_DEPENDS ${_output_syntax} + ${c_header_dependencies} + COMMENT ${comment}) + + # NOTE(opadron): I thought about making a proper target, but after trying it + # out, I decided that it would be far too convenient to use the same name as + # the target for the extension module (e.g.: for single-file modules): + # + # ... + # add_cython_target(_module.pyx) + # add_library(_module ${_module}) + # ... + # + # The above example would not be possible since the "_module" target name + # would already be taken by the cython target. Since I can't think of a + # reason why someone would need the custom target instead of just using the + # generated file directly, I decided to leave this commented out. + # + # add_custom_target(${_name} DEPENDS ${generated_file}) + + # Remove their visibility to the user. + set(corresponding_pxd_file "" CACHE INTERNAL "") + set(header_location "" CACHE INTERNAL "") + set(pxd_location "" CACHE INTERNAL "") +endfunction() diff --git a/cmake/Modules/UsePythonExtensions.cmake b/cmake/Modules/UsePythonExtensions.cmake new file mode 100644 index 000000000..c411e20c4 --- /dev/null +++ b/cmake/Modules/UsePythonExtensions.cmake @@ -0,0 +1,320 @@ +#.rst: +# +# The following functions are defined: +# +# .. cmake:command:: add_python_library +# +# Add a library that contains a mix of C, C++, Fortran, Cython, F2PY, Template, +# and Tempita sources. The required targets are automatically generated to +# "lower" source files from their high-level representation to a file that the +# compiler can accept. +# +# +# add_python_library( +# SOURCES [source1 [source2 ...]] +# [INCLUDE_DIRECTORIES [dir1 [dir2 ...]] +# [LINK_LIBRARIES [lib1 [lib2 ...]] +# [DEPENDS [source1 [source2 ...]]]) +# +# +# Example usage +# ^^^^^^^^^^^^^ +# +# .. code-block:: cmake +# +# find_package(PythonExtensions) +# +# file(GLOB arpack_sources ARPACK/SRC/*.f ARPACK/UTIL/*.f) +# +# add_python_library(arpack_scipy +# SOURCES ${arpack_sources} +# ${g77_wrapper_sources} +# INCLUDE_DIRECTORIES ARPACK/SRC +# ) +# +# .. cmake:command:: add_python_extension +# +# Add a extension that contains a mix of C, C++, Fortran, Cython, F2PY, Template, +# and Tempita sources. The required targets are automatically generated to +# "lower" source files from their high-level representation to a file that the +# compiler can accept. +# +# +# add_python_extension( +# SOURCES [source1 [source2 ...]] +# [INCLUDE_DIRECTORIES [dir1 [dir2 ...]] +# [LINK_LIBRARIES [lib1 [lib2 ...]] +# [DEPENDS [source1 [source2 ...]]]) +# +# +# Example usage +# ^^^^^^^^^^^^^ +# +# .. code-block:: cmake +# +# find_package(PythonExtensions) +# +# file(GLOB arpack_sources ARPACK/SRC/*.f ARPACK/UTIL/*.f) +# +# add_python_extension(arpack_scipy +# SOURCES ${arpack_sources} +# ${g77_wrapper_sources} +# INCLUDE_DIRECTORIES ARPACK/SRC +# ) +# +# +#============================================================================= +# Copyright 2011 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +macro(_remove_whitespace _output) + string(REGEX REPLACE "[ \r\n\t]+" " " ${_output} "${${_output}}") + string(STRIP "${${_output}}" ${_output}) +endmacro() + +function(add_python_library _name) + set(options STATIC SHARED MODULE) + set(multiValueArgs SOURCES INCLUDE_DIRECTORIES LINK_LIBRARIES COMPILE_DEFINITIONS DEPENDS) + cmake_parse_arguments(_args "${options}" "" "${multiValueArgs}" ${ARGN} ) + + # Validate arguments to allow simpler debugging + if(NOT _args_SOURCES) + message( + FATAL_ERROR + "You have called add_python_library for library ${_name} without " + "any source files. This typically indicates a problem with " + "your CMakeLists.txt file" + ) + endif() + + # Initialize the list of sources + set(_sources ${_args_SOURCES}) + + # Generate targets for all *.src files + set(_processed ) + foreach(_source IN LISTS _sources) + if(${_source} MATCHES ".pyf.src$" OR ${_source} MATCHES "\\.f\\.src$") + if(NOT NumPy_FOUND) + message( + FATAL_ERROR + "NumPy is required to process *.src Template files" + ) + endif() + string(REGEX REPLACE "\\.[^.]*$" "" _source_we ${_source}) + add_custom_command( + OUTPUT ${_source_we} + COMMAND ${NumPy_FROM_TEMPLATE_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/${_source} + ${CMAKE_CURRENT_BINARY_DIR}/${_source_we} + DEPENDS ${_source} ${_args_DEPENDS} + COMMENT "Generating ${_source_we} from template ${_source}" + ) + list(APPEND _processed ${_source_we}) + elseif(${_source} MATCHES "\\.c\\.src$") + if(NOT NumPy_FOUND) + message( + FATAL_ERROR + "NumPy is required to process *.src Template files" + ) + endif() + string(REGEX REPLACE "\\.[^.]*$" "" _source_we ${_source}) + add_custom_command( + OUTPUT ${_source_we} + COMMAND ${NumPy_CONV_TEMPLATE_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/${_source} + ${CMAKE_CURRENT_BINARY_DIR}/${_source_we} + DEPENDS ${_source} ${_args_DEPENDS} + COMMENT "Generating ${_source_we} from template ${_source}" + ) + list(APPEND _processed ${_source_we}) + elseif(${_source} MATCHES "\\.pyx\\.in$") + if(NOT Cython_FOUND) + message( + FATAL_ERROR + "Cython is required to process *.in Tempita files" + ) + endif() + string(REGEX REPLACE "\\.[^.]*$" "" _source_we ${_source}) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/${_source} + ${CMAKE_CURRENT_BINARY_DIR}/${_source} + COPYONLY + ) + set(_tempita_command + " + import os; + import sys; + from Cython.Tempita import Template; + cwd = os.getcwd(); + open(os.path.join(cwd, '${_source_we}'), 'w+') + .write( + Template.from_filename(os.path.join(cwd, '${_source}'), + encoding=sys.getdefaultencoding()).substitute() + ) + " + ) + _remove_whitespace(_tempita_command) + add_custom_command( + OUTPUT ${_source_we} + COMMAND ${PYTHON_EXECUTABLE} -c "${_tempita_command}" + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${_source}" + ${_args_DEPENDS} + ) + list(APPEND _processed ${_source_we}) + else() + list(APPEND _processed ${_source}) + endif() + endforeach() + set(_sources ${_processed}) + + # If we're building a Python extension and we're given only Fortran sources, + # We can conclude that we need to generate a Fortran interface file + list(FILTER _processed EXCLUDE REGEX "(\\.f|\\.f90)$") + if(NOT _processed AND _args_MODULE) + if(NOT NumPy_FOUND) + message( + FATAL_ERROR + "NumPy is required to process *.pyf F2PY files" + ) + endif() + set(_sources_abs ) + foreach(_source IN LISTS _sources) + if(NOT IS_ABSOLUTE ${_source}) + set(_source ${CMAKE_CURRENT_SOURCE_DIR}/${_source}) + endif() + list(APPEND _sources_abs ${_source}) + endforeach() + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_name}.pyf + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${F2PY_EXECUTABLE} + ARGS -h ${_name}.pyf -m ${_name} --overwrite-signature + ${_sources_abs} + DEPENDS ${_sources} ${_args_DEPENDS} + COMMENT "Generating ${_name} Fortran interface file" + ) + list(APPEND _sources ${_name}.pyf) + endif() + + # Are there F2PY targets? + set(_has_f2py_targets OFF) + set(_has_cython_targets OFF) + + # Generate targets for all *.pyx and *.pyf files + set(_processed ) + foreach(_source IN LISTS _sources) + if(${_source} MATCHES \\.pyx$) + if(NOT Cython_FOUND) + message( + FATAL_ERROR + "Cython is required to process *.pyx Cython files" + ) + endif() + string(REGEX REPLACE "\\.[^.]*$" "" _pyx_target_name ${_source}) + set(_has_cython_targets ON) + add_cython_target(${_pyx_target_name} + ${_source} + OUTPUT_VAR _pyx_target_output + DEPENDS ${_args_DEPENDS} + ) + list(APPEND _processed ${_pyx_target_output}) + elseif(${_source} MATCHES \\.pyf$) + if(NOT NumPy_FOUND) + message( + FATAL_ERROR + "NumPy is required to process *.pyf F2PY files" + ) + endif() + string(REGEX REPLACE "\\.[^.]*$" "" _pyf_target_name ${_source}) + set(_has_f2py_targets ON) + add_f2py_target(${_pyf_target_name} + ${_source} + OUTPUT_VAR _pyf_target_output + DEPENDS ${_args_DEPENDS} + ) + list(APPEND _processed ${_pyf_target_output}) + else() + list(APPEND _processed ${_source}) + endif() + endforeach() + set(_sources ${_processed}) + + if(_args_SHARED) + add_library(${_name} SHARED ${_sources}) + elseif(_args_MODULE) + add_library(${_name} MODULE ${_sources}) + else() + # Assume static + add_library(${_name} STATIC ${_sources}) + endif() + + target_include_directories(${_name} PRIVATE ${_args_INCLUDE_DIRECTORIES}) + target_link_libraries(${_name} ${SKBUILD_LINK_LIBRARIES_KEYWORD} ${_args_LINK_LIBRARIES}) + + if(_has_f2py_targets) + target_include_directories(${_name} PRIVATE ${F2PY_INCLUDE_DIRS}) + target_link_libraries(${_name} ${SKBUILD_LINK_LIBRARIES_KEYWORD} ${F2PY_LIBRARIES}) + endif() + + if(_args_COMPILE_DEFINITIONS) + target_compile_definitions(${_name} PRIVATE ${_args_COMPILE_DEFINITIONS}) + endif() + + if(_args_DEPENDS) + add_custom_target( + "${_name}_depends" + DEPENDS ${_args_DEPENDS} + ) + add_dependencies(${_name} "${_name}_depends") + endif() +endfunction() + +function(add_python_extension _name) + # FIXME: make sure that extensions with the same name can happen + # in multiple directories + + set(multiValueArgs SOURCES INCLUDE_DIRECTORIES LINK_LIBRARIES COMPILE_DEFINITIONS DEPENDS) + cmake_parse_arguments(_args "" "" "${multiValueArgs}" ${ARGN} ) + + # Validate arguments to allow simpler debugging + if(NOT _args_SOURCES) + message( + FATAL_ERROR + "You have called add_python_extension for library ${_name} without " + "any source files. This typically indicates a problem with " + "your CMakeLists.txt file" + ) + endif() + + add_python_library(${_name} MODULE + SOURCES ${_args_SOURCES} + INCLUDE_DIRECTORIES ${_args_INCLUDE_DIRECTORIES} + LINK_LIBRARIES ${_args_LINK_LIBRARIES} + COMPILE_DEFINITIONS ${_args_COMPILE_DEFINITIONS} + DEPENDS ${_args_DEPENDS} + ) + python_extension_module(${_name}) + + file(RELATIVE_PATH _relative "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}") + if(_relative STREQUAL "") + set(_relative ".") + endif() + + install( + TARGETS ${_name} + LIBRARY DESTINATION "${_relative}" + RUNTIME DESTINATION "${_relative}" + ) +endfunction() diff --git a/cmake/Modules/targetLinkLibrariesWithDynamicLookup.cmake b/cmake/Modules/targetLinkLibrariesWithDynamicLookup.cmake new file mode 100644 index 000000000..a583f42cd --- /dev/null +++ b/cmake/Modules/targetLinkLibrariesWithDynamicLookup.cmake @@ -0,0 +1,597 @@ +#.rst: +# +# Public Functions +# ^^^^^^^^^^^^^^^^ +# +# The following functions are defined: +# +# .. cmake:command:: target_link_libraries_with_dynamic_lookup +# +# :: +# +# target_link_libraries_with_dynamic_lookup( []) +# +# +# Useful to "weakly" link a loadable module. For example, it should be used +# when compiling a loadable module when the symbols should be resolve from +# the run-time environment where the module is loaded, and not a specific +# system library. +# +# Like proper linking, except that the given ```` are not necessarily +# linked. Instead, the ```` is produced in a manner that allows for +# symbols unresolved within it to be resolved at runtime, presumably by the +# given ````. If such a target can be produced, the provided +# ```` are not actually linked. +# +# It links a library to a target such that the symbols are resolved at +# run-time not link-time. +# +# The linker is checked to see if it supports undefined +# symbols when linking a shared library. If it does then the library +# is not linked when specified with this function. +# +# On platforms that do not support weak-linking, this function works just +# like ``target_link_libraries``. +# +# .. note:: +# +# For OSX it uses ``undefined dynamic_lookup``. This is similar to using +# ``-shared`` on Linux where undefined symbols are ignored. +# +# For more details, see `blog `_ +# from Tim D. Smith. +# +# +# .. cmake:command:: check_dynamic_lookup +# +# Check if the linker requires a command line flag to allow leaving symbols +# unresolved when producing a target of type ```` that is +# weakly-linked against a dependency of type ````. +# +# ```` +# can be one of "STATIC", "SHARED", "MODULE", or "EXE". +# +# ```` +# can be one of "STATIC", "SHARED", or "MODULE". +# +# Long signature: +# +# :: +# +# check_dynamic_lookup( +# +# +# []) +# +# +# Short signature: +# +# :: +# +# check_dynamic_lookup() # set to "MODULE" +# # set to "SHARED" +# +# +# The result is cached between invocations and recomputed only when the value +# of CMake's linker flag list changes; ``CMAKE_STATIC_LINKER_FLAGS`` if +# ```` is "STATIC", and ``CMAKE_SHARED_LINKER_FLAGS`` otherwise. +# +# +# Defined variables: +# +# ```` +# Whether the current C toolchain supports weak-linking for target binaries of +# type ```` that are weakly-linked against a dependency target of +# type ````. +# +# ```` +# List of flags to add to the linker command to produce a working target +# binary of type ```` that is weakly-linked against a dependency +# target of type ````. +# +# ``HAS_DYNAMIC_LOOKUP__`` +# Cached, global alias for ```` +# +# ``DYNAMIC_LOOKUP_FLAGS__`` +# Cached, global alias for ```` +# +# +# Private Functions +# ^^^^^^^^^^^^^^^^^ +# +# The following private functions are defined: +# +# .. warning:: These functions are not part of the scikit-build API. They +# exist purely as an implementation detail and may change from version +# to version without notice, or even be removed. +# +# We mean it. +# +# +# .. cmake:command:: _get_target_type +# +# :: +# +# _get_target_type( ) +# +# +# Shorthand for querying an abbreviated version of the target type +# of the given ````. +# +# ```` is set to: +# +# - "STATIC" for a STATIC_LIBRARY, +# - "SHARED" for a SHARED_LIBRARY, +# - "MODULE" for a MODULE_LIBRARY, +# - and "EXE" for an EXECUTABLE. +# +# Defined variables: +# +# ```` +# The abbreviated version of the ````'s type. +# +# +# .. cmake:command:: _test_weak_link_project +# +# :: +# +# _test_weak_link_project( +# +# +# ) +# +# +# Attempt to compile and run a test project where a target of type +# ```` is weakly-linked against a dependency of type ````: +# +# - ```` can be one of "STATIC", "SHARED", "MODULE", or "EXE". +# - ```` can be one of "STATIC", "SHARED", or "MODULE". +# +# Defined variables: +# +# ```` +# Whether the current C toolchain can produce a working target binary of type +# ```` that is weakly-linked against a dependency target of type +# ````. +# +# ```` +# List of flags to add to the linker command to produce a working target +# binary of type ```` that is weakly-linked against a dependency +# target of type ````. +# + +function(_get_target_type result_var target) + set(target_type "SHARED_LIBRARY") + if(TARGET ${target}) + get_property(target_type TARGET ${target} PROPERTY TYPE) + endif() + + set(result "STATIC") + + if(target_type STREQUAL "STATIC_LIBRARY") + set(result "STATIC") + endif() + + if(target_type STREQUAL "SHARED_LIBRARY") + set(result "SHARED") + endif() + + if(target_type STREQUAL "MODULE_LIBRARY") + set(result "MODULE") + endif() + + if(target_type STREQUAL "EXECUTABLE") + set(result "EXE") + endif() + + set(${result_var} ${result} PARENT_SCOPE) +endfunction() + + +function(_test_weak_link_project + target_type + lib_type + can_weak_link_var + project_name) + + set(gnu_ld_ignore "-Wl,--unresolved-symbols=ignore-all") + set(osx_dynamic_lookup "-undefined dynamic_lookup") + set(no_flag "") + + if(CMAKE_CROSSCOMPILING) + set(link_flag_spec "no_flag") + set(link_flag "${${link_flag_spec}}") + set(test_skipping_reason "") + set(test_pass FALSE) + + if(APPLE AND NOT CMAKE_CROSSCOMPILING_EMULATOR) + set(link_flag_spec "osx_dynamic_lookup") + set(link_flag "${${link_flag_spec}}") + set(test_skipping_reason " (Cross compiling without emulator on macOS)") + set(test_pass TRUE) + endif() + + if(test_pass) + set(test_description "Weak Link ${target_type} -> ${lib_type} (${link_flag_spec})") + message(STATUS "Performing Test ${test_description} - Assuming Success${test_skipping_reason}") + set(${can_weak_link_var} ${test_pass} PARENT_SCOPE) + set(${project_name} ${link_flag} PARENT_SCOPE) + return() + endif() + endif() + + foreach(link_flag_spec gnu_ld_ignore osx_dynamic_lookup no_flag) + set(link_flag "${${link_flag_spec}}") + + set(test_project_dir "${PROJECT_BINARY_DIR}/CMakeTmp") + set(test_project_dir "${test_project_dir}/${project_name}") + set(test_project_dir "${test_project_dir}/${link_flag_spec}") + set(test_project_dir "${test_project_dir}/${target_type}") + set(test_project_dir "${test_project_dir}/${lib_type}") + + set(test_project_src_dir "${test_project_dir}/src") + set(test_project_bin_dir "${test_project_dir}/build") + + file(MAKE_DIRECTORY ${test_project_src_dir}) + file(MAKE_DIRECTORY ${test_project_bin_dir}) + + set(mod_type "STATIC") + set(link_mod_lib TRUE) + set(link_exe_lib TRUE) + set(link_exe_mod FALSE) + + if("${target_type}" STREQUAL "EXE") + set(link_exe_lib FALSE) + set(link_exe_mod TRUE) + else() + set(mod_type "${target_type}") + endif() + + if("${mod_type}" STREQUAL "MODULE") + set(link_mod_lib FALSE) + endif() + + + file(WRITE "${test_project_src_dir}/CMakeLists.txt" " + cmake_minimum_required(VERSION ${CMAKE_VERSION}) + project(${project_name} C) + + include_directories(${test_project_src_dir}) + + add_library(number ${lib_type} number.c) + add_library(counter ${mod_type} counter.c) + ") + + if("${mod_type}" STREQUAL "MODULE") + file(APPEND "${test_project_src_dir}/CMakeLists.txt" " + set_target_properties(counter PROPERTIES PREFIX \"\") + ") + endif() + + if(link_mod_lib) + file(APPEND "${test_project_src_dir}/CMakeLists.txt" " + target_link_libraries(counter ${SKBUILD_LINK_LIBRARIES_KEYWORD} number) + ") + elseif(NOT link_flag STREQUAL "") + file(APPEND "${test_project_src_dir}/CMakeLists.txt" " + set_target_properties(counter PROPERTIES LINK_FLAGS \"${link_flag}\") + ") + endif() + + file(APPEND "${test_project_src_dir}/CMakeLists.txt" " + add_executable(main main.c) + ") + + if(link_exe_lib) + file(APPEND "${test_project_src_dir}/CMakeLists.txt" " + target_link_libraries(main ${SKBUILD_LINK_LIBRARIES_KEYWORD} number) + ") + elseif(NOT link_flag STREQUAL "") + file(APPEND "${test_project_src_dir}/CMakeLists.txt" " + target_link_libraries(main ${SKBUILD_LINK_LIBRARIES_KEYWORD} \"${link_flag}\") + ") + endif() + + if(link_exe_mod) + file(APPEND "${test_project_src_dir}/CMakeLists.txt" " + target_link_libraries(main ${SKBUILD_LINK_LIBRARIES_KEYWORD} counter) + ") + else() + file(APPEND "${test_project_src_dir}/CMakeLists.txt" " + target_link_libraries(main ${SKBUILD_LINK_LIBRARIES_KEYWORD} \"${CMAKE_DL_LIBS}\") + ") + endif() + + file(WRITE "${test_project_src_dir}/number.c" " + #include + + static int _number; + void set_number(int number) { _number = number; } + int get_number() { return _number; } + ") + + file(WRITE "${test_project_src_dir}/number.h" " + #ifndef _NUMBER_H + #define _NUMBER_H + extern void set_number(int); + extern int get_number(void); + #endif + ") + + file(WRITE "${test_project_src_dir}/counter.c" " + #include + int count() { + int result = get_number(); + set_number(result + 1); + return result; + } + ") + + file(WRITE "${test_project_src_dir}/counter.h" " + #ifndef _COUNTER_H + #define _COUNTER_H + extern int count(void); + #endif + ") + + file(WRITE "${test_project_src_dir}/main.c" " + #include + #include + #include + ") + + if(NOT link_exe_mod) + file(APPEND "${test_project_src_dir}/main.c" " + #include + ") + endif() + + file(APPEND "${test_project_src_dir}/main.c" " + int my_count() { + int result = get_number(); + set_number(result + 1); + return result; + } + + int main(int argc, char **argv) { + int result; + ") + + if(NOT link_exe_mod) + file(APPEND "${test_project_src_dir}/main.c" " + void *counter_module; + int (*count)(void); + + counter_module = dlopen(\"./counter.so\", RTLD_LAZY | RTLD_GLOBAL); + if(!counter_module) goto error; + + count = dlsym(counter_module, \"count\"); + if(!count) goto error; + ") + endif() + + file(APPEND "${test_project_src_dir}/main.c" " + result = count() != 0 ? EXIT_FAILURE : + my_count() != 1 ? EXIT_FAILURE : + my_count() != 2 ? EXIT_FAILURE : + count() != 3 ? EXIT_FAILURE : + count() != 4 ? EXIT_FAILURE : + count() != 5 ? EXIT_FAILURE : + my_count() != 6 ? EXIT_FAILURE : EXIT_SUCCESS; + ") + + if(NOT link_exe_mod) + file(APPEND "${test_project_src_dir}/main.c" " + goto done; + error: + fprintf(stderr, \"Error occurred:\\n %s\\n\", dlerror()); + result = 1; + + done: + if(counter_module) dlclose(counter_module); + ") + endif() + + file(APPEND "${test_project_src_dir}/main.c" " + return result; + } + ") + + set(_rpath_arg) + if(APPLE AND ${CMAKE_VERSION} VERSION_GREATER 2.8.11) + set(_rpath_arg "-DCMAKE_MACOSX_RPATH='${CMAKE_MACOSX_RPATH}'") + endif() + + try_compile(project_compiles + "${test_project_bin_dir}" + "${test_project_src_dir}" + "${project_name}" + CMAKE_FLAGS + "-DCMAKE_SHARED_LINKER_FLAGS='${CMAKE_SHARED_LINKER_FLAGS}'" + "-DCMAKE_ENABLE_EXPORTS=ON" + ${_rpath_arg} + OUTPUT_VARIABLE compile_output) + + set(project_works 1) + set(run_output) + + if(project_compiles) + execute_process(COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} + "${test_project_bin_dir}/main" + WORKING_DIRECTORY "${test_project_bin_dir}" + RESULT_VARIABLE project_works + OUTPUT_VARIABLE run_output + ERROR_VARIABLE run_output) + endif() + + set(test_description + "Weak Link ${target_type} -> ${lib_type} (${link_flag_spec})") + + if(project_works EQUAL 0) + set(project_works TRUE) + message(STATUS "Performing Test ${test_description} - Success") + else() + set(project_works FALSE) + message(STATUS "Performing Test ${test_description} - Failed") + file(APPEND ${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Performing Test ${test_description} failed with the " + "following output:\n" + "BUILD\n-----\n${compile_output}\nRUN\n---\n${run_output}\n") + endif() + + set(${can_weak_link_var} ${project_works} PARENT_SCOPE) + if(project_works) + set(${project_name} ${link_flag} PARENT_SCOPE) + break() + endif() + endforeach() +endfunction() + +function(check_dynamic_lookup) + # Two signatures are supported: + + if(ARGC EQUAL "1") + # + # check_dynamic_lookup() + # + set(target_type "MODULE") + set(lib_type "SHARED") + set(has_dynamic_lookup_var "${ARGV0}") + set(link_flags_var "unused") + + elseif(ARGC GREATER "2") + # + # check_dynamic_lookup( + # + # + # []) + # + set(target_type "${ARGV0}") + set(lib_type "${ARGV1}") + set(has_dynamic_lookup_var "${ARGV2}") + if(ARGC EQUAL "3") + set(link_flags_var "unused") + else() + set(link_flags_var "${ARGV3}") + endif() + else() + message(FATAL_ERROR "missing arguments") + endif() + + _check_dynamic_lookup( + ${target_type} + ${lib_type} + ${has_dynamic_lookup_var} + ${link_flags_var} + ) + set(${has_dynamic_lookup_var} ${${has_dynamic_lookup_var}} PARENT_SCOPE) + if(NOT "x${link_flags_var}x" STREQUAL "xunusedx") + set(${link_flags_var} ${${link_flags_var}} PARENT_SCOPE) + endif() +endfunction() + +function(_check_dynamic_lookup + target_type + lib_type + has_dynamic_lookup_var + link_flags_var + ) + + # hash the CMAKE_FLAGS passed and check cache to know if we need to rerun + if("${target_type}" STREQUAL "STATIC") + string(MD5 cmake_flags_hash "${CMAKE_STATIC_LINKER_FLAGS}") + else() + string(MD5 cmake_flags_hash "${CMAKE_SHARED_LINKER_FLAGS}") + endif() + + set(cache_var "HAS_DYNAMIC_LOOKUP_${target_type}_${lib_type}") + set(cache_hash_var "HAS_DYNAMIC_LOOKUP_${target_type}_${lib_type}_hash") + set(result_var "DYNAMIC_LOOKUP_FLAGS_${target_type}_${lib_type}") + + if( NOT DEFINED ${cache_hash_var} + OR NOT "${${cache_hash_var}}" STREQUAL "${cmake_flags_hash}") + unset(${cache_var} CACHE) + endif() + + if(NOT DEFINED ${cache_var}) + + if(CMAKE_CROSSCOMPILING AND NOT CMAKE_CROSSCOMPILING_EMULATOR) + set(skip_test TRUE) + endif() + + _test_weak_link_project(${target_type} + ${lib_type} + has_dynamic_lookup + link_flags) + + set(caveat " (when linking ${target_type} against ${lib_type})") + + set(${cache_var} "${has_dynamic_lookup}" + CACHE BOOL + "linker supports dynamic lookup for undefined symbols${caveat}") + mark_as_advanced(${cache_var}) + + set(${result_var} "${link_flags}" + CACHE STRING + "linker flags for dynamic lookup${caveat}") + mark_as_advanced(${result_var}) + + set(${cache_hash_var} "${cmake_flags_hash}" + CACHE INTERNAL "hashed flags for ${cache_var} check") + endif() + + set(${has_dynamic_lookup_var} "${${cache_var}}" PARENT_SCOPE) + set(${link_flags_var} "${${result_var}}" PARENT_SCOPE) +endfunction() + +function(target_link_libraries_with_dynamic_lookup target) + _get_target_type(target_type ${target}) + + set(link_props) + set(link_items) + set(link_libs) + + foreach(lib ${ARGN}) + _get_target_type(lib_type ${lib}) + check_dynamic_lookup(${target_type} + ${lib_type} + has_dynamic_lookup + dynamic_lookup_flags) + + if(has_dynamic_lookup) + if(dynamic_lookup_flags) + if("${target_type}" STREQUAL "EXE") + list(APPEND link_items "${dynamic_lookup_flags}") + else() + list(APPEND link_props "${dynamic_lookup_flags}") + endif() + endif() + elseif(${lib} MATCHES "(debug|optimized|general)") + # See gh-255 + else() + list(APPEND link_libs "${lib}") + endif() + endforeach() + + if(link_props) + list(REMOVE_DUPLICATES link_props) + endif() + + if(link_items) + list(REMOVE_DUPLICATES link_items) + endif() + + if(link_libs) + list(REMOVE_DUPLICATES link_libs) + endif() + + if(link_props) + set_target_properties(${target} + PROPERTIES LINK_FLAGS "${link_props}") + endif() + + set(links "${link_items}" "${link_libs}") + if(links) + target_link_libraries(${target} ${SKBUILD_LINK_LIBRARIES_KEYWORD} "${links}") + endif() +endfunction() diff --git a/pyproject.toml b/pyproject.toml index e445532a6..eb4616479 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,24 +1,69 @@ +[project] +name = "swiftest" +version = "2023.9.0" +authors=[ + {name = 'David A. Minton', email='daminton@purdue.edu'}, + {name = 'Carlisle Wishard'}, + {name = 'Jennifer Pouplin'}, + {name = 'Jake Elliott'}, + {name = 'Dana Singh'}, + {name = 'Kaustub Anand'}, +] +maintainers = [ + {name = 'David A. Minton', email='daminton@purdue.edu'}, +] +readme = "README.md" +requires-python=">=3.8" +license={file = "LICENSE.txt"} +classifiers=[ +'Development Status :: 3 - Alpha', +'Intended Audience :: Science/Research', +'Topic :: Scientific/Engineering :: Astronomy', +'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)', +'Programming Language :: Python :: 3', +] +keywords=['astronomy','astrophysics', 'planetary', 'nbody integrator', 'symplectic', 'wisdom-holman'] +dependencies = [ + 'numpy>=1.24.3', + 'scipy>=1.10.1', + 'xarray>=2022.11.0', + 'dask>=2022.1', + 'distributed>=2022.1', + 'bottleneck>=1.3.5', + 'h5netcdf>=1.0.2', + 'netcdf4>=1.6.2', + 'matplotlib>=3.7.1', + 'astropy>=5.1', + 'astroquery>=0.4.6', + 'tqdm>=4.65.0', + 'cython>=3.0.0', +] + +[project.urls] +Repository = 'https://github.itap.purdue.edu/MintonGroup/swiftest' + [build-system] requires = [ - "setuptools>=42", - "scikit-build>=0.17", - "cmake>=3.5.0", + "scikit-build-core", "cython>=3.0.0", - "ninja", "pytest", ] -build-backend = "setuptools.build_meta" +build-backend = "scikit_build_core.build" + +[tool.scikit-build] +cmake.args = ["-DBUILD_SHARED_LIBS=ON","-DUSE_SIMD=OFF"] +sdist.include = ["src/globals/globals_module.f90.in","swiftest/*.py","swiftest/*.pyx","swiftest/*.h"] [tool.cibuildwheel] -environment = {SKBUILD_CONFIGURE_OPTIONS="-DBUILD_SHARED_LIBS=ON -DUSE_SIMD=OFF"} test-command = "pytest {package}/tests" -test-requires = ['pytest','cython'] +test-requires = ['pytest'] test-skip = "cp312-*" skip = "pp* *i686 *-manylinux_i686 *_ppc64le *_s390x *-musllinux* *-win32" +build-verbosity = 1 [tool.cibuildwheel.linux] -environment = {FFLAGS="${FFLAGS} -fPIC", CFLAGS="${CFLAGS} -fPIC", LDFLAGS="${LDFLAGS} -fPIE", LIBS="-lgomp"} +repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel}" +environment = {NETCDF_FORTRAN_HOME="/usr/local", NETCDF_INCLUDE="/usr/local/include", LD_LIBRARY_PATH="/usr/local/lib:/project/lib", CPATH="/usr/local/include:/project/include"} before-all = [ - "yum install doxygen libxml2-devel -y || apt-get install doxygen libxml2-dev -y", - "buildscripts/build_dependencies.sh -p /usr/local", + "yum install -y epel-release && yum install -y netcdf-fortran netcdf-devel || apt-get install -y netcdf-fortran", ] diff --git a/setup.py b/setup.py deleted file mode 100644 index 2d6141ffa..000000000 --- a/setup.py +++ /dev/null @@ -1,64 +0,0 @@ -""" - Copyright 2022 - David Minton, Carlisle Wishard, Jennifer Pouplin, Jake Elliott, & Dana Singh - This file is part of Swiftest. - Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License - as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY - without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along with Swiftest. - If not, see: https://www.gnu.org/licenses. -""" - -from skbuild import setup -from pathlib import Path - -with open('version.txt') as version_file: - version = version_file.read().strip() - -setup(name='swiftest', - version=version, - author='David A. Minton', - author_email='daminton@purdue.edu', - url='https://github.itap.purdue.edu/MintonGroup/swiftest', - long_description=Path("README.md").read_text(encoding="utf-8"), - long_description_content_type="text/markdown", - python_requires=">=3.8", - license="GPLv3", - classifiers=[ - # How mature is this project? Common values are - # 3 - Alpha - # 4 - Beta - # 5 - Production/Stable - 'Development Status :: 3 - Alpha', - - # Indicate who your project is intended for - 'Intended Audience :: Science/Research', - 'Topic :: Scientific/Engineering :: Astronomy', - - # Pick your license as you wish (should match "license" above) - 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)', - - # Specify the Python versions you support here. In particular, ensure - # that you indicate whether you support Python 2, Python 3 or both. - 'Programming Language :: Python :: 3', - ], - keywords='astronomy astrophysics planetary nbody integrator symplectic wisdom-holman', - install_requires= [ - 'numpy>=1.24.3', - 'scipy>=1.10.1', - 'xarray>=2022.11.0', - 'dask>=2022.1', - 'distributed>=2022.1', - 'bottleneck>=1.3.5', - 'h5netcdf>=1.0.2', - 'netcdf4>=1.6.2', - 'matplotlib>=3.7.1', - 'astropy>=5.1', - 'astroquery>=0.4.6', - 'tqdm>=4.65.0', - 'cython>=3.0.0', - ], - packages=['swiftest'], - test_suite="swiftest.tests", - ) diff --git a/src/globals/globals_module.f90 b/src/globals/globals_module.f90 index ece47b07f..a12c018ce 100644 --- a/src/globals/globals_module.f90 +++ b/src/globals/globals_module.f90 @@ -48,7 +48,7 @@ module globals integer(I4B), parameter :: UPPERCASE_OFFSET = iachar('A') - iachar('a') !! ASCII character set parameter for lower to upper !! conversion - offset between upper and lower - character(*), parameter :: VERSION = "2023.8.1" !! Swiftest version + character(*), parameter :: VERSION = "2023.9.0" !! Swiftest version !> Symbolic name for integrator types character(*), parameter :: UNKNOWN_INTEGRATOR = "UKNOWN INTEGRATOR" diff --git a/version.txt b/version.txt index 4d449f4ac..882e30299 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -2023.8.1 \ No newline at end of file +2023.9.0 \ No newline at end of file From 37c7ca9a5091783887bd6bf8488f054b13fccba8 Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Thu, 7 Sep 2023 10:57:10 -0400 Subject: [PATCH 13/22] Fixed some remaining issues with the Linux build scripts --- buildscripts/build_dependencies.sh | 41 ---------------------------- buildscripts/build_hdf5.sh | 23 ++++++++++++++++ buildscripts/build_netcdf-c.sh | 13 +++++++++ buildscripts/build_netcdf-fortran.sh | 10 ++++++- buildscripts/build_zlib.sh | 13 +++++++++ pyproject.toml | 3 +- 6 files changed, 60 insertions(+), 43 deletions(-) diff --git a/buildscripts/build_dependencies.sh b/buildscripts/build_dependencies.sh index 5fc544450..645465d22 100755 --- a/buildscripts/build_dependencies.sh +++ b/buildscripts/build_dependencies.sh @@ -17,47 +17,6 @@ set -a ARGS=$@ . ${SCRIPT_DIR}/_build_getopts.sh ${ARGS} -ZLIB_VER="1.3" -HDF5_VER="1_14_2" -NC_VER="4.9.2" -NF_VER="4.6.1" - -printf "*********************************************************\n" -printf "* FETCHING DEPENCENCY SOURCES *\n" -printf "*********************************************************\n" -printf "Copying files to ${DEPENDENCY_DIR}\n" -mkdir -p ${DEPENDENCY_DIR} -if [ ! -d ${DEPENDENCY_DIR}/zlib-${ZLIB_VER} ]; then - [ -d ${DEPENDENCY_DIR}/zlib-* ] && rm -rf ${DEPENDENCY_DIR}/zlib-* - curl -L https://github.com/madler/zlib/releases/download/v${ZLIB_VER}/zlib-${ZLIB_VER}.tar.gz | tar xvz -C ${DEPENDENCY_DIR} -fi - -printf "Checking if HDF5 source exists\n" -if [[ (-d ${DEPENDENCY_DIR}/hdfsrc) && (-f ${DEPENDENCY_DIR}/hdfsrc/README.md) ]]; then - OLDVER=$(grep version ${DEPENDENCY_DIR}/hdfsrc/README.md | awk '{print $3}' | sed 's/\./_/g') - printf "Existing copy of HDF5 source detected\n" - printf "Existing version : ${OLDVER}\n" - printf "Requested version: ${HDF5_VER}\n" - if [ "$OLDVER" != "${HDF5_VER}" ]; then - printf "Existing version of HDF5 source doesn't match requested. Deleting\n" - rm -rf ${DEPENDENCY_DIR}/hdfsrc - fi -fi - -if [ ! -d ${DEPENDENCY_DIR}/hdfsrc ]; then - curl -s -L https://github.com/HDFGroup/hdf5/releases/download/hdf5-${HDF5_VER}/hdf5-${HDF5_VER}.tar.gz | tar xvz -C ${DEPENDENCY_DIR} -fi - -if [ ! -d ${DEPENDENCY_DIR}/netcdf-c-${NC_VER} ]; then - [ -d ${DEPENDENCY_DIR}/netcdf-c-* ] && rm -rf ${DEPENDENCY_DIR}/netcdf-c-* - curl -s -L https://github.com/Unidata/netcdf-c/archive/refs/tags/v${NC_VER}.tar.gz | tar xvz -C ${DEPENDENCY_DIR} -fi - -if [ ! -d ${DEPENDENCY_DIR}/netcdf-fortran-${NF_VER} ]; then - [ -d ${DEPENDENCY_DIR}/netcdf-fortran-* ] && rm -rf ${DEPENDENCY_DIR}/netcdf-fortran-* - curl -s -L https://github.com/Unidata/netcdf-fortran/archive/refs/tags/v${NF_VER}.tar.gz | tar xvz -C ${DEPENDENCY_DIR} -fi - cd $ROOT_DIR printf "*********************************************************\n" printf "* STARTING DEPENDENCY BUILD *\n" diff --git a/buildscripts/build_hdf5.sh b/buildscripts/build_hdf5.sh index 4fa633582..d351bd47d 100755 --- a/buildscripts/build_hdf5.sh +++ b/buildscripts/build_hdf5.sh @@ -15,6 +15,29 @@ set -a ARGS=$@ . ${SCRIPT_DIR}/_build_getopts.sh ${ARGS} +HDF5_VER="1_14_2" +printf "*********************************************************\n" +printf "* FETCHING HDF5 SOURCE *\n" +printf "*********************************************************\n" +printf "Copying files to ${DEPENDENCY_DIR}\n" + +printf "Checking if HDF5 source exists\n" +if [[ (-d ${DEPENDENCY_DIR}/hdfsrc) && (-f ${DEPENDENCY_DIR}/hdfsrc/README.md) ]]; then + OLDVER=$(grep version ${DEPENDENCY_DIR}/hdfsrc/README.md | awk '{print $3}' | sed 's/\./_/g') + printf "Existing copy of HDF5 source detected\n" + printf "Existing version : ${OLDVER}\n" + printf "Requested version: ${HDF5_VER}\n" + if [ "$OLDVER" != "${HDF5_VER}" ]; then + printf "Existing version of HDF5 source doesn't match requested. Deleting\n" + rm -rf ${DEPENDENCY_DIR}/hdfsrc + fi +fi + +if [ ! -d ${DEPENDENCY_DIR}/hdfsrc ]; then + curl -s -L https://github.com/HDFGroup/hdf5/releases/download/hdf5-${HDF5_VER}/hdf5-${HDF5_VER}.tar.gz | tar xvz -C ${DEPENDENCY_DIR} +fi + + printf "\n" printf "*********************************************************\n" printf "* BUILDING HDF5 LIBRARY *\n" diff --git a/buildscripts/build_netcdf-c.sh b/buildscripts/build_netcdf-c.sh index d11f39126..8f692fac1 100755 --- a/buildscripts/build_netcdf-c.sh +++ b/buildscripts/build_netcdf-c.sh @@ -16,6 +16,19 @@ set -a ARGS=$@ . ${SCRIPT_DIR}/_build_getopts.sh ${ARGS} + +NC_VER="4.9.2" + +printf "*********************************************************\n" +printf "* FETCHING NETCDF-C SOURCE *\n" +printf "*********************************************************\n" +printf "Copying files to ${DEPENDENCY_DIR}\n" + +if [ ! -d ${DEPENDENCY_DIR}/netcdf-c-${NC_VER} ]; then + [ -d ${DEPENDENCY_DIR}/netcdf-c-* ] && rm -rf ${DEPENDENCY_DIR}/netcdf-c-* + curl -s -L https://github.com/Unidata/netcdf-c/archive/refs/tags/v${NC_VER}.tar.gz | tar xvz -C ${DEPENDENCY_DIR} +fi + printf "\n" printf "*********************************************************\n" printf "* BUILDING NETCDF-C LIBRARY *\n" diff --git a/buildscripts/build_netcdf-fortran.sh b/buildscripts/build_netcdf-fortran.sh index 064903224..aea5e71aa 100755 --- a/buildscripts/build_netcdf-fortran.sh +++ b/buildscripts/build_netcdf-fortran.sh @@ -15,7 +15,15 @@ set -a ARGS=$@ . ${SCRIPT_DIR}/_build_getopts.sh ${ARGS} -LIBS="$(${PREFIX}/bin/nc-config --libs --static)" +NF_VER="4.6.1" +printf "*********************************************************\n" +printf "* FETCHING NETCDF-FORTRAN SOURCE *\n" +printf "*********************************************************\n" +printf "Copying files to ${DEPENDENCY_DIR}\n" +if [ ! -d ${DEPENDENCY_DIR}/netcdf-fortran-${NF_VER} ]; then + [ -d ${DEPENDENCY_DIR}/netcdf-fortran-* ] && rm -rf ${DEPENDENCY_DIR}/netcdf-fortran-* + curl -s -L https://github.com/Unidata/netcdf-fortran/archive/refs/tags/v${NF_VER}.tar.gz | tar xvz -C ${DEPENDENCY_DIR} +fi printf "\n" printf "*********************************************************\n" diff --git a/buildscripts/build_zlib.sh b/buildscripts/build_zlib.sh index 99571d8f3..e21b75b47 100755 --- a/buildscripts/build_zlib.sh +++ b/buildscripts/build_zlib.sh @@ -15,6 +15,19 @@ set -a ARGS=$@ . ${SCRIPT_DIR}/_build_getopts.sh ${ARGS} + +ZLIB_VER="1.3" + +printf "*********************************************************\n" +printf "* FETCHING ZLIB SOURCE *\n" +printf "*********************************************************\n" +printf "Copying files to ${DEPENDENCY_DIR}\n" +mkdir -p ${DEPENDENCY_DIR} +if [ ! -d ${DEPENDENCY_DIR}/zlib-${ZLIB_VER} ]; then + [ -d ${DEPENDENCY_DIR}/zlib-* ] && rm -rf ${DEPENDENCY_DIR}/zlib-* + curl -L https://github.com/madler/zlib/releases/download/v${ZLIB_VER}/zlib-${ZLIB_VER}.tar.gz | tar xvz -C ${DEPENDENCY_DIR} +fi + printf "*********************************************************\n" printf "* BUILDING ZLIB LIBRARY *\n" printf "*********************************************************\n" diff --git a/pyproject.toml b/pyproject.toml index eb4616479..433dfbcda 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,5 +65,6 @@ build-verbosity = 1 repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel}" environment = {NETCDF_FORTRAN_HOME="/usr/local", NETCDF_INCLUDE="/usr/local/include", LD_LIBRARY_PATH="/usr/local/lib:/project/lib", CPATH="/usr/local/include:/project/include"} before-all = [ - "yum install -y epel-release && yum install -y netcdf-fortran netcdf-devel || apt-get install -y netcdf-fortran", + "yum install doxygen libxml2-devel libcurl-devel -y", + "buildscripts/build_dependencies.sh -p /usr/local" ] From a91c0bdcbbf6b516b8c59aef30c453eb3062225f Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Thu, 7 Sep 2023 11:40:41 -0400 Subject: [PATCH 14/22] Skipping the 3.12 version for now as something is incompatible. --- pyproject.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 433dfbcda..25fbd2a2b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,8 +57,7 @@ sdist.include = ["src/globals/globals_module.f90.in","swiftest/*.py","swiftest/* [tool.cibuildwheel] test-command = "pytest {package}/tests" test-requires = ['pytest'] -test-skip = "cp312-*" -skip = "pp* *i686 *-manylinux_i686 *_ppc64le *_s390x *-musllinux* *-win32" +skip = "cp312-* pp* *i686 *-manylinux_i686 *_ppc64le *_s390x *-musllinux* *-win32" build-verbosity = 1 [tool.cibuildwheel.linux] From e01eb63b712b6f02885a95f4b2bb633e4a0c7b33 Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Thu, 7 Sep 2023 13:40:30 -0400 Subject: [PATCH 15/22] Added license file to .gitignore --- .gitignore | 1 + LICENSE.txt | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 LICENSE.txt diff --git a/.gitignore b/.gitignore index 9c5ee861f..e68502d0f 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ dump* *ipynb_checkpoints **/.DS_Store !version.txt +!LICENSE.txt !requirements.txt !pyproject.toml **/_skbuild diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 000000000..965bb4c26 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,10 @@ +Copyright 2023 - David Minton +The Swiftest development team: David Minton, Carlisle Wishard, Jennifer Pouplin, Jake Elliott, Dana Singh, & Kaustub Anand + +This file is part of Swiftest. +Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License +as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +You should have received a copy of the GNU General Public License along with Swiftest. +If not, see: https://www.gnu.org/licenses. \ No newline at end of file From 6aad7120179b2bdeabc4d56f98c8ba923f441ac3 Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Thu, 7 Sep 2023 15:49:05 -0400 Subject: [PATCH 16/22] Restructured MacOS build scripts and prepared for GitHub actions. --- .github/workflows/build_wheels.yml | 25 +++++++++ .gitignore | 1 + buildscripts/_build_getopts.sh | 23 +-------- buildscripts/build_dependencies.sh | 5 ++ buildscripts/build_macwheels.sh | 44 ---------------- buildscripts/build_swiftest.sh | 66 ------------------------ buildscripts/get_lomp.sh | 83 ++++++++++++++++++++++++++++++ pyproject.toml | 41 ++++++++++++++- 8 files changed, 154 insertions(+), 134 deletions(-) create mode 100644 .github/workflows/build_wheels.yml delete mode 100755 buildscripts/build_macwheels.sh delete mode 100755 buildscripts/build_swiftest.sh create mode 100755 buildscripts/get_lomp.sh diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml new file mode 100644 index 000000000..9b7a32427 --- /dev/null +++ b/.github/workflows/build_wheels.yml @@ -0,0 +1,25 @@ +name: swiftest + +on: [push] + +jobs: + build_wheels: + name: Build wheels on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-20.04, macos-11, macos-12, macos-13] + + steps: + - uses: actions/checkout@v3 + + - name: Build wheels + uses: pypa/cibuildwheel@v2.15.0 + with: + package-dir: . + output-dir: wheelhouse + config-file: "{package}/pyproject.toml" + + - uses: actions/upload-artifact@v3 + with: + path: ./wheelhouse/*.whl \ No newline at end of file diff --git a/.gitignore b/.gitignore index e68502d0f..ab0e8d718 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ swiftest_driver.sh !README.swifter dump* !**/.gitignore +!.github/workflows/build_wheels.yml !setup.py !examples/** !swiftest/** diff --git a/buildscripts/_build_getopts.sh b/buildscripts/_build_getopts.sh index fc9728db7..ac9e9586b 100755 --- a/buildscripts/_build_getopts.sh +++ b/buildscripts/_build_getopts.sh @@ -15,7 +15,7 @@ ROOT_DIR=$(realpath ${SCRIPT_DIR}/..) # Parse arguments USTMT="Usage: ${0} [-d /path/to/dependency/source] [-p /prefix/path] [-m MACOSX_DEPLOYMENT_TARGET]" -MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET:-"11.0"} +MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET:-"$(sw_vers --ProductVersion)"} while getopts ":d:p:m:h" ARG; do case "${ARG}" in @@ -49,27 +49,6 @@ BUILD_DIR=${BUILD_DIR:-$(mktemp -ut swiftest_build.XXXXXXXX)} PREFIX=${PREFIX:-${ROOT_DIR}} DEPENDENCY_DIR=${DEPENDENCY_DIR:-${BUILD_DIR}} -if [ -z ${DEPENDENCY_ENV_VARS+x} ]; then - . ${SCRIPT_DIR}/set_compilers.sh - - LD_LIBRARY_PATH="${PREFIX}/lib:${LD_LIBRARY_PATH}" - CPPFLAGS="${CPPFLAGS} -isystem ${PREFIX}/include" - LDFLAGS="${LDFLAGS} -L${PREFIX}/lib" - CPATH="${PREFIX}/include:${CPATH}" - - HDF5_ROOT="${PREFIX}" - HDF5_LIBDIR="${HDF5_ROOT}/lib" - HDF5_INCLUDE_DIR="${HDF5_ROOT}/include" - HDF5_PLUGIN_PATH="${HDF5_LIBDIR}/plugin" - NCDIR="${PREFIX}" - NFDIR="${PREFIX}" - NETCDF_FORTRAN_HOME=${NFDIR} - NETCDF_INCLUDE=${NFDIR}/include - NETCDF_HOME=${NCDIR} - - DEPENDENCY_ENV_VARS=true -fi - mkdir -p ${DEPENDENCY_DIR} mkdir -p ${PREFIX}/lib mkdir -p ${PREFIX}/include diff --git a/buildscripts/build_dependencies.sh b/buildscripts/build_dependencies.sh index 645465d22..ee8efb0f7 100755 --- a/buildscripts/build_dependencies.sh +++ b/buildscripts/build_dependencies.sh @@ -25,6 +25,11 @@ printf "Using ${OS} compilers:\nFC: ${FC}\nCC: ${CC}\nCXX: ${CXX}\n" printf "Installing to ${PREFIX}\n" printf "\n" +# Get the OpenMP Libraries +if [ $OS == "MacOSX" ]; then + ${SCRIPT_DIR}/get_lomp.sh ${ARGS} +fi + set -e ${SCRIPT_DIR}/build_zlib.sh ${ARGS} ${SCRIPT_DIR}/build_hdf5.sh ${ARGS} diff --git a/buildscripts/build_macwheels.sh b/buildscripts/build_macwheels.sh deleted file mode 100755 index 49acbec91..000000000 --- a/buildscripts/build_macwheels.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash -# This script will build all versions of the MacOS wheels, for both Apple Silicon (arm64) and Intel (x86_64) and for a variety -# of OS versions. -# -# Copyright 2023 - David Minton -# This file is part of Swiftest. -# Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -# Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -# You should have received a copy of the GNU General Public License along with Swiftest. -# If not, see: https://www.gnu.org/licenses. -set -a -SCRIPT_DIR=$(realpath $(dirname $0)) -ROOT_DIR=$(realpath ${SCRIPT_DIR}/..) -BUILD_DIR=$(mktemp -ut swiftest_build) -PREFIX=${ROOT_DIR} -DEPENDENCY_DIR=${BUILD_DIR}/downloads - -# The versions of MacOS that we have development tools for -declare -a MACVER=("10.13" "11.0" "12.0" "13.0") - -for MACOSX_DEPLOYMENT_TARGET in "${MACVER[@]}"; do - ARGS="-p ${PREFIX} -d ${DEPENDENCY_DIR} -m ${MACOSX_DEPLOYMENT_TARGET}" - printf "**********************************************************************\n" - printf "ARGS: ${ARGS}\n" - printf "**********************************************************************\n" - - if [ "${MACOSX_DEPLOYMENT_TARGET}" != "10.13" ]; then - ${SCRIPT_DIR}/build_dependencies.sh ${ARGS} - ${SCRIPT_DIR}/build_swiftest.sh ${ARGS} - cmake -P distclean.cmake - fi - - if [ "${MACOSX_DEPLOYMENT_TARGET}" != "13.0" ]; then - ${SCRIPT_DIR}/intelbash.sh ${SCRIPT_DIR}/build_dependencies.sh ${ARGS} - ${SCRIPT_DIR}/intelbash.sh ${SCRIPT_DIR}/build_swiftest.sh ${ARGS} - cmake -P distclean.cmake - fi -done -python3 -m build --sdist - - - diff --git a/buildscripts/build_swiftest.sh b/buildscripts/build_swiftest.sh deleted file mode 100755 index 3f0af181d..000000000 --- a/buildscripts/build_swiftest.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/bash -# This script will build the Swiftest package. It is assumed that compatible dependencies have been built already before this is run -# -# Copyright 2023 - David Minton -# This file is part of Swiftest. -# Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -# Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -# You should have received a copy of the GNU General Public License along with Swiftest. -# If not, see: https://www.gnu.org/licenses. -set -a -if [ -z ${SCRIPT_DIR+x} ]; then SCRIPT_DIR=$(realpath $(dirname $0)); fi -ARGS=$@ - -. ${SCRIPT_DIR}/_build_getopts.sh ${ARGS} -ARGS="-p ${PREFIX} -d ${DEPENDENCY_DIR} -m ${MACOSX_DEPLOYMENT_TARGET}" - -# Determine if we are in the correct directory (the script can either be run from the Swiftest project root directory or the -# buildscripts directory) -if [ ! -f "${ROOT_DIR}/setup.py" ]; then - echo "Error: setup.py not found" - exit 1 -fi - -read -r OS ARCH < <($SCRIPT_DIR/get_platform.sh) -echo $OS $ARCH - -if [ $OS = "Linux" ]; then - cibuildwheel --platform linux -else - SKBUILD_CONFIGURE_OPTIONS="-DBUILD_SHARED_LIBS=ON -DUSE_SIMD=OFF" - SKBUILD_CONFIGURE_OPTIONS="${SKBUILD_CONFIGURE_OPTIONS} -DMACHINE_CODE_VALUE=\"generic\"" - - NETCDF_FORTRAN_HOME=${ROOT_DIR} - NETCDF_INCLUDE=${ROOT_DIR}/include - - CPPFLAGS="-Xclang -fopenmp" - LIBS="-lomp" - LDFLAGS="-Wl,-rpath,${ROOT_DIR}/lib" - CPATH="${ROOT_DIR}/include" - LD_LIBRARY_PATH="${ROOT_DIR}/lib" - LIBRARY_PATH="${LD_LIBRARY_PATH}" - cd $ROOT_DIR - - printf "\n" - printf "*********************************************************\n" - printf "* BUILDING SWIFTEST *\n" - printf "*********************************************************\n" - printf "LIBS: ${LIBS}\n" - printf "CFLAGS: ${CFLAGS}\n" - printf "FFLAGS: ${FFLAGS}\n" - printf "FCFLAGS: ${FCFLAGS}\n" - printf "CPPFLAGS: ${CPPFLAGS}\n" - printf "CPATH: ${CPATH}\n" - printf "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}\n" - printf "LDFLAGS: ${LDFLAGS}\n" - printf "LIBS: ${LIBS}\n" - printf "NETCDF_FORTRAN_HOME: ${NETCDF_FORTRAN_HOME}\n" - printf "NETCDF_INCLUDE: ${NETCDF_INCLUDE}\n" - printf "SKBUILD_CONFIGURE_OPTIONS: ${SKBUILD_CONFIGURE_OPTIONS}\n" - printf "MACOSX_DEPLOYMENT_TARGET: ${MACOSX_DEPLOYMENT_TARGET}\n" - printf "*********************************************************\n" - - cibuildwheel --platform macos -fi \ No newline at end of file diff --git a/buildscripts/get_lomp.sh b/buildscripts/get_lomp.sh new file mode 100755 index 000000000..6b56e5b3c --- /dev/null +++ b/buildscripts/get_lomp.sh @@ -0,0 +1,83 @@ +#!/bin/bash +# This script will download the correct OpenMP library for a given MacOS deployment target +# +# Copyright 2023 - David Minton +# This file is part of Swiftest. +# Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with Swiftest. +# If not, see: https://www.gnu.org/licenses. + +# Determine the platform and architecture +SCRIPT_DIR=$(realpath $(dirname $0)) +set -a +ARGS=$@ +. ${SCRIPT_DIR}/_build_getopts.sh ${ARGS} +printf "MACOSX_DEPLOYMENT_TARGET: ${MACOSX_DEPLOYMENT_TARGET}\n" + +TARGET_MAJOR=`echo $MACOSX_DEPLOYMENT_TARGET | cut -d. -f1` +TARGET_MINOR=`echo $MACOSX_DEPLOYMENT_TARGET | cut -d. -f2` +TARGET_REV=`echo $MACOSX_DEPLOYMENT_TARGET | cut -d. -f3` + +#Figure out which version to get +case $TARGET_MAJOR in + 13) + OMPVER="14.0.6" + DVER="20" + ;; + 12) + if ((TARGET_MINOR>=5)); then + OMPVER="14.0.6" + DVER="20" + else + OMPVER="13.0.0" + DVER="21" + fi + ;; + 11) + if ((TARGET_MINOR>=3)); then + OMPVER="12.0.1" + DVER="20" + else + OMPVER="11.0.1" + DVER="20" + fi + ;; + 10) + DVER="17" + case $TARGET_MINOR in + 15) + case $TARGET_REV in + 4) + OMPVER="10.0.0" + ;; + 2) + OMPVER="9.0.1" + ;; + esac + ;; + 14) + case $TARGET_REV in + 4) + OMPVER="8.0.1" + ;; + 3) + OMPVER="7.1.0" + ;; + esac + ;; + *) + OMPVER="7.1.0" + ;; + esac + ;; +esac + +filename="openmp-${OMPVER}-darwin${DVER}-Release.tar.gz" +#Download and install the libraries +printf "Downloading ${filename}\n" +curl -O https://mac.r-project.org/openmp/${filename} && \ + sudo tar fvxz ${filename} -C / && \ + rm ${filename} \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 25fbd2a2b..3ea08b70c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -60,10 +60,47 @@ test-requires = ['pytest'] skip = "cp312-* pp* *i686 *-manylinux_i686 *_ppc64le *_s390x *-musllinux* *-win32" build-verbosity = 1 +[tool.cibuildwheel.macos.environment] +ROOT_DIR="$(pwd)" +ARCH="$(uname -m)" +MACOSX_DEPLOYMENT_TARGET="$(sw_vers --ProductVersion)" +PREFIX="${ROOT_DIR}" +LD_LIBRARY_PATH="/usr/local/lib:${PREFIX}/lib:${HOMEBREW_PREFIX}/lib" +LDFLAGS="-Wl,-rpath,${ROOT_DIR}/lib -Wl,-rpath,${PREFIX}/lib -Wl,-rpath,/usr/local/lib -Wl,-no_compact_unwind -L${PREFIX}/lib" +CPATH="/usr/local/include:${PREFIX}/include:${HOMEBREW_PREFIX}/include:${ROOT_DIR}/include" +CPPFLAGS="-isystem ${PREFIX}/include -isystem /usr/local/include" +LIBS="-lomp" +CFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -Wno-deprecated-non-prototype -arch ${ARCH}" +FCFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -arch ${ARCH}" +FFFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -arch ${ARCH}" +HDF5_ROOT="${PREFIX}" +HDF5_LIBDIR="${HDF5_ROOT}/lib" +HDF5_INCLUDE_DIR="${HDF5_ROOT}/include" +HDF5_PLUGIN_PATH="${HDF5_LIBDIR}/plugin" +NETCDF_FORTRAN_HOME="${PREFIX}" +NETCDF_INCLUDE="${PREFIX}" +NCDIR="${PREFIX}" +NFDIR="${PREFIX}" +FC="${HOMEBREW_PREFIX}/bin/gfortran-12" +CC="/usr/bin/clang" +CXX="/usr/bin/clang++" +CPP="/usr/bin/cpp" +AR="/usr/bin/ar" +NM="/usr/bin/nm" +RANLIB="/usr/bin/ranlib" + +[tool.cibuildwheel.macos] +before-all = [ + "LIBS=\"\" buildscripts/build_dependencies.sh -p ${PREFIX} -d ${TMPDIR}/swiftest.build -m ${MACOSX_DEPLOYMENT_TARGET}" +] + [tool.cibuildwheel.linux] -repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel}" -environment = {NETCDF_FORTRAN_HOME="/usr/local", NETCDF_INCLUDE="/usr/local/include", LD_LIBRARY_PATH="/usr/local/lib:/project/lib", CPATH="/usr/local/include:/project/include"} before-all = [ "yum install doxygen libxml2-devel libcurl-devel -y", "buildscripts/build_dependencies.sh -p /usr/local" ] +[tool.cibuildwheel.linux.environment] +NETCDF_FORTRAN_HOME="/usr/local" +NETCDF_INCLUDE="/usr/local/include" +LD_LIBRARY_PATH="/usr/local/lib:/project/lib" +CPATH="/usr/local/include:/project/include" From f6f6e2b11cc3aee03ec419a2191a75290cd13920 Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Thu, 7 Sep 2023 16:07:27 -0400 Subject: [PATCH 17/22] Updated the build_wheels action file --- .github/workflows/build_wheels.yml | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index 9b7a32427..3e4330b10 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -1,6 +1,6 @@ name: swiftest -on: [push] +on: push jobs: build_wheels: @@ -15,6 +15,9 @@ jobs: - name: Build wheels uses: pypa/cibuildwheel@v2.15.0 + env: + CIBW_ARCHS_MACOS: x86_64 arm64 + CIBW_ARCHS_LINUX: x86_64 aarch64 with: package-dir: . output-dir: wheelhouse @@ -22,4 +25,18 @@ jobs: - uses: actions/upload-artifact@v3 with: - path: ./wheelhouse/*.whl \ No newline at end of file + path: ./wheelhouse/*.whl + + + build_sdist: + name: Build source distribution + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build sdist + run: pipx run build --sdist + + - uses: actions/upload-artifact@v3 + with: + path: dist/*.tar.gz \ No newline at end of file From 4efc03832fbd1f9a57451b7b574d6f1486a2c0e3 Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Thu, 7 Sep 2023 16:12:46 -0400 Subject: [PATCH 18/22] Fixed option that works differently in older MacOS --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3ea08b70c..46d8b1f10 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,7 +63,7 @@ build-verbosity = 1 [tool.cibuildwheel.macos.environment] ROOT_DIR="$(pwd)" ARCH="$(uname -m)" -MACOSX_DEPLOYMENT_TARGET="$(sw_vers --ProductVersion)" +MACOSX_DEPLOYMENT_TARGET="$(sw_vers -productVersion)" PREFIX="${ROOT_DIR}" LD_LIBRARY_PATH="/usr/local/lib:${PREFIX}/lib:${HOMEBREW_PREFIX}/lib" LDFLAGS="-Wl,-rpath,${ROOT_DIR}/lib -Wl,-rpath,${PREFIX}/lib -Wl,-rpath,/usr/local/lib -Wl,-no_compact_unwind -L${PREFIX}/lib" From a6582a363823b25d891bac9391ab43fd988b1368 Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Thu, 7 Sep 2023 16:19:36 -0400 Subject: [PATCH 19/22] Added the missing coreutils and fixed typo in build scripts --- buildscripts/build_dependencies.sh | 2 +- pyproject.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/buildscripts/build_dependencies.sh b/buildscripts/build_dependencies.sh index ee8efb0f7..8d8027aa6 100755 --- a/buildscripts/build_dependencies.sh +++ b/buildscripts/build_dependencies.sh @@ -26,7 +26,7 @@ printf "Installing to ${PREFIX}\n" printf "\n" # Get the OpenMP Libraries -if [ $OS == "MacOSX" ]; then +if [ $OS = "MacOSX" ]; then ${SCRIPT_DIR}/get_lomp.sh ${ARGS} fi diff --git a/pyproject.toml b/pyproject.toml index 46d8b1f10..f852a19df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -91,6 +91,7 @@ RANLIB="/usr/bin/ranlib" [tool.cibuildwheel.macos] before-all = [ + "brew install coreutils", "LIBS=\"\" buildscripts/build_dependencies.sh -p ${PREFIX} -d ${TMPDIR}/swiftest.build -m ${MACOSX_DEPLOYMENT_TARGET}" ] From 1ae6431725fbf6c4be7c5c5219c2b4a688f430e9 Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Thu, 7 Sep 2023 16:36:58 -0400 Subject: [PATCH 20/22] Explicitly define the HOMEBREW_PREFIX directory and the path to gfortran for the MacOS runner on Github Actions --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index f852a19df..2b36e4260 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,6 +65,7 @@ ROOT_DIR="$(pwd)" ARCH="$(uname -m)" MACOSX_DEPLOYMENT_TARGET="$(sw_vers -productVersion)" PREFIX="${ROOT_DIR}" +HOMEBREW_PREFIX="$(brew --prefix)" LD_LIBRARY_PATH="/usr/local/lib:${PREFIX}/lib:${HOMEBREW_PREFIX}/lib" LDFLAGS="-Wl,-rpath,${ROOT_DIR}/lib -Wl,-rpath,${PREFIX}/lib -Wl,-rpath,/usr/local/lib -Wl,-no_compact_unwind -L${PREFIX}/lib" CPATH="/usr/local/include:${PREFIX}/include:${HOMEBREW_PREFIX}/include:${ROOT_DIR}/include" @@ -81,7 +82,7 @@ NETCDF_FORTRAN_HOME="${PREFIX}" NETCDF_INCLUDE="${PREFIX}" NCDIR="${PREFIX}" NFDIR="${PREFIX}" -FC="${HOMEBREW_PREFIX}/bin/gfortran-12" +FC="$(command -v gfortran-12)" CC="/usr/bin/clang" CXX="/usr/bin/clang++" CPP="/usr/bin/cpp" From c3378eb00f9f6036c4a5f3ba0139d89c737844f7 Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Thu, 7 Sep 2023 16:49:46 -0400 Subject: [PATCH 21/22] Added libzip to MacOS install due to failure on GitHub runner --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2b36e4260..fd62d3e6a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -92,7 +92,7 @@ RANLIB="/usr/bin/ranlib" [tool.cibuildwheel.macos] before-all = [ - "brew install coreutils", + "brew install coreutils libzip", "LIBS=\"\" buildscripts/build_dependencies.sh -p ${PREFIX} -d ${TMPDIR}/swiftest.build -m ${MACOSX_DEPLOYMENT_TARGET}" ] From 741bfefbbec645f0b6e64b2c132651cff9e95108 Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Thu, 7 Sep 2023 17:42:22 -0400 Subject: [PATCH 22/22] Tweaked scripts to get remote Mac build to work --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index fd62d3e6a..8d8eb8761 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,7 +67,7 @@ MACOSX_DEPLOYMENT_TARGET="$(sw_vers -productVersion)" PREFIX="${ROOT_DIR}" HOMEBREW_PREFIX="$(brew --prefix)" LD_LIBRARY_PATH="/usr/local/lib:${PREFIX}/lib:${HOMEBREW_PREFIX}/lib" -LDFLAGS="-Wl,-rpath,${ROOT_DIR}/lib -Wl,-rpath,${PREFIX}/lib -Wl,-rpath,/usr/local/lib -Wl,-no_compact_unwind -L${PREFIX}/lib" +LDFLAGS="-Wl,-rpath,${ROOT_DIR}/lib -Wl,-no_compact_unwind -L${PREFIX}/lib -L${HOMEBREW_PREFIX}/lib" CPATH="/usr/local/include:${PREFIX}/include:${HOMEBREW_PREFIX}/include:${ROOT_DIR}/include" CPPFLAGS="-isystem ${PREFIX}/include -isystem /usr/local/include" LIBS="-lomp" @@ -92,7 +92,7 @@ RANLIB="/usr/bin/ranlib" [tool.cibuildwheel.macos] before-all = [ - "brew install coreutils libzip", + "brew install coreutils", "LIBS=\"\" buildscripts/build_dependencies.sh -p ${PREFIX} -d ${TMPDIR}/swiftest.build -m ${MACOSX_DEPLOYMENT_TARGET}" ]