From ca74dbb1de5acb59286a5f3e70469c6d3aa2fc66 Mon Sep 17 00:00:00 2001 From: James Kermode Date: Thu, 29 Jan 2026 15:31:29 +0000 Subject: [PATCH 1/2] Add CMake build support for find_package(QUIP) (#711) Enable LAMMPS and other CMake projects to use QUIP libraries via CMake's find_package() mechanism. Changes: - Add cmake/QUIPConfig.cmake.in template that creates imported targets (QUIP::fox, QUIP::libAtoms, QUIP::GAP, QUIP::Potentials, QUIP::Utils, QUIP::QUIP) for CMake consumers - Use Meson's cmake module to generate QUIPConfig.cmake and QUIPConfigVersion.cmake during installation - Add install: true to all library definitions so they are installed to the lib directory - Update fox and GAP submodules to include install: true After installation, CMake projects can use: find_package(QUIP REQUIRED) target_link_libraries(myapp QUIP::QUIP) Co-Authored-By: Claude Opus 4.5 --- cmake/QUIPConfig.cmake.in | 71 ++++++++++++++++++++++++++++++++++++++ meson.build | 20 +++++++++++ src/GAP | 2 +- src/Potentials/meson.build | 1 + src/Utils/meson.build | 1 + src/fox | 2 +- src/libAtoms/meson.build | 1 + 7 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 cmake/QUIPConfig.cmake.in diff --git a/cmake/QUIPConfig.cmake.in b/cmake/QUIPConfig.cmake.in new file mode 100644 index 000000000..f75cb68a2 --- /dev/null +++ b/cmake/QUIPConfig.cmake.in @@ -0,0 +1,71 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) +find_dependency(BLAS) +find_dependency(LAPACK) + +# Find QUIP libraries +find_library(QUIP_POTENTIALS_LIBRARY NAMES Potentials HINTS "${PACKAGE_PREFIX_DIR}/lib") +find_library(QUIP_LIBATOMS_LIBRARY NAMES libAtoms HINTS "${PACKAGE_PREFIX_DIR}/lib") +find_library(QUIP_FOX_LIBRARY NAMES fox HINTS "${PACKAGE_PREFIX_DIR}/lib") +find_library(QUIP_UTILS_LIBRARY NAMES Utils HINTS "${PACKAGE_PREFIX_DIR}/lib") + +# GAP is optional +set(QUIP_HAS_GAP @QUIP_HAS_GAP@) +if(QUIP_HAS_GAP) + find_library(QUIP_GAP_LIBRARY NAMES GAP HINTS "${PACKAGE_PREFIX_DIR}/lib") +endif() + +# Create imported targets +if(QUIP_FOX_LIBRARY) + add_library(QUIP::fox SHARED IMPORTED) + set_target_properties(QUIP::fox PROPERTIES IMPORTED_LOCATION "${QUIP_FOX_LIBRARY}") +endif() + +if(QUIP_LIBATOMS_LIBRARY) + add_library(QUIP::libAtoms SHARED IMPORTED) + set_target_properties(QUIP::libAtoms PROPERTIES + IMPORTED_LOCATION "${QUIP_LIBATOMS_LIBRARY}" + INTERFACE_LINK_LIBRARIES "QUIP::fox;${BLAS_LIBRARIES};${LAPACK_LIBRARIES}") +endif() + +if(QUIP_HAS_GAP AND QUIP_GAP_LIBRARY) + add_library(QUIP::GAP SHARED IMPORTED) + set_target_properties(QUIP::GAP PROPERTIES + IMPORTED_LOCATION "${QUIP_GAP_LIBRARY}" + INTERFACE_LINK_LIBRARIES "QUIP::libAtoms") +endif() + +if(QUIP_POTENTIALS_LIBRARY) + add_library(QUIP::Potentials SHARED IMPORTED) + set_target_properties(QUIP::Potentials PROPERTIES + IMPORTED_LOCATION "${QUIP_POTENTIALS_LIBRARY}") + if(QUIP_HAS_GAP) + set_target_properties(QUIP::Potentials PROPERTIES + INTERFACE_LINK_LIBRARIES "QUIP::GAP;QUIP::libAtoms") + else() + set_target_properties(QUIP::Potentials PROPERTIES + INTERFACE_LINK_LIBRARIES "QUIP::libAtoms") + endif() +endif() + +if(QUIP_UTILS_LIBRARY) + add_library(QUIP::Utils SHARED IMPORTED) + set_target_properties(QUIP::Utils PROPERTIES + IMPORTED_LOCATION "${QUIP_UTILS_LIBRARY}" + INTERFACE_LINK_LIBRARIES "QUIP::Potentials") +endif() + +# Unified target for convenience +add_library(QUIP::QUIP INTERFACE IMPORTED) +if(QUIP_HAS_GAP) + set_target_properties(QUIP::QUIP PROPERTIES + INTERFACE_LINK_LIBRARIES "QUIP::Utils;QUIP::Potentials;QUIP::GAP;QUIP::libAtoms;QUIP::fox") +else() + set_target_properties(QUIP::QUIP PROPERTIES + INTERFACE_LINK_LIBRARIES "QUIP::Utils;QUIP::Potentials;QUIP::libAtoms;QUIP::fox") +endif() + +set(QUIP_FOUND TRUE) +set(QUIP_LIBRARIES QUIP::QUIP) +set(QUIP_VERSION @QUIP_VERSION@) diff --git a/meson.build b/meson.build index f6aa346a9..b73b35b93 100644 --- a/meson.build +++ b/meson.build @@ -108,3 +108,23 @@ endif subdir('src') +# CMake package config generation for find_package(QUIP) support +cmake = import('cmake') + +cmake_conf = configuration_data() +cmake_conf.set('QUIP_VERSION', meson.project_version()) +cmake_conf.set('QUIP_HAS_GAP', get_option('gap') ? 'TRUE' : 'FALSE') + +cmake.write_basic_package_version_file( + name: 'QUIP', + version: meson.project_version(), + compatibility: 'SameMajorVersion', + install_dir: get_option('libdir') / 'cmake' / 'QUIP' +) + +cmake.configure_package_config_file( + name: 'QUIP', + input: 'cmake/QUIPConfig.cmake.in', + configuration: cmake_conf, + install_dir: get_option('libdir') / 'cmake' / 'QUIP' +) diff --git a/src/GAP b/src/GAP index cefcbc005..480fc2d1c 160000 --- a/src/GAP +++ b/src/GAP @@ -1 +1 @@ -Subproject commit cefcbc005e955ab4e6795f5cf349ee754e527f25 +Subproject commit 480fc2d1c851d69eaa7932832f0c48c306bb5b93 diff --git a/src/Potentials/meson.build b/src/Potentials/meson.build index 7ca2e447b..c7a45b08b 100644 --- a/src/Potentials/meson.build +++ b/src/Potentials/meson.build @@ -95,4 +95,5 @@ Potentials = library('Potentials', ], link_with : [libAtoms,fox,GAP], link_args: openmp_link_args, + install: true, ) diff --git a/src/Utils/meson.build b/src/Utils/meson.build index 8301b196c..afadcf969 100644 --- a/src/Utils/meson.build +++ b/src/Utils/meson.build @@ -18,4 +18,5 @@ Utils = library('Utils', ], link_with : [libAtoms,fox,GAP,Potentials], link_args: openmp_link_args, + install: true, ) diff --git a/src/fox b/src/fox index 84a273a3d..67b28ffe7 160000 --- a/src/fox +++ b/src/fox @@ -1 +1 @@ -Subproject commit 84a273a3d32512d6bb1ee04d05a3a144c341936c +Subproject commit 67b28ffe75d434bfc59aab7db8ec23d02ed195ca diff --git a/src/libAtoms/meson.build b/src/libAtoms/meson.build index 89688136d..86d93d134 100644 --- a/src/libAtoms/meson.build +++ b/src/libAtoms/meson.build @@ -84,4 +84,5 @@ libAtoms = library('libAtoms', c_args: ['-DPROTOTYPES=1'], link_args: libatoms_link_args, override_options: ['b_lundef=false'], # Allow undefined symbols + install: true, ) From d4cc9e6a04858ac72e07924967e16203ccc15bb8 Mon Sep 17 00:00:00 2001 From: James Kermode Date: Thu, 29 Jan 2026 19:25:20 +0000 Subject: [PATCH 2/2] Fix undefined f90wrap_abort_ on Linux by installing stub library The f90wrap_stub library provides the f90wrap_abort implementation needed by libAtoms for non-Python usage. On macOS this wasn't caught because of -Wl,-undefined,dynamic_lookup, but Linux requires all symbols resolved at link time. Changes: - Install libf90wrap_stub.a alongside other libraries - Add QUIP::f90wrap_stub target to CMake config - Link f90wrap_stub into libAtoms interface dependencies Co-Authored-By: Claude Opus 4.5 --- cmake/QUIPConfig.cmake.in | 10 +++++++++- src/libAtoms/meson.build | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/cmake/QUIPConfig.cmake.in b/cmake/QUIPConfig.cmake.in index f75cb68a2..8af70f737 100644 --- a/cmake/QUIPConfig.cmake.in +++ b/cmake/QUIPConfig.cmake.in @@ -9,6 +9,8 @@ find_library(QUIP_POTENTIALS_LIBRARY NAMES Potentials HINTS "${PACKAGE_PREFIX_DI find_library(QUIP_LIBATOMS_LIBRARY NAMES libAtoms HINTS "${PACKAGE_PREFIX_DIR}/lib") find_library(QUIP_FOX_LIBRARY NAMES fox HINTS "${PACKAGE_PREFIX_DIR}/lib") find_library(QUIP_UTILS_LIBRARY NAMES Utils HINTS "${PACKAGE_PREFIX_DIR}/lib") +# f90wrap stub provides f90wrap_abort for non-Python usage +find_library(QUIP_F90WRAP_STUB_LIBRARY NAMES f90wrap_stub HINTS "${PACKAGE_PREFIX_DIR}/lib") # GAP is optional set(QUIP_HAS_GAP @QUIP_HAS_GAP@) @@ -22,11 +24,17 @@ if(QUIP_FOX_LIBRARY) set_target_properties(QUIP::fox PROPERTIES IMPORTED_LOCATION "${QUIP_FOX_LIBRARY}") endif() +# f90wrap stub target (static library providing f90wrap_abort for non-Python usage) +if(QUIP_F90WRAP_STUB_LIBRARY) + add_library(QUIP::f90wrap_stub STATIC IMPORTED) + set_target_properties(QUIP::f90wrap_stub PROPERTIES IMPORTED_LOCATION "${QUIP_F90WRAP_STUB_LIBRARY}") +endif() + if(QUIP_LIBATOMS_LIBRARY) add_library(QUIP::libAtoms SHARED IMPORTED) set_target_properties(QUIP::libAtoms PROPERTIES IMPORTED_LOCATION "${QUIP_LIBATOMS_LIBRARY}" - INTERFACE_LINK_LIBRARIES "QUIP::fox;${BLAS_LIBRARIES};${LAPACK_LIBRARIES}") + INTERFACE_LINK_LIBRARIES "QUIP::f90wrap_stub;QUIP::fox;${BLAS_LIBRARIES};${LAPACK_LIBRARIES}") endif() if(QUIP_HAS_GAP AND QUIP_GAP_LIBRARY) diff --git a/src/libAtoms/meson.build b/src/libAtoms/meson.build index 86d93d134..8f4d8a7ca 100644 --- a/src/libAtoms/meson.build +++ b/src/libAtoms/meson.build @@ -61,9 +61,11 @@ libAtoms_c_sources = [ 'xyz.c', 'sockets.c', ] -# Create static library for f90wrap stub (linked only with standalone programs) +# Create static library for f90wrap stub (linked with standalone programs and external users) +# This provides the f90wrap_abort implementation for non-Python usage f90wrap_stub_lib = static_library('f90wrap_stub', 'f90wrap_stub.F90', + install: true, ) # Platform-specific link args