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. 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) Plugins are dependent on the LAMMPS binary interface (ABI)
and particularly the MPI library used. So they are not guaranteed and particularly the MPI library used. So they are not guaranteed
to work when the plugin was compiled with a different MPI library 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 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON) 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}) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR})
include(CheckIncludeFileCXX) include(CheckIncludeFileCXX)
include(LAMMPSInterfaceCXX) include(LAMMPSInterfaceCXX)
@ -53,12 +48,13 @@ target_link_libraries(nve2plugin PRIVATE lammps)
add_library(helloplugin MODULE helloplugin.cpp) add_library(helloplugin MODULE helloplugin.cpp)
target_link_libraries(helloplugin PRIVATE lammps) target_link_libraries(helloplugin PRIVATE lammps)
set_target_properties(morse2plugin nve2plugin helloplugin PROPERTIES set_target_properties(morse2plugin nve2plugin helloplugin PROPERTIES PREFIX "")
PREFIX ""
LINK_FLAGS "-rdynamic")
# MacOS seems to need this
if(CMAKE_SYSTEM_NAME STREQUAL Darwin) if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
set_target_properties(morse2plugin nve2plugin helloplugin PROPERTIES set_target_properties(morse2plugin nve2plugin helloplugin PROPERTIES
LINK_FLAGS "-Wl,-undefined,dynamic_lookup") 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() 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 ARCHIVE = ar
ARFLAGS = -rc ARFLAGS = -rc
SHLIBFLAGS = -shared SHLIBFLAGS = -shared -rdynamic
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
# LAMMPS-specific settings, all OPTIONAL # LAMMPS-specific settings, all OPTIONAL

View File

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

View File

@ -24,12 +24,49 @@
#include <map> #include <map>
#include <list> #include <list>
#ifdef _WIN32 #if defined(_WIN32)
#include <windows.h> #include <windows.h>
#else #else
#include <dlfcn.h> #include <dlfcn.h>
#endif #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 namespace LAMMPS_NS
{ {
// list of plugin information data for loaded styles // list of plugin information data for loaded styles
@ -42,13 +79,11 @@ namespace LAMMPS_NS
void plugin_load(const char *file, LAMMPS *lmp) void plugin_load(const char *file, LAMMPS *lmp)
{ {
int me = lmp->comm->me; 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 // 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 (dso == nullptr) {
if (me == 0) if (me == 0)
utils::logmesg(lmp,fmt::format("Open of file {} failed\n",file)); 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 // look up lammpsplugin_init() function in DSO
// function must have C bindings so there is no name mangling // 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) { if (initfunc == nullptr) {
dlclose(dso); my_dlclose(dso);
if (me == 0) if (me == 0)
utils::logmesg(lmp,fmt::format("Plugin symbol lookup failure in " utils::logmesg(lmp,fmt::format("Plugin symbol lookup failure in "
@ -74,7 +110,6 @@ namespace LAMMPS_NS
(*(lammpsplugin_initfunc)(initfunc))((void *)lmp, dso, (*(lammpsplugin_initfunc)(initfunc))((void *)lmp, dso,
(void *)&plugin_register); (void *)&plugin_register);
#endif
} }
/* -------------------------------------------------------------------- /* --------------------------------------------------------------------
@ -221,11 +256,7 @@ namespace LAMMPS_NS
// if reference count is down to zero, close DSO handle. // if reference count is down to zero, close DSO handle.
-- dso_refcounter[handle]; -- dso_refcounter[handle];
if (dso_refcounter[handle] == 0) { if (dso_refcounter[handle] == 0) my_dlclose(handle);
#ifndef WIN32
dlclose(handle);
#endif
}
} }
/* -------------------------------------------------------------------- /* --------------------------------------------------------------------