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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
*.nc
*.nc4
*.npz
/cmake/
/@cmake/
/cmake@/
/env/
/@env/
/env@/
Expand Down
85 changes: 29 additions & 56 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,79 +4,52 @@

# Boiler plate preamble
# ---------------------
cmake_minimum_required (VERSION 3.13)
cmake_minimum_required (VERSION 3.24)
cmake_policy (SET CMP0053 NEW)
cmake_policy (SET CMP0054 NEW)
cmake_policy (SET CMP0132 NEW)

project (
GMAOpyobs
VERSION 1.1.0
LANGUAGES Fortran CXX C) # Note - CXX is required for ESMF
LANGUAGES Fortran C
)

# Enforce out of source directory builds
# --------------------------------------
if ("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}")
message(SEND_ERROR "In-source builds are disabled. Please
issue cmake command in separate build directory.")
endif ("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}")
if ("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}")
message(SEND_ERROR "In-source builds are disabled. Please
issue cmake command in separate build directory.")
endif ("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}")

# Set the default build type to release
# -------------------------------------
if (NOT CMAKE_BUILD_TYPE)

message (STATUS "Setting build type to 'Release' as none was specified.")
set (CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)

# Set the possible values of build type for cmake-gui
# ---------------------------------------------------
set_property (CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Release" "Aggressive")
endif ()
list (APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")

# Where to find relevant cmake macros
# -----------------------------------
if (NOT COMMAND esma)
foreach (dir cmake @cmake cmake@)
if (EXISTS ${CMAKE_CURRENT_LIST_DIR}/${dir})
list (APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/${dir}")
set (ESMA_CMAKE_PATH "${CMAKE_CURRENT_LIST_DIR}/${dir}"
CACHE PATH "Path to ESMA_cmake code")
endif ()
endforeach ()

include (esma)
# Recursively build source tree
# -----------------------------

set (PYOBS_STANDALONE TRUE)
# mepo can now clone subrepos in three styles
set (ESMA_ENV_DIRS
env
@env
env@
)
foreach (dir IN LISTS ESMA_ENV_DIRS)
if (EXISTS ${CMAKE_CURRENT_LIST_DIR}/${dir})
add_subdirectory (${dir})
endif ()
ecbuild_declare_project()
endforeach ()

# Generic DFLAGS
# These should be relocated and/or eliminated.
# --------------------------------------------
add_definitions(-Dsys${CMAKE_SYSTEM_NAME} -DESMA64)
add_definitions(${MPI_Fortran_COMPILE_FLAGS})
include_directories(${MPI_Fortran_INCLUDE_PATH})

# Recursively build source tree
# -----------------------------
esma_add_subdirectory(env)
esma_add_subdirectory(src)
add_subdirectory(src)

# https://www.scivision.dev/cmake-auto-gitignore-build-dir/
# --- auto-ignore build directory
if(NOT EXISTS ${PROJECT_BINARY_DIR}/.gitignore)
file(WRITE ${PROJECT_BINARY_DIR}/.gitignore "*")
endif()
if(NOT EXISTS ${PROJECT_BINARY_DIR}/.gitignore)
file(WRITE ${PROJECT_BINARY_DIR}/.gitignore "*")
endif()

# Piggyback that file into install
# --------------------------------
install(
FILES ${PROJECT_BINARY_DIR}/.gitignore
DESTINATION ${CMAKE_INSTALL_PREFIX}
)

# Adds ability to tar source
# --------------------------
if (PYOBS_STANDALONE)
include(esma_cpack OPTIONAL)
endif ()
install(
FILES ${PROJECT_BINARY_DIR}/.gitignore
DESTINATION ${CMAKE_INSTALL_PREFIX}
)
131 changes: 131 additions & 0 deletions cmake/UseF2Py.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Copyright (c) 2024, Henry Schreiner
# Developed under NSF AWARD OAC-2209877 and by the respective contributors.
# All rights reserved.
#
# SPDX-License-Identifier: Apache-2.0

if(CMAKE_VERSION VERSION_LESS 3.17)
message(FATAL_ERROR "CMake 3.17+ required")
endif()

include_guard(GLOBAL)

if(TARGET Python::NumPy)
set(_Python Python CACHE INTERNAL "" FORCE)
elseif(TARGET Python3::NumPy)
set(_Python Python3 CACHE INTERNAL "" FORCE)
else()
message(FATAL_ERROR "You must find Python or Python3 with the NumPy component before including F2PY!")
endif()

execute_process(
COMMAND "${${_Python}_EXECUTABLE}" -c
"import numpy.f2py; print(numpy.f2py.get_include())"
OUTPUT_VARIABLE F2PY_inc_output
ERROR_VARIABLE F2PY_inc_error
RESULT_VARIABLE F2PY_inc_result
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_STRIP_TRAILING_WHITESPACE)

if(NOT F2PY_inc_result EQUAL 0)
message(FATAL_ERROR "Can't find f2py, got ${F2PY_inc_output} ${F2PY_inc_error}")
endif()

set(F2PY_INCLUDE_DIR "${F2PY_inc_output}" CACHE STRING "" FORCE)
set(F2PY_OBJECT_FILES "${F2PY_inc_output}/fortranobject.c;${F2PY_inc_output}/fortranobject.h" CACHE STRING "" FORCE)
mark_as_advanced(F2PY_INCLUDE_DIR F2PY_OBJECT_FILES)

add_library(F2Py::Headers IMPORTED GLOBAL INTERFACE)
target_include_directories(F2Py::Headers INTERFACE "${F2PY_INCLUDE_DIR}")

function(f2py_object_library NAME TYPE)
add_library(${NAME} ${TYPE} "${F2PY_INCLUDE_DIR}/fortranobject.c")
target_link_libraries(${NAME} PUBLIC ${_Python}::NumPy F2Py::Headers)
if("${TYPE}" STREQUAL "OBJECT")
set_property(TARGET ${NAME} PROPERTY POSITION_INDEPENDENT_CODE ON)
endif()
endfunction()

function(f2py_generate_module NAME)
cmake_parse_arguments(
PARSE_ARGV 1
F2PY
"NOLOWER;F77;F90"
"OUTPUT_DIR;OUTPUT_VARIABLE"
"F2PY_ARGS"
)
set(ALL_FILES ${F2PY_UNPARSED_ARGUMENTS})

if(NOT ALL_FILES)
message(FATAL_ERROR "One or more input files must be specified")
endif()

if(NOT F2PY_OUTPUT_DIR)
set(F2PY_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
endif()

if(NAME MATCHES "\\.pyf$")
set(_file_arg "${NAME}")
get_filename_component(NAME "${NAME}" NAME_WE)
else()
set(_file_arg -m ${NAME})
endif()

if(F2PY_F77 AND F2PY_F90)
message(FATAL_ERROR "Can't specify F77 and F90")
elseif(NOT F2PY_F77 AND NOT F2PY_F90)
set(HAS_F90_FILE FALSE)

foreach(file IN LISTS ALL_FILES)
if("${file}" MATCHES "\\.f90$")
set(HAS_F90_FILE TRUE)
break()
endif()
endforeach()

if(HAS_F90_FILE)
set(F2PY_F90 ON)
else()
set(F2PY_F77 ON)
endif()
endif()

if(F2PY_F77)
set(wrapper_files ${NAME}-f2pywrappers.f)
else()
set(wrapper_files ${NAME}-f2pywrappers.f ${NAME}-f2pywrappers2.f90)
endif()

if(F2PY_NOLOWER)
set(lower "--no-lower")
else()
set(lower "--lower")
endif()

set(abs_all_files)
foreach(file IN LISTS ALL_FILES)
if(IS_ABSOLUTE "${file}")
list(APPEND abs_all_files "${file}")
else()
list(APPEND abs_all_files "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
endif()
endforeach()

add_custom_command(
OUTPUT ${NAME}module.c ${wrapper_files}
DEPENDS ${ALL_FILES}
VERBATIM
COMMAND
"${${_Python}_EXECUTABLE}" -m numpy.f2py
"${abs_all_files}" ${_file_arg} ${lower} ${F2PY_F2PY_ARGS}
COMMAND
"${CMAKE_COMMAND}" -E touch ${wrapper_files}
WORKING_DIRECTORY "${F2PY_OUTPUT_DIR}"
COMMENT
"F2PY making ${NAME} wrappers"
)

if(F2PY_OUTPUT_VARIABLE)
set(${F2PY_OUTPUT_VARIABLE} ${NAME}module.c ${wrapper_files} PARENT_SCOPE)
endif()
endfunction()
12 changes: 0 additions & 12 deletions components.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,3 @@ env:
remote: ../ESMA_env.git
tag: v4.8.2
develop: main

cmake:
local: ./cmake@
remote: ../ESMA_cmake.git
tag: v3.28.0
develop: develop

ecbuild:
local: ./cmake@/ecbuild@
remote: ../ecbuild.git
tag: geos/v1.3.0

102 changes: 54 additions & 48 deletions src/f2py/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,64 +2,70 @@
# Cmake rules for creating python modules with f2py and
#

# The OVERRIDE tells esma_set_this() to name the library as
# what we set here rather than the name of the directory
esma_set_this ( OVERRIDE GMAOpyobs )

# cmake requirements
# ------------------

# NOTE: For CI purposes, f2py is hard to support. Until
# a solution can be found, we add a flag to allow
# the user to disable f2py in these circumstances
option(USE_F2PY "Use f2py to build python modules" ON)
if (USE_F2PY)
find_package(F2PY3 REQUIRED)

# This setting is needed on macOS to ensure
# that the desired Python is found (i.e., if
# a user has installed their own Python, it
# should be favored over the system Python or
# one from Homebrew, etc.)
set (CMAKE_FIND_FRAMEWORK LAST)

find_package(
Python
COMPONENTS Interpreter Development.Module NumPy
REQUIRED)

include(UseF2Py)

# Libray
# ------
esma_add_library (${this}
SRCS VegType_Mod.F90
VegType_io.c
glint_mod.F90
sgp4_mod.F90
TLE_mod.F90
csUtils.F90
# Library: GMAOpyobs
# ------------------
add_library (GMAOpyobs
VegType_Mod.F90
VegType_io.c
glint_mod.F90
sgp4_mod.F90
TLE_mod.F90
csUtils.F90
)
install(TARGETS GMAOpyobs DESTINATION lib)

# Module: binObs
# --------------

f2py_object_library(binObs_object OBJECT)
f2py_generate_module(binObs_ binObs_py.F OUTPUT_VARIABLE binObs_files)
python_add_library(binObs_ MODULE "${binObs_files}" WITH_SOABI)
target_link_libraries(binObs_ PRIVATE binObs_object)
target_link_libraries(binObs_ PRIVATE GMAOpyobs)
install(TARGETS binObs_ DESTINATION lib/Python)


# Module: IGBP
# ------------

# Module: binObs
# --------------
esma_add_f2py3_module(binObs_
SOURCES binObs_py.F
DESTINATION lib/Python
INCLUDEDIRS ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_BINARY_DIR}/lib
${include_${this}}
)
add_dependencies(binObs_ ${this})
f2py_object_library(IGBP_object OBJECT)
f2py_generate_module(IGBP_ IGBP_py.F90 OUTPUT_VARIABLE IGBP_files)
python_add_library(IGBP_ MODULE "${IGBP_files}" WITH_SOABI)
target_link_libraries(IGBP_ PRIVATE IGBP_object)
target_link_libraries(IGBP_ PRIVATE GMAOpyobs)
install(TARGETS IGBP_ DESTINATION lib/Python/pyobs)

# Module: IGBP
# ------------
esma_add_f2py3_module(IGBP_
SOURCES IGBP_py.F90
DESTINATION lib/Python/pyobs
ONLY getsimpleveg getdetailedveg
LIBRARIES GMAOpyobs
INCLUDEDIRS ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_BINARY_DIR}/lib
${include_${this}}
)
add_dependencies(IGBP_ ${this})
# Module: sgp4
# ------------

# Module: sgp4
# ------------
esma_add_f2py3_module(sgp4_
SOURCES sgp4_py.F90
DESTINATION lib/Python/pyobs
LIBRARIES GMAOpyobs
INCLUDEDIRS ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_BINARY_DIR}/lib
${include_${this}}
)
add_dependencies(sgp4_ ${this})
f2py_object_library(sgp4_object OBJECT)
f2py_generate_module(sgp4_ sgp4_py.F90 OUTPUT_VARIABLE sgp4_files)
python_add_library(sgp4_ MODULE "${sgp4_files}" WITH_SOABI)
target_link_libraries(sgp4_ PRIVATE sgp4_object)
target_link_libraries(sgp4_ PRIVATE GMAOpyobs)
install(TARGETS sgp4_ DESTINATION lib/Python/pyobs)

endif (USE_F2PY)
endif ()
Loading