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(" CEED_QFUNCTION_ATTR") and 38 "CeedErrorImpl" not in line and 39 "const char *, ...);" not in line and 40 not line.startswith("CEED_EXTERN const char *const") and 41 not ceed_version_ge.match(line)] 42lines = [line.replace("CEED_EXTERN", "extern") for line in lines] 43 44# Find scalar type inclusion line and insert definitions 45for line in lines: 46 if re.search("ceed-f32.h", line) is not None: 47 insert_index = lines.index(line) + 1 48 extra_lines = ['typedef float CeedScalar;'] 49 extra_lines.append('static const int CEED_SCALAR_TYPE;') 50 extra_lines.append('static const double CEED_EPSILON;') 51 elif re.search("ceed-f64.h", line) is not None: 52 insert_index = lines.index(line) + 1 53 extra_lines = ['typedef double CeedScalar;'] 54 extra_lines.append('static const int CEED_SCALAR_TYPE;') 55 extra_lines.append('static const double CEED_EPSILON;') 56lines[insert_index: insert_index] = extra_lines 57 58# Remove all include statements now that scalar type has been dealt with 59lines = [line for line in lines if not line.startswith("#include")] 60 61# Build header from lines 62header = '\n'.join(lines) 63header = header.split("static inline CeedInt CeedIntPow", 1)[0] 64header += '\nextern int CeedVectorGetState(CeedVector, uint64_t*);' 65header += '\nextern int CeedElemRestrictionGetLLayout(CeedElemRestriction, CeedInt layout[3]);' 66header += '\nextern int CeedElemRestrictionGetELayout(CeedElemRestriction, CeedInt layout[3]);' 67 68# Note: cffi cannot handle vargs 69header = re.sub("va_list", "const char *", header) 70 71ffibuilder.cdef(header) 72 73ffibuilder.set_source("_ceed_cffi", 74 """ 75 #define va_list const char * 76 #include <ceed.h> // the C header of the library 77 #include <ceed/backend.h> // declarations for the backend functions above 78 """, 79 include_dirs=[ 80 os.path.join(ceed_dir, "include")], # include path 81 libraries=["ceed"], # library name, for the linker 82 # library path, for the linker 83 library_dirs=[ceed_libdir], 84 # use libceed.so as installed 85 runtime_library_dirs=['$ORIGIN/libceed/lib'] 86 ) 87 88# ------------------------------------------------------------------------------ 89# Builder 90# ------------------------------------------------------------------------------ 91if __name__ == "__main__": 92 ffibuilder.compile(verbose=True) 93 94# ------------------------------------------------------------------------------ 95