233 lines
9.3 KiB
ReStructuredText
233 lines
9.3 KiB
ReStructuredText
Link LAMMPS as a library to another code
|
|
========================================
|
|
|
|
LAMMPS is designed as a library of C++ objects that can be integrated
|
|
into other applications, including Python scripts. The files
|
|
``src/library.cpp`` and ``src/library.h`` define a C-style API for using
|
|
LAMMPS as a library. See the :doc:`Howto_library` page for a
|
|
description of the interface and how to use it for your needs.
|
|
|
|
The :doc:`Build_basics` page explains how to build LAMMPS as either a
|
|
shared or static library. This results in a file in the compilation
|
|
folder called ``liblammps.a`` or ``liblammps_<name>.a`` in case of
|
|
building a static library. In case of a shared library, the name is the
|
|
same only that the suffix is going to be either ``.so`` or ``.dylib`` or
|
|
``.dll`` instead of ``.a`` depending on the OS. In some cases, the
|
|
``.so`` file may be a symbolic link to a file with the suffix ``.so.0``
|
|
(or some other number).
|
|
|
|
.. note::
|
|
|
|
Care should be taken to use the same MPI library for the calling code
|
|
and the LAMMPS library, unless LAMMPS is to be compiled without (real)
|
|
MPI support using the included STUBS MPI library.
|
|
|
|
Link with LAMMPS as a static library
|
|
------------------------------------
|
|
|
|
The calling application can link to LAMMPS as a static library with
|
|
compilation and link commands, as in the examples shown below. These
|
|
are examples for a code written in C in the file ``caller.c``.
|
|
The benefit of linking to a static library is, that the resulting
|
|
executable is independent of that library since all required
|
|
executable code from the library is copied into the calling executable.
|
|
|
|
.. tabs::
|
|
|
|
.. tab:: CMake build
|
|
|
|
This assumes that LAMMPS has been configured without setting a
|
|
``LAMMPS_MACHINE`` name, installed with "make install", and the
|
|
``PKG_CONFIG_PATH`` environment variable has been updated to
|
|
include the ``liblammps.pc`` file installed into the configured
|
|
destination folder. The commands to compile and link a coupled
|
|
executable are then:
|
|
|
|
.. code-block:: bash
|
|
|
|
mpicc -c -O $(pkg-config --cflags liblammps) caller.c
|
|
mpicxx -o caller caller.o -$(pkg-config --libs liblammps)
|
|
|
|
.. tab:: Traditional make
|
|
|
|
This assumes that LAMMPS has been compiled in the folder
|
|
``${HOME}/lammps/src`` with "make mpi". The commands to compile
|
|
and link a coupled executable are then:
|
|
|
|
.. code-block:: bash
|
|
|
|
mpicc -c -O -I${HOME}/lammps/src caller.c
|
|
mpicxx -o caller caller.o -L${HOME}/lammps/src -llammps_mpi
|
|
|
|
The *-I* argument is the path to the location of the ``library.h``
|
|
header file containing the interface to the LAMMPS C-style library
|
|
interface. The *-L* argument is the path to where the
|
|
``liblammps_mpi.a`` file is located. The *-llammps_mpi* argument
|
|
is shorthand for telling the compiler to link the file
|
|
``liblammps_mpi.a``. If LAMMPS has been built as a shared
|
|
library, then the linker will use ``liblammps_mpi.so`` instead.
|
|
If both files are available, the linker will usually prefer the
|
|
shared library. In case of a shared library, you may need to
|
|
update the ``LD_LIBRARY_PATH`` environment variable or running the
|
|
``caller`` executable will fail since it cannot find the shared
|
|
library at runtime.
|
|
|
|
However, it is only as simple as shown above for the case of a plain
|
|
LAMMPS library without any optional packages that depend on libraries
|
|
(bundled or external) or when using a shared library. Otherwise, you
|
|
need to include all flags, libraries, and paths for the coupled
|
|
executable, that are also required to link the LAMMPS executable.
|
|
|
|
.. tabs::
|
|
|
|
.. tab:: CMake build
|
|
|
|
When using CMake, additional libraries with sources in the lib
|
|
folder are built, but not included in ``liblammps.a`` and
|
|
(currently) not installed with ``make install`` and not included
|
|
in the ``pkgconfig`` configuration file. They can be found in the
|
|
top level build folder, but you have to determine the necessary
|
|
link flags manually. It is therefore recommended to either use
|
|
the traditional make procedure to build and link with a static
|
|
library or build and link with a shared library instead.
|
|
|
|
.. tab:: Traditional make
|
|
|
|
After you have compiled a static LAMMPS library using the
|
|
conventional build system for example with "make mode=static
|
|
serial". And you also have installed the ``POEMS`` package after
|
|
building its bundled library in ``lib/poems``. Then the commands
|
|
to build and link the coupled executable change to:
|
|
|
|
.. code-block:: bash
|
|
|
|
gcc -c -O -I${HOME}/lammps/src -caller.c
|
|
g++ -o caller caller.o -L${HOME}/lammps/lib/poems \
|
|
-L${HOME}/lammps/src/STUBS -L${HOME}/lammps/src \
|
|
-llammps_serial -lpoems -lmpi_stubs
|
|
|
|
Note, that you need to link with ``g++`` instead of ``gcc`` even
|
|
if you have written your code in C, since LAMMPS itself is C++
|
|
code. You can display the currently applied settings for building
|
|
LAMMPS for the "serial" machine target by using the command:
|
|
|
|
.. code-block:: bash
|
|
|
|
make mode=print serial
|
|
|
|
Which should output something like:
|
|
|
|
.. code-block:: bash
|
|
|
|
# Compiler:
|
|
CXX=g++
|
|
# Linker:
|
|
LD=g++
|
|
# Compilation:
|
|
CXXFLAGS=-g -O3 -DLAMMPS_GZIP -DLAMMPS_MEMALIGN=64 -I${HOME}/compile/lammps/lib/poems -I${HOME}/compile/lammps/src/STUBS
|
|
# Linking:
|
|
LDFLAGS=-g -O
|
|
# Libraries:
|
|
LDLIBS=-L${HOME}/compile/lammps/src -llammps_serial -L${HOME}/compile/lammps/lib/poems -L${HOME}/compile/lammps/src/STUBS -lpoems -lmpi_stubs
|
|
|
|
From this you can gather the necessary paths and flags. With
|
|
makefiles for other *machine* configurations you need to do the
|
|
equivalent and replace "serial" with the corresponding "machine"
|
|
name of the makefile.
|
|
|
|
Link with LAMMPS as a shared library
|
|
------------------------------------
|
|
|
|
When linking to LAMMPS built as a shared library, the situation becomes
|
|
much simpler, as all dependent libraries and objects are either included
|
|
in the shared library or registered as a dependent library in the shared
|
|
library file. Thus, those libraries need not be specified when linking
|
|
the calling executable. Only the *-I* flags are needed. So the example
|
|
case from above of the serial version static LAMMPS library with the
|
|
POEMS package installed becomes:
|
|
|
|
.. tabs::
|
|
|
|
.. tab:: CMake build
|
|
|
|
The commands with a shared LAMMPS library compiled with the CMake
|
|
build process are the same as for the static library.
|
|
|
|
.. code-block:: bash
|
|
|
|
mpicc -c -O $(pkg-config --cflags liblammps) caller.c
|
|
mpicxx -o caller caller.o -$(pkg-config --libs liblammps)
|
|
|
|
.. tab:: Traditional make
|
|
|
|
The commands with a shared LAMMPS library compiled with the
|
|
traditional make build using ``make mode=shared serial`` becomes:
|
|
|
|
.. code-block:: bash
|
|
|
|
gcc -c -O -I${HOME}/lammps/src -caller.c
|
|
g++ -o caller caller.o -L${HOME}/lammps/src -llammps_serial
|
|
|
|
Locating liblammps.so at runtime
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Unlike with a static link, now the ``liblammps.so`` file is required at
|
|
runtime and needs to be in a folder, where the shared linker program of
|
|
the operating system can find it. This would be either a folder like
|
|
``/usr/local/lib64`` or ``${HOME}/.local/lib64`` or a folder pointed to
|
|
by the ``LD_LIBRARY_PATH`` environment variable. You can type
|
|
|
|
.. code-block:: bash
|
|
|
|
printenv LD_LIBRARY_PATH
|
|
|
|
to see what directories are in that list.
|
|
|
|
Or you can add the LAMMPS src directory or the directory you performed a
|
|
CMake style build in to your ``LD_LIBRARY_PATH`` environment variable,
|
|
so that the current version of the shared library is always available to
|
|
programs that use it.
|
|
|
|
For the Bourne or Korn shells (/bin/sh, /bin/ksh, /bin/bash etc.), you
|
|
would add something like this to your ``${HOME}/.profile`` file:
|
|
|
|
.. code-block:: bash
|
|
|
|
LD_LIBRARY_PATH ${LD_LIBRARY_PATH-/usr/lib64}:${HOME}/lammps/src
|
|
export LD_LIBRARY_PATH
|
|
|
|
For the csh or tcsh shells, you would equivalently add something like this
|
|
to your ``${HOME}/.cshrc`` file:
|
|
|
|
.. code-block:: csh
|
|
|
|
setenv LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:${HOME}/lammps/src
|
|
|
|
You can verify whether all required shared libraries are found with the
|
|
``ldd`` tool. Example:
|
|
|
|
.. code-block:: bash
|
|
|
|
LD_LIBRARY_PATH=/home/user/lammps/src ldd caller
|
|
linux-vdso.so.1 (0x00007ffe729e0000)
|
|
liblammps.so => /home/user/lammps/src/liblammps.so (0x00007fc91bb9e000)
|
|
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fc91b984000)
|
|
libm.so.6 => /lib64/libm.so.6 (0x00007fc91b83e000)
|
|
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fc91b824000)
|
|
libc.so.6 => /lib64/libc.so.6 (0x00007fc91b65b000)
|
|
/lib64/ld-linux-x86-64.so.2 (0x00007fc91c094000)
|
|
|
|
If a required library is missing, you would get a 'not found' entry:
|
|
|
|
.. code-block:: bash
|
|
|
|
ldd caller
|
|
linux-vdso.so.1 (0x00007ffd672fe000)
|
|
liblammps.so => not found
|
|
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fb7c7e86000)
|
|
libm.so.6 => /usr/lib64/libm.so.6 (0x00007fb7c7d40000)
|
|
libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007fb7c7d26000)
|
|
libc.so.6 => /usr/lib64/libc.so.6 (0x00007fb7c7b5d000)
|
|
/lib64/ld-linux-x86-64.so.2 (0x00007fb7c80a2000)
|
|
|