######################################## # 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() ######################################## project(lammps CXX) set(SOVERSION 0) get_filename_component(LAMMPS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/.. ABSOLUTE) get_filename_component(LAMMPS_LIB_BINARY_DIR ${CMAKE_BINARY_DIR}/lib ABSOLUTE) 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) 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) set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/.local" CACHE PATH "default install path" FORCE ) 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(CheckCCompilerFlag) include(CheckIncludeFileCXX) # set required compiler flags and compiler/CPU arch specific optimizations if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel") 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() if(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") set(CMAKE_TUNE_DEFAULT "-march=native") endif() if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") set(CMAKE_TUNE_DEFAULT "-march=native") endif() # we require C++11 without extensions set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # GNU compiler specific features for testing if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") option(ENABLE_COVERAGE "Enable collecting code coverage data" OFF) mark_as_advanced(ENABLE_COVERAGE) if(ENABLE_COVERAGE) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") endif() 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) if(BUILD_SHARED_LIBS) # for all pkg libs, mpi_stubs and linalg set(CMAKE_POSITION_INDEPENDENT_CODE ON) endif() option(BUILD_TOOLS "Build and install LAMMPS tools (msi2lmp, binary2txt, chain)" OFF) 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}) 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 ASPHERE BODY CLASS2 COLLOID COMPRESS DIPOLE GRANULAR KSPACE LATTE MANYBODY MC MESSAGE MISC MOLECULE PERI POEMS QEQ REPLICA RIGID SHOCK SPIN SNAP SRD KIM PYTHON MSCG MPIIO VORONOI USER-ATC USER-AWPMD USER-BOCS USER-CGDNA USER-MESODPD USER-CGSDK USER-COLVARS USER-DIFFRACTION USER-DPD USER-DRUDE USER-EFF USER-FEP USER-H5MD USER-LB USER-MANIFOLD USER-MEAMC USER-MGPT USER-MISC USER-MOFFF USER-MOLFILE USER-NETCDF USER-PHONON USER-PLUMED USER-PTM USER-QTB USER-REACTION USER-REAXC USER-SCAFACOS USER-SDPD USER-SMD USER-SMTBQ USER-SPH USER-TALLY USER-UEF USER-VTK USER-QUIP USER-QMMM USER-YAFF USER-ADIOS) set(SUFFIX_PACKAGES CORESHELL USER-OMP KOKKOS OPT USER-INTEL GPU) 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_USER-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) set(MPI_CXX_SKIP_MPICXX TRUE) find_package(MPI QUIET) option(BUILD_MPI "Build MPI version" ${MPI_FOUND}) else() option(BUILD_MPI "Build MPI version" OFF) endif() if(BUILD_MPI) # We use a non-standard procedure to cross-compile with MPI on Windows if((CMAKE_SYSTEM_NAME STREQUAL Windows) AND CMAKE_CROSSCOMPILING) include(MPI4WIN) target_link_libraries(lammps PUBLIC MPI::MPI_CXX) else() find_package(MPI REQUIRED) target_link_libraries(lammps PUBLIC MPI::MPI_CXX) 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() else() enable_language(C) file(GLOB MPI_SOURCES ${LAMMPS_SOURCE_DIR}/STUBS/mpi.c) add_library(mpi_stubs STATIC ${MPI_SOURCES}) set_target_properties(mpi_stubs PROPERTIES OUTPUT_NAME lammps_mpi_stubs${LAMMPS_MACHINE}) target_include_directories(mpi_stubs PUBLIC $ $) install(FILES ${LAMMPS_SOURCE_DIR}/STUBS/mpi.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/lammps/mpi) if(BUILD_SHARED_LIBS) target_link_libraries(lammps PRIVATE mpi_stubs) target_include_directories(lammps INTERFACE $ $) else() target_link_libraries(lammps PUBLIC mpi_stubs) endif() add_library(MPI::MPI_CXX ALIAS 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 if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") 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)" OFF) 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(MPIIO MPI) pkg_depends(USER-ATC MANYBODY) pkg_depends(USER-LB MPI) pkg_depends(USER-PHONON KSPACE) pkg_depends(USER-SCAFACOS MPI) # 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 8.99.9)) OR ((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 9.99.9)) OR ((CMAKE_CXX_COMPILER_ID STREQUAL "Intel") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 18.99.9)) ) # 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. target_compile_definitions(lammps PRIVATE -DLAMMPS_OMP_COMPAT=4) else() target_compile_definitions(lammps PRIVATE -DLAMMPS_OMP_COMPAT=3) endif() target_link_libraries(lammps PRIVATE OpenMP::OpenMP_CXX) endif() if(PKG_MSCG OR PKG_USER-ATC OR PKG_USER-AWPMD OR PKG_USER-QUIP OR PKG_LATTE) 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() 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_DIR}) 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(NOT GZIP_FOUND) message(FATAL_ERROR "gzip executable not found") endif() target_compile_definitions(lammps PRIVATE -DLAMMPS_GZIP) 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(NOT FFMPEG_FOUND) message(FATAL_ERROR "ffmpeg executable not found") endif() target_compile_definitions(lammps PRIVATE -DLAMMPS_FFMPEG) 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 VORONOI USER-COLVARS USER-MOLFILE USER-NETCDF USER-PLUMED USER-QMMM USER-QUIP USER-SCAFACOS USER-SMD USER-VTK KIM LATTE MESSAGE MSCG COMPRESS) if(PKG_${PKG_WITH_INCL}) include(Packages/${PKG_WITH_INCL}) endif() endforeach() set(CMAKE_TUNE_FLAGS "${CMAKE_TUNE_DEFAULT}" CACHE STRING "Compiler specific optimization or instrumentation") separate_arguments(CMAKE_TUNE_FLAGS) include(CheckCXXCompilerFlag) foreach(_FLAG ${CMAKE_TUNE_FLAGS}) string(REGEX REPLACE "[=\"]" "" _FLAGX ${_FLAG}) check_cxx_compiler_flag("${_FLAG}" COMPILER_SUPPORTS${_FLAGX}) if(COMPILER_SUPPORTS${_FLAGX}) target_compile_options(lammps PRIVATE ${_FLAG}) else() message(WARNING "${_FLAG} found in CMAKE_TUNE_FLAGS, but not supported by the compiler, skipping") endif() 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) set(MATH_LIBRARIES "m" CACHE STRING "math library") mark_as_advanced( MATH_LIBRARIES ) target_link_libraries(lammps PRIVATE ${MATH_LIBRARIES}) ###################################### # Generate Basic Style files ###################################### include(StyleHeaderUtils) RegisterStyles(${LAMMPS_SOURCE_DIR}) ############################################## # 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(SIMPLE_LIB POEMS USER-ATC USER-AWPMD USER-H5MD) if(PKG_${SIMPLE_LIB}) string(REGEX REPLACE "^USER-" "" PKG_LIB "${SIMPLE_LIB}") string(TOLOWER "${PKG_LIB}" PKG_LIB) file(GLOB_RECURSE ${PKG_LIB}_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/${PKG_LIB}/[^.]*.c ${LAMMPS_LIB_SOURCE_DIR}/${PKG_LIB}/[^.]*.cpp) 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_USER-AWPMD) target_link_libraries(awpmd PRIVATE ${LAPACK_LIBRARIES}) endif() if(PKG_USER-ATC) if(LAMMPS_SIZES STREQUAL BIGBIG) message(FATAL_ERROR "The USER-ATC Package is not compatible with -DLAMMPS_BIGBIG") endif() target_link_libraries(atc PRIVATE ${LAPACK_LIBRARIES}) if(BUILD_MPI) target_link_libraries(atc PRIVATE MPI::MPI_CXX) else() target_link_libraries(atc PRIVATE mpi_stubs) endif() target_include_directories(atc PRIVATE ${LAMMPS_SOURCE_DIR}) target_compile_definitions(atc PRIVATE -DLAMMPS_${LAMMPS_SIZES}) endif() if(PKG_USER-H5MD) include(Packages/USER-H5MD) endif() ###################################################################### # packages which selectively include variants based on enabled styles # e.g. accelerator packages ###################################################################### foreach(PKG_WITH_INCL CORESHELL QEQ USER-OMP USER-SDPD KOKKOS OPT USER-INTEL GPU) if(PKG_${PKG_WITH_INCL}) include(Packages/${PKG_WITH_INCL}) endif() endforeach() ###################################################################### # 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 -lwsock32 -lpsapi) 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 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}) 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}) 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) if(BUILD_TOOLS) add_executable(binary2txt ${LAMMPS_TOOLS_DIR}/binary2txt.cpp) target_compile_definitions(binary2txt PRIVATE -DLAMMPS_${LAMMPS_SIZES}) install(TARGETS binary2txt DESTINATION ${CMAKE_INSTALL_BINDIR}) include(CheckGeneratorSupport) if(CMAKE_GENERATOR_SUPPORT_FORTRAN) include(CheckLanguage) check_language(Fortran) if(CMAKE_Fortran_COMPILER) enable_language(Fortran) add_executable(chain.x ${LAMMPS_TOOLS_DIR}/chain.f) target_link_libraries(chain.x PRIVATE ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES}) install(TARGETS chain.x DESTINATION ${CMAKE_INSTALL_BINDIR}) else() message(WARNING "No suitable Fortran compiler found, skipping building 'chain.x'") endif() else() message(WARNING "CMake build doesn't support fortran, skipping building 'chain.x'") endif() enable_language(C) get_filename_component(MSI2LMP_SOURCE_DIR ${LAMMPS_TOOLS_DIR}/msi2lmp/src ABSOLUTE) file(GLOB MSI2LMP_SOURCES ${MSI2LMP_SOURCE_DIR}/[^.]*.c) add_executable(msi2lmp ${MSI2LMP_SOURCES}) target_link_libraries(msi2lmp PRIVATE ${MATH_LIBRARIES}) install(TARGETS msi2lmp DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES ${LAMMPS_DOC_DIR}/msi2lmp.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) endif() 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) 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) add_custom_target( install-python ${Python_EXECUTABLE} install.py -v ${LAMMPS_SOURCE_DIR}/version.h -m ${LAMMPS_PYTHON_DIR}/lammps.py -l ${CMAKE_BINARY_DIR}/liblammps${CMAKE_SHARED_LIBRARY_SUFFIX} WORKING_DIRECTORY ${LAMMPS_PYTHON_DIR} 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) execute_process(COMMAND ${Python_EXECUTABLE} -c "import distutils.sysconfig as cg; print(cg.get_python_lib(1,0,prefix='${CMAKE_INSTALL_PREFIX}'))" OUTPUT_VARIABLE PYTHON_DEFAULT_INSTDIR OUTPUT_STRIP_TRAILING_WHITESPACE) set(PYTHON_INSTDIR ${PYTHON_DEFAULT_INSTDIR} CACHE PATH "Installation folder for LAMMPS Python module") install(FILES ${LAMMPS_PYTHON_DIR}/lammps.py DESTINATION ${PYTHON_INSTDIR}) endif() endif() include(Testing) include(CodeCoverage) ############################################################################### # Print package summary ############################################################################### foreach(PKG ${STANDARD_PACKAGES} ${SUFFIX_PACKAGES}) if(PKG_${PKG}) message(STATUS "Building package: ${PKG}") endif() endforeach() get_target_property(DEFINES lammps COMPILE_DEFINITIONS) include(FeatureSummary) feature_summary(DESCRIPTION "The following tools and libraries have been found and configured:" WHAT PACKAGES_FOUND) message(STATUS "<<< Build configuration >>> Build type: ${CMAKE_BUILD_TYPE} Install path: ${CMAKE_INSTALL_PREFIX} Generator: ${CMAKE_GENERATOR} using ${CMAKE_MAKE_PROGRAM} -- <<< 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_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 "GPU architecture: ${GPU_ARCH}") elseif(GPU_API STREQUAL "OPENCL") message(STATUS "OpenCL tuning: ${OCL_TUNE}") 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() else() message(STATUS "Kokkos FFT: ${FFT}") endif() endif() endif()