######################################## # CMake build system # This file is part of LAMMPS # Created by Christoph Junghans and Richard Berger cmake_minimum_required(VERSION 3.10) # set policy to silence warnings about ignoring _ROOT but use it if(POLICY CMP0074) cmake_policy(SET CMP0074 NEW) endif() # set policy to silence warnings about missing executable permissions in # pythonx.y-config when cross-compiling. review occasionally if it may be set to NEW if(POLICY CMP0109) cmake_policy(SET CMP0109 OLD) endif() ######################################## project(lammps CXX) set(SOVERSION 0) get_property(BUILD_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) get_filename_component(LAMMPS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/.. ABSOLUTE) get_filename_component(LAMMPS_LIB_BINARY_DIR ${CMAKE_BINARY_DIR}/lib ABSOLUTE) # collect all executables and shared libs in the top level build folder set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(LAMMPS_SOURCE_DIR ${LAMMPS_DIR}/src) set(LAMMPS_LIB_SOURCE_DIR ${LAMMPS_DIR}/lib) set(LAMMPS_DOC_DIR ${LAMMPS_DIR}/doc) set(LAMMPS_TOOLS_DIR ${LAMMPS_DIR}/tools) set(LAMMPS_PYTHON_DIR ${LAMMPS_DIR}/python) set(LAMMPS_POTENTIALS_DIR ${LAMMPS_DIR}/potentials) set(LAMMPS_DOWNLOADS_URL "https://download.lammps.org" CACHE STRING "Base URL for LAMMPS downloads") set(LAMMPS_POTENTIALS_URL "${LAMMPS_DOWNLOADS_URL}/potentials") set(LAMMPS_THIRDPARTY_URL "${LAMMPS_DOWNLOADS_URL}/thirdparty") mark_as_advanced(LAMMPS_DOWNLOADS_URL) find_package(Git) # by default, install into $HOME/.local (not /usr/local), so that no root access (and sudo!!) is needed if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) if((CMAKE_SYSTEM_NAME STREQUAL "Windows") AND (NOT CMAKE_CROSSCOMPILING)) set(CMAKE_INSTALL_PREFIX "$ENV{USERPROFILE}/LAMMPS" CACHE PATH "Default install path" FORCE) else() set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/.local" CACHE PATH "Default install path" FORCE) endif() endif() # If enabled, no need to use LD_LIBRARY_PATH / DYLD_LIBRARY_PATH when installed option(LAMMPS_INSTALL_RPATH "Set runtime path for shared libraries linked to LAMMPS binaries" OFF) if(LAMMPS_INSTALL_RPATH) set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON) endif() # Cmake modules/macros are in a subdirectory to keep this file cleaner set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Modules) # make sure LIBRARY_PATH is set if environment variable is set if(DEFINED ENV{LIBRARY_PATH}) list(APPEND CMAKE_LIBRARY_PATH "$ENV{LIBRARY_PATH}") message(STATUS "Appending $ENV{LIBRARY_PATH} to CMAKE_LIBRARY_PATH: ${CMAKE_LIBRARY_PATH}") endif() include(LAMMPSUtils) get_lammps_version(${LAMMPS_SOURCE_DIR}/version.h PROJECT_VERSION) include(PreventInSourceBuilds) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CXX_FLAGS) set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE) endif(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CXX_FLAGS) string(TOUPPER "${CMAKE_BUILD_TYPE}" BTYPE) # check for files auto-generated by make-based buildsystem # this is fast, so check for it all the time check_for_autogen_files(${LAMMPS_SOURCE_DIR}) ###################################################################### # compiler tests # these need ot be done early (before further tests). ##################################################################### include(CheckIncludeFileCXX) # set required compiler flags and compiler/CPU arch specific optimizations if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel") if(CMAKE_SYSTEM_NAME STREQUAL "Windows") if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Qrestrict") endif() if(CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 17.3 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 17.4) set(CMAKE_TUNE_DEFAULT "/QxCOMMON-AVX512") else() set(CMAKE_TUNE_DEFAULT "/QxHost") endif() else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -restrict") if(CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 17.3 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 17.4) set(CMAKE_TUNE_DEFAULT "-xCOMMON-AVX512") else() set(CMAKE_TUNE_DEFAULT "-xHost") endif() endif() endif() # silence excessive warnings for new Intel Compilers if(CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM") set(CMAKE_TUNE_DEFAULT "-Wno-tautological-constant-compare -Wno-unused-command-line-argument") endif() # silence excessive warnings for PGI/NVHPC compilers if((CMAKE_CXX_COMPILER_ID STREQUAL "NVHPC") OR (CMAKE_CXX_COMPILER_ID STREQUAL "PGI")) set(CMAKE_TUNE_DEFAULT "-Minform=severe") endif() # silence nvcc warnings if((PKG_KOKKOS) AND (Kokkos_ENABLE_CUDA) AND NOT (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")) set(CMAKE_TUNE_DEFAULT "${CMAKE_TUNE_DEFAULT} -Xcudafe --diag_suppress=unrecognized_pragma") endif() # we require C++11 without extensions. Kokkos requires at least C++14 (currently) if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 11) endif() if(CMAKE_CXX_STANDARD LESS 11) message(FATAL_ERROR "C++ standard must be set to at least 11") endif() if(PKG_KOKKOS AND (CMAKE_CXX_STANDARD LESS 14)) set(CMAKE_CXX_STANDARD 14) endif() set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF CACHE BOOL "Use compiler extensions") # ugly hacks for MSVC which by default always reports an old C++ standard in the __cplusplus macro # and prints lots of pointless warnings about "unsafe" functions if(MSVC) add_compile_options(/Zc:__cplusplus) add_compile_options(/wd4244) add_compile_options(/wd4267) if(LAMMPS_EXCEPTIONS) add_compile_options(/EHsc) endif() add_compile_definitions(_CRT_SECURE_NO_WARNINGS) endif() # export all symbols when building a .dll file on windows if((CMAKE_SYSTEM_NAME STREQUAL "Windows") AND BUILD_SHARED_LIBS) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) endif() ######################################################################## # User input options # ######################################################################## set(LAMMPS_MACHINE "" CACHE STRING "Suffix to append to lmp binary (WON'T enable any features automatically") mark_as_advanced(LAMMPS_MACHINE) if(LAMMPS_MACHINE) set(LAMMPS_MACHINE "_${LAMMPS_MACHINE}") endif() set(LAMMPS_BINARY lmp${LAMMPS_MACHINE}) option(BUILD_SHARED_LIBS "Build shared library" OFF) option(CMAKE_POSITION_INDEPENDENT_CODE "Create object compatible with shared libraries" ON) option(BUILD_TOOLS "Build and install LAMMPS tools (msi2lmp, binary2txt, chain)" OFF) option(BUILD_LAMMPS_SHELL "Build and install the LAMMPS shell" OFF) # Support using clang-tidy for C++ files with selected options set(ENABLE_CLANG_TIDY OFF CACHE BOOL "Include clang-tidy processing when compiling") if(ENABLE_CLANG_TIDY) set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-checks=-*,performance-trivially-destructible,performance-unnecessary-copy-initialization,performance-unnecessary-value-param,readability-redundant-control-flow,readability-redundant-declaration,readability-redundant-function-ptr-dereference,readability-redundant-member-init,readability-redundant-string-cstr,readability-redundant-string-init,readability-simplify-boolean-expr,readability-static-accessed-through-instance,readability-static-definition-in-anonymous-namespace,modernize-use-override,modernize-use-bool-literals,modernize-use-emplace,modernize-return-braced-init-list,modernize-use-equals-default,modernize-use-equals-delete,modernize-replace-random-shuffle,modernize-deprecated-headers,modernize-use-nullptr,modernize-use-noexcept,modernize-redundant-void-arg;-fix;-header-filter=.*,header-filter=library.h,header-filter=fmt/*.h" CACHE STRING "clang-tidy settings") else() unset(CMAKE_CXX_CLANG_TIDY CACHE) endif() include(GNUInstallDirs) file(GLOB ALL_SOURCES ${LAMMPS_SOURCE_DIR}/[^.]*.cpp) file(GLOB MAIN_SOURCES ${LAMMPS_SOURCE_DIR}/main.cpp) list(REMOVE_ITEM ALL_SOURCES ${MAIN_SOURCES}) add_library(lammps ${ALL_SOURCES}) # tell CMake to export all symbols to a .dll on Windows with MinGW cross-compilers if(BUILD_SHARED_LIBS AND (CMAKE_SYSTEM_NAME STREQUAL "Windows") AND CMAKE_CROSSCOMPILING) set_target_properties(lammps PROPERTIES LINK_FLAGS "-Wl,--export-all-symbols") endif() add_executable(lmp ${MAIN_SOURCES}) target_link_libraries(lmp PRIVATE lammps) set_target_properties(lmp PROPERTIES OUTPUT_NAME ${LAMMPS_BINARY}) install(TARGETS lmp EXPORT LAMMPS_Targets DESTINATION ${CMAKE_INSTALL_BINDIR}) option(CMAKE_VERBOSE_MAKEFILE "Generate verbose Makefiles" OFF) set(STANDARD_PACKAGES ADIOS ASPHERE ATC AWPMD BOCS BODY BPM BROWNIAN CG-DNA CG-SDK CLASS2 COLLOID COLVARS COMPRESS DIELECTRIC DIFFRACTION DIPOLE DPD-BASIC DPD-MESO DPD-REACT DPD-SMOOTH DRUDE EFF ELECTRODE EXTRA-COMPUTE EXTRA-DUMP EXTRA-FIX EXTRA-MOLECULE EXTRA-PAIR FEP GRANULAR H5MD INTERLAYER KIM KSPACE LATBOLTZ LATTE MACHDYN MANIFOLD MANYBODY MC MDI MEAM MESONT MGPT MISC ML-HDNNP ML-IAP ML-PACE ML-QUIP ML-RANN ML-SNAP MOFFF MOLECULE MOLFILE MPIIO MSCG NETCDF ORIENT PERI PHONON PLUGIN PLUMED POEMS PTM PYTHON QEQ QMMM QTB REACTION REAXFF REPLICA RIGID SCAFACOS SHOCK SMTBQ SPH SPIN SRD TALLY UEF VORONOI VTK YAFF) set(SUFFIX_PACKAGES CORESHELL GPU KOKKOS OPT INTEL OPENMP) foreach(PKG ${STANDARD_PACKAGES} ${SUFFIX_PACKAGES}) option(PKG_${PKG} "Build ${PKG} Package" OFF) endforeach() ###################################################### # packages with special compiler needs or external libs ###################################################### target_include_directories(lammps PUBLIC $) if(PKG_ADIOS) # The search for ADIOS2 must come before MPI because # it includes its own MPI search with the latest FindMPI.cmake # script that defines the MPI::MPI_C target enable_language(C) find_package(ADIOS2 REQUIRED) target_link_libraries(lammps PRIVATE adios2::adios2) endif() if(NOT CMAKE_CROSSCOMPILING) find_package(MPI QUIET) option(BUILD_MPI "Build MPI version" ${MPI_FOUND}) else() option(BUILD_MPI "Build MPI version" OFF) endif() if(BUILD_MPI) # do not include the (obsolete) MPI C++ bindings which makes # for leaner object files and avoids namespace conflicts set(MPI_CXX_SKIP_MPICXX TRUE) # We use a non-standard procedure to cross-compile with MPI on Windows if((CMAKE_SYSTEM_NAME STREQUAL "Windows") AND CMAKE_CROSSCOMPILING) include(MPI4WIN) else() find_package(MPI REQUIRED) option(LAMMPS_LONGLONG_TO_LONG "Workaround if your system or MPI version does not recognize 'long long' data types" OFF) if(LAMMPS_LONGLONG_TO_LONG) target_compile_definitions(lammps PRIVATE -DLAMMPS_LONGLONG_TO_LONG) endif() endif() target_link_libraries(lammps PUBLIC MPI::MPI_CXX) else() target_sources(lammps PRIVATE ${LAMMPS_SOURCE_DIR}/STUBS/mpi.cpp) add_library(mpi_stubs INTERFACE) target_include_directories(mpi_stubs INTERFACE $) target_link_libraries(lammps PUBLIC mpi_stubs) endif() set(LAMMPS_SIZES "smallbig" CACHE STRING "LAMMPS integer sizes (smallsmall: all 32-bit, smallbig: 64-bit #atoms #timesteps, bigbig: also 64-bit imageint, 64-bit atom ids)") set(LAMMPS_SIZES_VALUES smallbig bigbig smallsmall) set_property(CACHE LAMMPS_SIZES PROPERTY STRINGS ${LAMMPS_SIZES_VALUES}) validate_option(LAMMPS_SIZES LAMMPS_SIZES_VALUES) string(TOUPPER ${LAMMPS_SIZES} LAMMPS_SIZES) target_compile_definitions(lammps PUBLIC -DLAMMPS_${LAMMPS_SIZES}) # posix_memalign is not available on Windows # with INTEL package and Intel compilers we use TBB's aligned malloc if((CMAKE_SYSTEM_NAME STREQUAL "Windows") AND NOT (PKG_INTEL AND ((CMAKE_CXX_COMPILER_ID STREQUAL "Intel") OR (CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")))) set(LAMMPS_MEMALIGN "0" CACHE STRING "posix_memalign() is not available on Windows" FORCE) else() set(LAMMPS_MEMALIGN "64" CACHE STRING "enables the use of the posix_memalign() call instead of malloc() when large chunks or memory are allocated by LAMMPS. Set to 0 to disable") endif() if(NOT ${LAMMPS_MEMALIGN} STREQUAL "0") target_compile_definitions(lammps PRIVATE -DLAMMPS_MEMALIGN=${LAMMPS_MEMALIGN}) endif() option(LAMMPS_EXCEPTIONS "enable the use of C++ exceptions for error messages (useful for library interface)" ${ENABLE_TESTING}) if(LAMMPS_EXCEPTIONS) target_compile_definitions(lammps PUBLIC -DLAMMPS_EXCEPTIONS) endif() # "hard" dependencies between packages resulting # in an error instead of skipping over files pkg_depends(ML-IAP ML-SNAP) pkg_depends(MPIIO MPI) pkg_depends(ATC MANYBODY) pkg_depends(LATBOLTZ MPI) pkg_depends(SCAFACOS MPI) pkg_depends(DIELECTRIC KSPACE) pkg_depends(DIELECTRIC EXTRA-PAIR) pkg_depends(CG-DNA MOLECULE) pkg_depends(CG-DNA ASPHERE) pkg_depends(ELECTRODE KSPACE) # detect if we may enable OpenMP support by default set(BUILD_OMP_DEFAULT OFF) find_package(OpenMP QUIET) if(OpenMP_FOUND) check_include_file_cxx(omp.h HAVE_OMP_H_INCLUDE) if(HAVE_OMP_H_INCLUDE) set(BUILD_OMP_DEFAULT ON) endif() endif() option(BUILD_OMP "Build with OpenMP support" ${BUILD_OMP_DEFAULT}) if(BUILD_OMP) find_package(OpenMP REQUIRED) check_include_file_cxx(omp.h HAVE_OMP_H_INCLUDE) if(NOT HAVE_OMP_H_INCLUDE) message(FATAL_ERROR "Cannot find the 'omp.h' header file required for full OpenMP support") endif() if(((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 9.0)) OR (CMAKE_CXX_COMPILER_ID STREQUAL "PGI") OR (CMAKE_CXX_COMPILER_ID STREQUAL "NVHPC") OR (CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM") OR (CMAKE_CXX_COMPILER_ID STREQUAL "XLClang") OR ((CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0)) OR ((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0)) OR ((CMAKE_CXX_COMPILER_ID STREQUAL "Intel") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.0))) # GCC 9.x and later plus Clang 10.x and later implement strict OpenMP 4.0 semantics for consts. # Intel 18.0 was tested to support both, so we switch to OpenMP 4+ from 19.x onward to be safe. set(LAMMPS_OMP_COMPAT_LEVEL 4) else() set(LAMMPS_OMP_COMPAT_LEVEL 3) endif() target_compile_definitions(lammps PRIVATE -DLAMMPS_OMP_COMPAT=${LAMMPS_OMP_COMPAT_LEVEL}) target_link_libraries(lammps PRIVATE OpenMP::OpenMP_CXX) target_link_libraries(lmp PRIVATE OpenMP::OpenMP_CXX) endif() if(PKG_MSCG OR PKG_ATC OR PKG_AWPMD OR PKG_ML-QUIP OR PKG_LATTE OR PKG_ELECTRODE) enable_language(C) find_package(LAPACK) find_package(BLAS) if(NOT LAPACK_FOUND OR NOT BLAS_FOUND) include(CheckGeneratorSupport) if(NOT CMAKE_GENERATOR_SUPPORT_FORTRAN) status(FATAL_ERROR "Cannot build internal linear algebra library as CMake build tool lacks Fortran support") endif() enable_language(Fortran) file(GLOB LAPACK_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/linalg/[^.]*.[fF]) add_library(linalg STATIC ${LAPACK_SOURCES}) set_target_properties(linalg PROPERTIES OUTPUT_NAME lammps_linalg${LAMMPS_MACHINE}) set(BLAS_LIBRARIES "$") set(LAPACK_LIBRARIES "$") else() list(APPEND LAPACK_LIBRARIES ${BLAS_LIBRARIES}) endif() endif() # tweak jpeg library names to avoid linker errors with MinGW cross-compilation set(JPEG_NAMES libjpeg libjpeg-62) find_package(JPEG QUIET) option(WITH_JPEG "Enable JPEG support" ${JPEG_FOUND}) if(WITH_JPEG) find_package(JPEG REQUIRED) target_compile_definitions(lammps PRIVATE -DLAMMPS_JPEG) if(CMAKE_VERSION VERSION_LESS 3.12) target_include_directories(lammps PRIVATE ${JPEG_INCLUDE_DIRS}) target_link_libraries(lammps PRIVATE ${JPEG_LIBRARIES}) else() target_link_libraries(lammps PRIVATE JPEG::JPEG) endif() endif() find_package(PNG QUIET) find_package(ZLIB QUIET) if(PNG_FOUND AND ZLIB_FOUND) option(WITH_PNG "Enable PNG support" ON) else() option(WITH_PNG "Enable PNG support" OFF) endif() if(WITH_PNG) find_package(PNG REQUIRED) find_package(ZLIB REQUIRED) target_link_libraries(lammps PRIVATE PNG::PNG ZLIB::ZLIB) target_compile_definitions(lammps PRIVATE -DLAMMPS_PNG) endif() find_program(GZIP_EXECUTABLE gzip) find_package_handle_standard_args(GZIP REQUIRED_VARS GZIP_EXECUTABLE) option(WITH_GZIP "Enable GZIP support" ${GZIP_FOUND}) if(WITH_GZIP) if(GZIP_FOUND OR ((CMAKE_SYSTEM_NAME STREQUAL "Windows") AND CMAKE_CROSSCOMPILING)) target_compile_definitions(lammps PRIVATE -DLAMMPS_GZIP) else() message(FATAL_ERROR "gzip executable not found") endif() endif() find_program(FFMPEG_EXECUTABLE ffmpeg) find_package_handle_standard_args(FFMPEG REQUIRED_VARS FFMPEG_EXECUTABLE) option(WITH_FFMPEG "Enable FFMPEG support" ${FFMPEG_FOUND}) if(WITH_FFMPEG) if(FFMPEG_FOUND OR ((CMAKE_SYSTEM_NAME STREQUAL "Windows") AND CMAKE_CROSSCOMPILING)) target_compile_definitions(lammps PRIVATE -DLAMMPS_FFMPEG) else() message(FATAL_ERROR "ffmpeg executable not found") endif() endif() if(BUILD_SHARED_LIBS) set(CONFIGURE_REQUEST_PIC "--with-pic") set(CMAKE_REQUEST_PIC "-DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE}") set(CUDA_REQUEST_PIC "-Xcompiler ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") else() set(CONFIGURE_REQUEST_PIC) set(CMAKE_REQUEST_PIC) set(CUDA_REQUEST_PIC) endif() foreach(PKG_WITH_INCL KSPACE PYTHON ML-IAP VORONOI COLVARS ML-HDNNP MDI MOLFILE NETCDF PLUMED QMMM ML-QUIP SCAFACOS MACHDYN VTK KIM LATTE MSCG COMPRESS ML-PACE) if(PKG_${PKG_WITH_INCL}) include(Packages/${PKG_WITH_INCL}) endif() endforeach() # optionally enable building script wrappers using swig option(WITH_SWIG "Build scripting language wrappers with SWIG" OFF) if(WITH_SWIG) get_filename_component(LAMMPS_SWIG_DIR ${LAMMPS_SOURCE_DIR}/../tools/swig ABSOLUTE) add_subdirectory(${LAMMPS_SWIG_DIR} swig) endif() set(CMAKE_TUNE_FLAGS "${CMAKE_TUNE_DEFAULT}" CACHE STRING "Compiler and machine specific optimization flags (compilation only)") separate_arguments(CMAKE_TUNE_FLAGS) foreach(_FLAG ${CMAKE_TUNE_FLAGS}) target_compile_options(lammps PRIVATE ${_FLAG}) target_compile_options(lmp PRIVATE ${_FLAG}) endforeach() ######################################################################## # Basic system tests (standard libraries, headers, functions, types) # ######################################################################## foreach(HEADER cmath) check_include_file_cxx(${HEADER} FOUND_${HEADER}) if(NOT FOUND_${HEADER}) message(FATAL_ERROR "Could not find needed header - ${HEADER}") endif(NOT FOUND_${HEADER}) endforeach(HEADER) # make the standard math library overrideable and autodetected (for systems that don't have it) find_library(STANDARD_MATH_LIB m DOC "Standard Math library") mark_as_advanced(STANDARD_MATH_LIB) if(STANDARD_MATH_LIB) target_link_libraries(lammps PRIVATE ${STANDARD_MATH_LIB}) endif() ###################################### # Generate Basic Style files ###################################### include(StyleHeaderUtils) RegisterStyles(${LAMMPS_SOURCE_DIR}) ######################################################## # Fetch missing external files and archives for packages ######################################################## foreach(PKG ${STANDARD_PACKAGES} ${SUFFIX_PACKAGES}) if(PKG_${PKG}) FetchPotentials(${LAMMPS_SOURCE_DIR}/${PKG} ${LAMMPS_POTENTIALS_DIR}) endif() endforeach() ############################################## # add sources of enabled packages ############################################ foreach(PKG ${STANDARD_PACKAGES}) set(${PKG}_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/${PKG}) file(GLOB ${PKG}_SOURCES ${${PKG}_SOURCES_DIR}/[^.]*.cpp) file(GLOB ${PKG}_HEADERS ${${PKG}_SOURCES_DIR}/[^.]*.h) # check for package files in src directory due to old make system DetectBuildSystemConflict(${LAMMPS_SOURCE_DIR} ${${PKG}_SOURCES} ${${PKG}_HEADERS}) if(PKG_${PKG}) # detects styles in package and adds them to global list RegisterStyles(${${PKG}_SOURCES_DIR}) target_sources(lammps PRIVATE ${${PKG}_SOURCES}) target_include_directories(lammps PRIVATE ${${PKG}_SOURCES_DIR}) endif() RegisterPackages(${${PKG}_SOURCES_DIR}) endforeach() # packages that need defines set foreach(PKG MPIIO) if(PKG_${PKG}) target_compile_definitions(lammps PRIVATE -DLMP_${PKG}) endif() endforeach() # dedicated check for entire contents of accelerator packages foreach(PKG ${SUFFIX_PACKAGES}) set(${PKG}_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/${PKG}) file(GLOB ${PKG}_SOURCES ${${PKG}_SOURCES_DIR}/[^.]*.cpp) file(GLOB ${PKG}_HEADERS ${${PKG}_SOURCES_DIR}/[^.]*.h) # check for package files in src directory due to old make system DetectBuildSystemConflict(${LAMMPS_SOURCE_DIR} ${${PKG}_SOURCES} ${${PKG}_HEADERS}) RegisterPackages(${${PKG}_SOURCES_DIR}) endforeach() ############################################## # add lib sources of (simple) enabled packages ############################################ foreach(PKG_LIB POEMS ATC AWPMD H5MD MESONT) if(PKG_${PKG_LIB}) string(TOLOWER "${PKG_LIB}" PKG_LIB) if(PKG_LIB STREQUAL "mesont") enable_language(Fortran) file(GLOB_RECURSE ${PKG_LIB}_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/${PKG_LIB}/[^.]*.f90) else() file(GLOB_RECURSE ${PKG_LIB}_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/${PKG_LIB}/[^.]*.c ${LAMMPS_LIB_SOURCE_DIR}/${PKG_LIB}/[^.]*.cpp) endif() add_library(${PKG_LIB} STATIC ${${PKG_LIB}_SOURCES}) set_target_properties(${PKG_LIB} PROPERTIES OUTPUT_NAME lammps_${PKG_LIB}${LAMMPS_MACHINE}) target_link_libraries(lammps PRIVATE ${PKG_LIB}) if(PKG_LIB STREQUAL "awpmd") target_include_directories(awpmd PUBLIC ${LAMMPS_LIB_SOURCE_DIR}/awpmd/systems/interact ${LAMMPS_LIB_SOURCE_DIR}/awpmd/ivutils/include) elseif(PKG_LIB STREQUAL "h5md") target_include_directories(h5md PUBLIC ${LAMMPS_LIB_SOURCE_DIR}/h5md/include ${HDF5_INCLUDE_DIRS}) else() target_include_directories(${PKG_LIB} PUBLIC ${LAMMPS_LIB_SOURCE_DIR}/${PKG_LIB}) endif() endif() endforeach() if(PKG_ELECTRODE) target_link_libraries(lammps PRIVATE ${LAPACK_LIBRARIES}) endif() if(PKG_AWPMD) target_link_libraries(awpmd PRIVATE ${LAPACK_LIBRARIES}) endif() if(PKG_ATC) if(LAMMPS_SIZES STREQUAL "BIGBIG") message(FATAL_ERROR "The ATC Package is not compatible with -DLAMMPS_BIGBIG") endif() if(BUILD_MPI) target_link_libraries(atc PRIVATE ${LAPACK_LIBRARIES} MPI::MPI_CXX) else() target_link_libraries(atc PRIVATE ${LAPACK_LIBRARIES} mpi_stubs) endif() target_include_directories(atc PRIVATE ${LAMMPS_SOURCE_DIR}) target_compile_definitions(atc PRIVATE -DLAMMPS_${LAMMPS_SIZES}) endif() if(PKG_H5MD) include(Packages/H5MD) endif() ###################################################################### # packages which selectively include variants based on enabled styles # e.g. accelerator packages ###################################################################### foreach(PKG_WITH_INCL CORESHELL DPD-SMOOTH PHONON QEQ OPENMP KOKKOS OPT INTEL GPU) if(PKG_${PKG_WITH_INCL}) include(Packages/${PKG_WITH_INCL}) endif() endforeach() if(PKG_PLUGIN) target_compile_definitions(lammps PRIVATE -DLMP_PLUGIN) endif() # link with -ldl or equivalent for plugin loading; except on Windows if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows") target_link_libraries(lammps PRIVATE ${CMAKE_DL_LIBS}) endif() ###################################################################### # the windows version of LAMMPS requires a couple extra libraries # and the MPI library - if use - has to be linked right before those # and after everything else that is compiled locally ###################################################################### if(CMAKE_SYSTEM_NAME STREQUAL "Windows") target_link_libraries(lammps PRIVATE "wsock32;psapi") endif() ###################################################### # Generate style headers based on global list of # styles registered during package selection # Generate packages headers from all packages ###################################################### set(LAMMPS_STYLE_HEADERS_DIR ${CMAKE_CURRENT_BINARY_DIR}/styles) GenerateStyleHeaders(${LAMMPS_STYLE_HEADERS_DIR}) GeneratePackagesHeaders(${LAMMPS_STYLE_HEADERS_DIR}) target_include_directories(lammps PRIVATE ${LAMMPS_STYLE_HEADERS_DIR}) ###################################### # Generate lmpinstalledpkgs.h ###################################### set(temp "#ifndef LMP_INSTALLED_PKGS_H\n#define LMP_INSTALLED_PKGS_H\n") set(temp "${temp}const char * LAMMPS_NS::LAMMPS::installed_packages[] = {\n") set(temp_PKG_LIST ${STANDARD_PACKAGES} ${SUFFIX_PACKAGES}) list(SORT temp_PKG_LIST) foreach(PKG ${temp_PKG_LIST}) if(PKG_${PKG}) set(temp "${temp} \"${PKG}\",\n") endif() endforeach() set(temp "${temp} NULL\n};\n#endif\n\n") message(STATUS "Generating lmpinstalledpkgs.h...") file(WRITE "${LAMMPS_STYLE_HEADERS_DIR}/lmpinstalledpkgs.h.tmp" "${temp}" ) execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${LAMMPS_STYLE_HEADERS_DIR}/lmpinstalledpkgs.h.tmp" "${LAMMPS_STYLE_HEADERS_DIR}/lmpinstalledpkgs.h") ###################################### # Generate lmpgitversion.h ###################################### add_custom_target(gitversion COMMAND ${CMAKE_COMMAND} -DLAMMPS_DIR="${LAMMPS_DIR}" -DGIT_EXECUTABLE="${GIT_EXECUTABLE}" -DGIT_FOUND="${GIT_FOUND}" -DLAMMPS_STYLE_HEADERS_DIR="${LAMMPS_STYLE_HEADERS_DIR}" -P ${CMAKE_CURRENT_SOURCE_DIR}/Modules/generate_lmpgitversion.cmake) set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${LAMMPS_STYLE_HEADERS_DIR}/gitversion.h) add_dependencies(lammps gitversion) ########################################### # Actually add executable and lib to build ############################################ get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) list(FIND LANGUAGES "Fortran" _index) if(_index GREATER -1) target_link_libraries(lammps PRIVATE ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES}) endif() set(LAMMPS_CXX_HEADERS angle.h atom.h bond.h citeme.h comm.h compute.h dihedral.h domain.h error.h fix.h force.h group.h improper.h input.h info.h kspace.h lammps.h lattice.h library.h lmppython.h lmptype.h memory.h modify.h neighbor.h neigh_list.h output.h pair.h pointers.h region.h timer.h universe.h update.h utils.h variable.h) if(LAMMPS_EXCEPTIONS) list(APPEND LAMMPS_CXX_HEADERS exceptions.h) endif() set_target_properties(lammps PROPERTIES OUTPUT_NAME lammps${LAMMPS_MACHINE}) set_target_properties(lammps PROPERTIES SOVERSION ${SOVERSION}) set_target_properties(lammps PROPERTIES PREFIX "lib") target_include_directories(lammps PUBLIC $) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/includes/lammps) foreach(_HEADER ${LAMMPS_CXX_HEADERS}) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/includes/lammps/${_HEADER} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${LAMMPS_SOURCE_DIR}/${_HEADER} ${CMAKE_CURRENT_BINARY_DIR}/includes/lammps/${_HEADER} DEPENDS ${LAMMPS_SOURCE_DIR}/${_HEADER}) add_custom_target(${_HEADER} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/includes/lammps/${_HEADER}) add_dependencies(lammps ${_HEADER}) if(BUILD_SHARED_LIBS) install(FILES ${LAMMPS_SOURCE_DIR}/${_HEADER} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/lammps) endif() endforeach() target_include_directories(lammps INTERFACE $) add_library(LAMMPS::lammps ALIAS lammps) get_target_property(LAMMPS_DEFINES lammps INTERFACE_COMPILE_DEFINITIONS) set(LAMMPS_API_DEFINES) foreach(_DEF ${LAMMPS_DEFINES}) set(LAMMPS_API_DEFINES "${LAMMPS_API_DEFINES} -D${_DEF}") endforeach() if(BUILD_SHARED_LIBS) install(TARGETS lammps EXPORT LAMMPS_Targets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) if(NOT BUILD_MPI) install(TARGETS mpi_stubs EXPORT LAMMPS_Targets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() configure_file(pkgconfig/liblammps.pc.in ${CMAKE_CURRENT_BINARY_DIR}/liblammps${LAMMPS_MACHINE}.pc @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/liblammps${LAMMPS_MACHINE}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) install(EXPORT LAMMPS_Targets FILE LAMMPS_Targets.cmake NAMESPACE LAMMPS:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/LAMMPS) include(CMakePackageConfigHelpers) configure_file(LAMMPSConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/LAMMPSConfig.cmake @ONLY) write_basic_package_version_file("LAMMPSConfigVersion.cmake" VERSION ${PROJECT_VERSION} COMPATIBILITY ExactVersion) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/LAMMPSConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/LAMMPSConfigVersion.cmake" DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/LAMMPS) endif() install(FILES ${LAMMPS_DOC_DIR}/lammps.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 RENAME ${LAMMPS_BINARY}.1) include(Tools) include(Documentation) ############################################################################### # Install potential and force field files in data directory ############################################################################### set(LAMMPS_INSTALL_DATADIR ${CMAKE_INSTALL_FULL_DATADIR}/lammps) install(DIRECTORY ${LAMMPS_POTENTIALS_DIR} DESTINATION ${LAMMPS_INSTALL_DATADIR}) if(BUILD_TOOLS) install(DIRECTORY ${LAMMPS_TOOLS_DIR}/msi2lmp/frc_files DESTINATION ${LAMMPS_INSTALL_DATADIR}) endif() configure_file(etc/profile.d/lammps.sh.in ${CMAKE_BINARY_DIR}/etc/profile.d/lammps.sh @ONLY) configure_file(etc/profile.d/lammps.csh.in ${CMAKE_BINARY_DIR}/etc/profile.d/lammps.csh @ONLY) install( FILES ${CMAKE_BINARY_DIR}/etc/profile.d/lammps.sh ${CMAKE_BINARY_DIR}/etc/profile.d/lammps.csh DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/profile.d ) ############################################################################### # Install LAMMPS lib and python module into site-packages folder with # "install-python" target. Behaves exactly like "make install-python" for # conventional build. Only available, if a shared library is built. # This is primarily for people that only want to use the Python wrapper. ############################################################################### if(BUILD_SHARED_LIBS) if(CMAKE_VERSION VERSION_LESS 3.12) # adjust so we find Python 3 versions before Python 2 on old systems with old CMake set(Python_ADDITIONAL_VERSIONS 3.12 3.11 3.10 3.9 3.8 3.7 3.6) find_package(PythonInterp) # Deprecated since version 3.12 if(PYTHONINTERP_FOUND) set(Python_EXECUTABLE ${PYTHON_EXECUTABLE}) endif() else() find_package(Python COMPONENTS Interpreter) endif() if(BUILD_IS_MULTI_CONFIG) set(LIBLAMMPS_SHARED_BINARY ${CMAKE_BINARY_DIR}/$/liblammps${LAMMPS_MACHINE}${CMAKE_SHARED_LIBRARY_SUFFIX}) else() set(LIBLAMMPS_SHARED_BINARY ${CMAKE_BINARY_DIR}/liblammps${LAMMPS_MACHINE}${CMAKE_SHARED_LIBRARY_SUFFIX}) endif() if(Python_EXECUTABLE) add_custom_target( install-python ${CMAKE_COMMAND} -E remove_directory build COMMAND ${Python_EXECUTABLE} ${LAMMPS_PYTHON_DIR}/install.py -p ${LAMMPS_PYTHON_DIR}/lammps -l ${LIBLAMMPS_SHARED_BINARY} COMMENT "Installing LAMMPS Python module") else() add_custom_target( install-python ${CMAKE_COMMAND} -E echo "Must have Python installed to install the LAMMPS Python module") endif() else() add_custom_target( install-python ${CMAKE_COMMAND} -E echo "Must build LAMMPS as a shared library to use the Python module") endif() ############################################################################### # Add LAMMPS python module to "install" target. This is taylored for building # LAMMPS for package managers and with different prefix settings. # This requires either a shared library or that the PYTHON package is included. ############################################################################### if(BUILD_SHARED_LIBS OR PKG_PYTHON) if(CMAKE_VERSION VERSION_LESS 3.12) find_package(PythonInterp) # Deprecated since version 3.12 if(PYTHONINTERP_FOUND) set(Python_EXECUTABLE ${PYTHON_EXECUTABLE}) endif() else() find_package(Python COMPONENTS Interpreter) endif() if(Python_EXECUTABLE) file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/python) install(CODE "execute_process(COMMAND ${Python_EXECUTABLE} setup.py build -b ${CMAKE_BINARY_DIR}/python install --prefix=${CMAKE_INSTALL_PREFIX} --root=\$ENV{DESTDIR}/ WORKING_DIRECTORY ${LAMMPS_PYTHON_DIR})") endif() endif() include(Testing) include(CodeCoverage) include(CodingStandard) find_package(ClangFormat 8.0) if(ClangFormat_FOUND) add_custom_target(format-src COMMAND ${ClangFormat_EXECUTABLE} --verbose -i -style=file *.cpp *.h */*.cpp */*.h WORKING_DIRECTORY ${LAMMPS_SOURCE_DIR}) endif() get_target_property(DEFINES lammps COMPILE_DEFINITIONS) if(BUILD_IS_MULTI_CONFIG) set(LAMMPS_BUILD_TYPE "Multi-Config") else() set(LAMMPS_BUILD_TYPE ${CMAKE_BUILD_TYPE}) endif() include(FeatureSummary) feature_summary(DESCRIPTION "The following tools and libraries have been found and configured:" WHAT PACKAGES_FOUND) message(STATUS "<<< Build configuration >>> LAMMPS Version: ${PROJECT_VERSION} Operating System: ${CMAKE_SYSTEM_NAME} ${CMAKE_LINUX_DISTRO} ${CMAKE_DISTRO_VERSION} Build type: ${LAMMPS_BUILD_TYPE} Install path: ${CMAKE_INSTALL_PREFIX} Generator: ${CMAKE_GENERATOR} using ${CMAKE_MAKE_PROGRAM}") ############################################################################### # Print package summary ############################################################################### set(ENABLED_PACKAGES) foreach(PKG ${STANDARD_PACKAGES} ${SUFFIX_PACKAGES}) if(PKG_${PKG}) list(APPEND ENABLED_PACKAGES ${PKG}) endif() endforeach() if(ENABLED_PACKAGES) list(SORT ENABLED_PACKAGES) else() set(ENABLED_PACKAGES "") endif() message(STATUS "Enabled packages: ${ENABLED_PACKAGES}") message(STATUS "<<< Compilers and Flags: >>> -- C++ Compiler: ${CMAKE_CXX_COMPILER} Type: ${CMAKE_CXX_COMPILER_ID} Version: ${CMAKE_CXX_COMPILER_VERSION} C++ Flags: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BTYPE}} Defines: ${DEFINES}") get_target_property(OPTIONS lammps COMPILE_OPTIONS) if(OPTIONS) message(" Options: ${OPTIONS}") endif() get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) list(FIND LANGUAGES "Fortran" _index) if(_index GREATER -1) message(STATUS "Fortran Compiler: ${CMAKE_Fortran_COMPILER} Type: ${CMAKE_Fortran_COMPILER_ID} Version: ${CMAKE_Fortran_COMPILER_VERSION} Fortran Flags:${CMAKE_Fortran_FLAGS} ${CMAKE_Fortran_FLAGS_${BTYPE}}") endif() list(FIND LANGUAGES "C" _index) if(_index GREATER -1) message(STATUS "C compiler: ${CMAKE_C_COMPILER} Type: ${CMAKE_C_COMPILER_ID} Version: ${CMAKE_C_COMPILER_VERSION} C Flags: ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${BTYPE}}") endif() message(STATUS "<<< Linker flags: >>>") message(STATUS "Executable name: ${LAMMPS_BINARY}") if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.13) get_target_property(OPTIONS lammps LINK_OPTIONS) if(OPTIONS) message(STATUS "Linker options: ${OPTIONS}") endif() endif() if(CMAKE_EXE_LINKER_FLAGS) message(STATUS "Executable linker flags: ${CMAKE_EXE_LINKER_FLAGS}") endif() if(BUILD_SHARED_LIBS) message(STATUS "Shared library flags: ${CMAKE_SHARED_LINKER_FLAGS}") else() message(STATUS "Static library flags: ${CMAKE_STATIC_LINKER_FLAGS}") endif() if(BUILD_MPI) message(STATUS "<<< MPI flags >>> -- MPI_defines: ${MPI_CXX_COMPILE_DEFINITIONS} -- MPI includes: ${MPI_CXX_INCLUDE_PATH} -- MPI libraries: ${MPI_CXX_LIBRARIES};${MPI_Fortran_LIBRARIES}") endif() if(PKG_GPU) message(STATUS "<<< GPU package settings >>> -- GPU API: ${GPU_API}") if(GPU_API STREQUAL "CUDA") message(STATUS "CUDA Compiler: ${CUDA_NVCC_EXECUTABLE}") message(STATUS "GPU default architecture: ${GPU_ARCH}") message(STATUS "GPU binning with CUDPP: ${CUDPP_OPT}") message(STATUS "CUDA MPS support: ${CUDA_MPS_SUPPORT}") elseif(GPU_API STREQUAL "HIP") message(STATUS "HIP platform: ${HIP_PLATFORM}") message(STATUS "HIP architecture: ${HIP_ARCH}") if(HIP_USE_DEVICE_SORT) message(STATUS "HIP GPU sorting: on") else() message(STATUS "HIP GPU sorting: off") endif() endif() message(STATUS "GPU precision: ${GPU_PREC}") endif() if(PKG_KOKKOS) message(STATUS "Kokkos Arch: ${KOKKOS_ARCH}") endif() if(PKG_KSPACE) message(STATUS "<<< FFT settings >>> -- Primary FFT lib: ${FFT}") if(FFT_SINGLE) message(STATUS "Using single precision FFTs") else() message(STATUS "Using double precision FFTs") endif() if(FFT_FFTW_THREADS OR FFT_MKL_THREADS) message(STATUS "Using threaded FFTs") else() message(STATUS "Using non-threaded FFTs") endif() if(PKG_KOKKOS) if(Kokkos_ENABLE_CUDA) if(FFT STREQUAL "KISS") message(STATUS "Kokkos FFT: KISS") else() message(STATUS "Kokkos FFT: cuFFT") endif() elseif(Kokkos_ENABLE_HIP) if(FFT STREQUAL "KISS") message(STATUS "Kokkos FFT: KISS") else() message(STATUS "Kokkos FFT: hipFFT") endif() else() message(STATUS "Kokkos FFT: ${FFT}") endif() endif() endif() if(BUILD_DOC) message(STATUS "<<< Building HTML Manual >>>") endif() if(BUILD_TOOLS) message(STATUS "<<< Building Tools >>>") endif() if(BUILD_LAMMPS_SHELL) message(STATUS "<<< Building LAMMPS Shell >>>") endif() if(ENABLE_TESTING) message(STATUS "<<< Building Unit Tests >>>") if(ENABLE_COVERAGE) message(STATUS "Collecting code coverage data") endif() endif()