add preliminary support for compiling/loading plugins on windows

This commit is contained in:
Axel Kohlmeyer
2021-03-12 22:21:11 -05:00
parent b2085f56d6
commit 3e90b1971a
6 changed files with 85 additions and 25 deletions

View File

@ -58,6 +58,9 @@ Restrictions
Plugins are currently not available on Windows.
For the loading of plugins to work, the LAMMPS library must be
:ref:`compiled as a shared library <library>`.
Plugins are dependent on the LAMMPS binary interface (ABI)
and particularly the MPI library used. So they are not guaranteed
to work when the plugin was compiled with a different MPI library

View File

@ -31,11 +31,6 @@ endif()
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# bail out on windows
if(CMAKE_SYSTEM_NAME STREQUAL Windows)
message(FATAL_ERROR "LAMMPS plugins are currently not supported on Windows")
endif()
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR})
include(CheckIncludeFileCXX)
include(LAMMPSInterfaceCXX)
@ -53,12 +48,13 @@ target_link_libraries(nve2plugin PRIVATE lammps)
add_library(helloplugin MODULE helloplugin.cpp)
target_link_libraries(helloplugin PRIVATE lammps)
set_target_properties(morse2plugin nve2plugin helloplugin PROPERTIES
PREFIX ""
LINK_FLAGS "-rdynamic")
set_target_properties(morse2plugin nve2plugin helloplugin PROPERTIES PREFIX "")
# MacOS seems to need this
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
set_target_properties(morse2plugin nve2plugin helloplugin PROPERTIES
LINK_FLAGS "-Wl,-undefined,dynamic_lookup")
elseif(CMAKE_SYSTEM_NAME STREQUAL Windows)
set_target_properties(morse2plugin nve2plugin helloplugin PROPERTIES LINK_FLAGS "-Wl,--undefined")
else()
set_target_properties(morse2plugin nve2plugin helloplugin PROPERTIES LINK_FLAGS "-rdynamic")
endif()

View File

@ -0,0 +1,30 @@
CXX=g++
CXXFLAGS=-I../../src -I../../src/STUBS -Wall -Wextra -O3 -fPIC -I../../src/USER-OMP -fopenmp
LD=$(CXX) -shared -rdynamic -fopenmp
default: morse2plugin.so nve2plugin.so helloplugin.so
helloplugin.so: helloplugin.o
$(LD) -o $@ $^
morse2plugin.so: morse2plugin.o pair_morse2.o pair_morse2_omp.o
$(LD) -o $@ $^
nve2plugin.so: nve2plugin.o fix_nve2.o
$(LD) -o $@ $^
.cpp.o:
$(CXX) -o $@ $(CXXFLAGS) -c $<
helloplugin.o: helloplugin.cpp
pair_morse2.o: pair_morse2.cpp pair_morse2.h
pair_morse2_omp.o: pair_morse2_omp.cpp pair_morse2_omp.h pair_morse2.h
morse2plugin.o: morse2plugin.cpp pair_morse2.h pair_morse2_omp.h
fix_nve2.o: fix_nve2.cpp fix_nve2.h
nve2plugin.o: nve2plugin.cpp fix_nve2.h
clean:
rm -rf *~ *.so *.dylib *.o log.lammps CMakeCache.txt CMakeFiles

View File

@ -18,7 +18,7 @@ SIZE = size
ARCHIVE = ar
ARFLAGS = -rc
SHLIBFLAGS = -shared
SHLIBFLAGS = -shared -rdynamic
# ---------------------------------------------------------------------
# LAMMPS-specific settings, all OPTIONAL

View File

@ -18,7 +18,7 @@ SIZE = size
ARCHIVE = ar
ARFLAGS = -rc
SHLIBFLAGS = -shared
SHLIBFLAGS = -shared -rdynamic
# ---------------------------------------------------------------------
# LAMMPS-specific settings, all OPTIONAL

View File

@ -24,12 +24,49 @@
#include <map>
#include <list>
#ifdef _WIN32
#if defined(_WIN32)
#include <windows.h>
#else
#include <dlfcn.h>
#endif
#if defined(_WIN32)
// open a shared object file
static void *my_dlopen(const char *fname) {
return (void *)LoadLibrary(fname);
}
// resolve a symbol in shared object
static void *my_dlsym(void *h, const char *sym) {
return (void *)GetProcAddress((HINSTANCE)h, sym);
}
// close a shared object
static int my_dlclose(void *h) {
/* FreeLibrary returns nonzero on success */
return !FreeLibrary((HINSTANCE)h);
}
#else
// open a shared object file
static void *my_dlopen(const char *fname) {
return dlopen(fname, RTLD_NOW|RTLD_GLOBAL);
}
// resolve a symbol in shared object
static void *my_dlsym(void *h, const char *sym) {
return dlsym(h, sym);
}
// close a shared object
static int my_dlclose(void *h) {
return dlclose(h);
}
#endif
namespace LAMMPS_NS
{
// list of plugin information data for loaded styles
@ -42,13 +79,11 @@ namespace LAMMPS_NS
void plugin_load(const char *file, LAMMPS *lmp)
{
int me = lmp->comm->me;
#if defined(WIN32)
lmp->error->all(FLERR,"Loading of plugins on Windows not yet supported\n");
#else
// open DSO file from given path; load symbols globally
void *dso = dlopen(file,RTLD_NOW|RTLD_GLOBAL);
void *dso = my_dlopen(file);
if (dso == nullptr) {
if (me == 0)
utils::logmesg(lmp,fmt::format("Open of file {} failed\n",file));
@ -58,9 +93,10 @@ namespace LAMMPS_NS
// look up lammpsplugin_init() function in DSO
// function must have C bindings so there is no name mangling
void *initfunc = dlsym(dso,"lammpsplugin_init");
void *initfunc = my_dlsym(dso,"lammpsplugin_init");
if (initfunc == nullptr) {
dlclose(dso);
my_dlclose(dso);
if (me == 0)
utils::logmesg(lmp,fmt::format("Plugin symbol lookup failure in "
@ -74,7 +110,6 @@ namespace LAMMPS_NS
(*(lammpsplugin_initfunc)(initfunc))((void *)lmp, dso,
(void *)&plugin_register);
#endif
}
/* --------------------------------------------------------------------
@ -221,11 +256,7 @@ namespace LAMMPS_NS
// if reference count is down to zero, close DSO handle.
-- dso_refcounter[handle];
if (dso_refcounter[handle] == 0) {
#ifndef WIN32
dlclose(handle);
#endif
}
if (dso_refcounter[handle] == 0) my_dlclose(handle);
}
/* --------------------------------------------------------------------