From feb3fb9cf2ed4ef8b631d07e9b9b0d5c965938e4 Mon Sep 17 00:00:00 2001 From: Giovanni Bussi <giovanni.bussi@gmail.com> Date: Mon, 12 Nov 2018 10:17:11 +0100 Subject: [PATCH] Made python wrapper self-contained It does not link to library anymore, but just includes Plumed.h file. It thus could be compiled with different compilers and flags wrt plumed. Notice that as of PLUMED 2.5 Plumed.h also contains the full implementation of the dynamic loader, so it is sufficient to define the proper cpp flags in order to recompile the loader and avoiding the need to link plumedWrapper.a. This basically allows the python wrapper to be selfcontained and installable before having installed plumed. --- python/Makefile | 14 ++------------ python/buildPythonInterface.py | 28 ++++++++++++++++------------ python/cplumed.pxd | 7 +++++-- python/plumed.pyx | 2 ++ src/lib/Makefile | 10 ++-------- 5 files changed, 27 insertions(+), 34 deletions(-) diff --git a/python/Makefile b/python/Makefile index e552d225d..072c148ad 100644 --- a/python/Makefile +++ b/python/Makefile @@ -16,22 +16,12 @@ else ifdef python_bin -ifeq ($(SOEXT),dylib) -PYTHON_EXTRA_LDFLAGS=-undefined dynamic_lookup -else -PYTHON_EXTRA_LDFLAGS= -endif - all: @echo Building python interface for PLUMED - LD_LIBRARY_PATH=$$PWD/../src/lib:$$LD_LIBRARY_PATH \ - CC="$(CC)" \ - LDSHARED="$(LDSHARED) $(PYTHON_EXTRA_LDFLAGS)" \ - CXX="$(CXX)" \ + unset CXX && unset CC && unset CFLAGS && unset CXXFLAGS && unset LDSHARED && \ program_name=plumed \ - plumedexe=../src/lib/plumed \ include_dir=../src/wrapper \ - lib_dir=../src/lib \ + default_kernel="$$PWD/../src/lib/libplumedKernel.$(SOEXT)" \ $(python_bin) buildPythonInterface.py build_ext -i else diff --git a/python/buildPythonInterface.py b/python/buildPythonInterface.py index 191644038..ffb33307a 100644 --- a/python/buildPythonInterface.py +++ b/python/buildPythonInterface.py @@ -29,31 +29,35 @@ import numpy import subprocess import os -# Function for checking if PLUMED is in path -def is_exe(fpath): - return os.path.isfile(fpath) and os.access(fpath, os.X_OK) +plumedname = os.getenv("program_name") +if plumedname is None: + plumedname = "plumed" -plumedexe=os.environ["plumedexe"] +plumedversion = subprocess.check_output(['grep','-v','#','../VERSION']).decode("utf-8") -plumedversion = subprocess.check_output([plumedexe, 'info', '--version']).decode("utf-8") -print( "Version number for this plumed is " + plumedversion ) +print( "Module name " + plumedname ) +print( "Version number " + plumedversion ) -print( "Building interface using CC=" + os.environ["CC"] + " , CXX=" + os.environ["CXX"] + " and LDSHARED=" + os.environ["LDSHARED"] ) +extra_compile_args=['-D__PLUMED_HAS_DLOPEN','-D__PLUMED_WRAPPER_LINK_RUNTIME=1','-D__PLUMED_WRAPPER_CXX=1','-D__PLUMED_WRAPPER_IMPLEMENTATION=1','-D__PLUMED_WRAPPER_EXTERN=0'] + +defaultkernel=os.getenv("default_kernel") +if defaultkernel is not None: + extra_compile_args.append("-D__PLUMED_DEFAULT_KERNEL=" + os.path.abspath(defaultkernel)) + print( "Hardcoded PLUMED_KERNEL " + os.path.abspath(defaultkernel)) setup( - name='plumed', + name=plumedname, version=plumedversion, description='Python interface to PLUMED', author='Gareth A. Tribello', author_email='plumed-users@googlegroups.com', url='http://www.plumed.org', ext_modules = cythonize([ - Extension( name="plumed", + Extension( name=plumedname, sources=["plumed.pyx"], - library_dirs=[os.environ["lib_dir"]], - libraries=[os.environ["program_name"]], language="c++", - include_dirs=[os.environ["include_dir"], numpy.get_include()] + include_dirs=[os.environ["include_dir"], numpy.get_include()], + extra_compile_args=extra_compile_args ) ]) ) diff --git a/python/cplumed.pxd b/python/cplumed.pxd index 5450a008d..513ec72be 100644 --- a/python/cplumed.pxd +++ b/python/cplumed.pxd @@ -23,10 +23,13 @@ # This create cython wrappers to the main bits of the PLUMED libraray # +from libcpp cimport bool + +# Some of these functions are noexcept. +# We anyway use except + in case this changes later. cdef extern from "Plumed.h" namespace "PLMD": cdef cppclass Plumed: Plumed() except + void cmd(const char*key, const void*val) except + void cmd(const char*key) except + - - + bool valid() except + diff --git a/python/plumed.pyx b/python/plumed.pyx index 032764a2f..96b99f335 100644 --- a/python/plumed.pyx +++ b/python/plumed.pyx @@ -31,6 +31,8 @@ cimport numpy as np cdef class Plumed: cdef cplumed.Plumed c_plumed def __cinit__(self): + if not self.c_plumed.valid(): + raise RuntimeError("PLUMED not available, check your PLUMED_KERNEL environment variable") cdef int pres = 8 self.c_plumed.cmd( "setRealPrecision", <void*>&pres ) def cmd_ndarray_real(self, ckey, val): diff --git a/src/lib/Makefile b/src/lib/Makefile index 3927668cb..9cb765941 100644 --- a/src/lib/Makefile +++ b/src/lib/Makefile @@ -17,8 +17,6 @@ ifneq ($(MAKECMDGOALS),clean) endif ifeq ($(SOEXT),dylib) -# Extra flags required to properly compile the python interface - PYTHON_EXTRA_LDFLAGS:=-undefined dynamic_lookup SONAME_OPTION:=-Wl,-install_name else PYTHON_EXTRA_LDFLAGS:= @@ -314,14 +312,10 @@ endif ifdef python_bin cp -pr ../../python install cd install/python && rm -fr *.so plumed.cpp build && \ - LD_LIBRARY_PATH=$$PWD/../..:$$LD_LIBRARY_PATH \ - CC="$(CC)" \ - LDSHARED="$(LDSHARED) $(PYTHON_EXTRA_LDFLAGS)" \ - CXX="$(CXX)" \ - plumedexe="../../plumed" \ + unset CXX && unset CC && unset CFLAGS && unset CXXFLAGS && unset LDSHARED && \ program_name="$(program_name)" \ include_dir=../../../wrapper \ - lib_dir="$(DESTDIR)$(libdir)" \ + default_kernel="$(libdir)/lib$(program_name)Kernel.$(SOEXT)" \ $(python_bin) buildPythonInterface.py build_ext -i cp -pr install/python "$(DESTDIR)$(libdir)/$(program_name)/" endif -- GitLab