1# Copyright (c) 2017-2025, Lawrence Livermore National Security, LLC and other CEED contributors 2# All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3# 4# SPDX-License-Identifier: BSD-2-Clause 5# 6# This file is part of CEED: http://github.com/ceed 7 8import os 9import re 10from cffi import FFI 11ffibuilder = FFI() 12 13ceed_version_ge = re.compile(r'\s+\(!?CEED_VERSION.*') 14 15 16def get_ceed_dirs(): 17 here = os.path.dirname(os.path.abspath(__file__)) 18 prefix = os.path.dirname(here) 19 # make install links the installed library in build/lbiceed.so Sadly, it 20 # does not seem possible to obtain the bath that libceed_build_ext has/will 21 # install to. 22 libdir = os.path.join(prefix, "build") 23 return prefix, libdir 24 25 26ceed_dir, ceed_libdir = get_ceed_dirs() 27 28# ------------------------------------------------------------------------------ 29# Provide C definitions to CFFI 30# ------------------------------------------------------------------------------ 31lines = [] 32for header_path in ["include/ceed/types.h", "include/ceed/ceed.h"]: 33 with open(os.path.abspath(header_path)) as f: 34 lines += [line.strip() for line in f if 35 not (line.startswith("#") and not line.startswith("#include")) and 36 not line.startswith(" static") and 37 not line.startswith("#include \"deprecated.h\"") and 38 not line.startswith(" CEED_QFUNCTION_ATTR") and 39 "CeedErrorImpl" not in line and 40 "const char *, ...);" not in line and 41 not line.startswith("CEED_EXTERN const char *const") and 42 not ceed_version_ge.match(line)] 43lines = [line.replace("CEED_EXTERN", "extern") for line in lines] 44 45# Find scalar type inclusion line and insert definitions 46for line in lines: 47 if re.search("ceed-f32.h", line) is not None: 48 insert_index = lines.index(line) + 1 49 extra_lines = ['typedef float CeedScalar;'] 50 extra_lines.append('static const int CEED_SCALAR_TYPE;') 51 extra_lines.append('static const double CEED_EPSILON;') 52 elif re.search("ceed-f64.h", line) is not None: 53 insert_index = lines.index(line) + 1 54 extra_lines = ['typedef double CeedScalar;'] 55 extra_lines.append('static const int CEED_SCALAR_TYPE;') 56 extra_lines.append('static const double CEED_EPSILON;') 57lines[insert_index: insert_index] = extra_lines 58 59# Remove all include statements now that scalar type has been dealt with 60lines = [line for line in lines if not line.startswith("#include")] 61 62# Build header from lines 63header = '\n'.join(lines) 64header = header.split("static inline CeedInt CeedIntPow", 1)[0] 65header += '\nextern int CeedVectorGetState(CeedVector, uint64_t*);' 66header += '\nextern int CeedElemRestrictionGetLLayout(CeedElemRestriction, CeedInt layout[3]);' 67header += '\nextern int CeedElemRestrictionGetELayout(CeedElemRestriction, CeedInt layout[3]);' 68 69# Note: cffi cannot handle vargs 70header = re.sub("va_list", "const char *", header) 71 72ffibuilder.cdef(header) 73 74ffibuilder.set_source("_ceed_cffi", 75 """ 76 #define va_list const char * 77 #include <ceed.h> // the C header of the library 78 #include <ceed/backend.h> // declarations for the backend functions above 79 """, 80 include_dirs=[ 81 os.path.join(ceed_dir, "include")], # include path 82 libraries=["ceed"], # library name, for the linker 83 # library path, for the linker 84 library_dirs=[ceed_libdir], 85 # use libceed.so as installed 86 runtime_library_dirs=['$ORIGIN/libceed/lib'] 87 ) 88 89# ------------------------------------------------------------------------------ 90# Builder 91# ------------------------------------------------------------------------------ 92if __name__ == "__main__": 93 ffibuilder.compile(verbose=True) 94 95# ------------------------------------------------------------------------------ 96