From ec68859680c78f554764cbf7277543bf3ef93240 Mon Sep 17 00:00:00 2001
From: Matt Whitlock <bitcoin@mattwhitlock.name>
Date: Fri, 16 Aug 2024 19:02:45 -0400
Subject: [PATCH] support linking against system-installed libsecp256k1

---
 CMakeLists.txt     |  5 ++++-
 src/CMakeLists.txt | 49 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 398cba7f97e1b72332442535c868569cbab1c073..d1defd5b8a1380b743107da66b8a754d9e4e2e04 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,7 +7,7 @@
 #
 # Centos Stream 9, https://www.centos.org/cl-vs-cs/#end-of-life, EOL in May 2027:
 #  - CMake 3.26.5, https://mirror.stream.centos.org/9-stream/AppStream/x86_64/os/Packages/
-cmake_minimum_required(VERSION 3.22)
+cmake_minimum_required(VERSION 3.25)
 
 if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
   message(FATAL_ERROR "In-source builds are not allowed.")
@@ -177,6 +177,9 @@ if(WITH_MULTIPROCESS)
   )
 endif()
 
+option(WITH_SYSTEM_LIBSECP256K1 "Link with system-installed libsecp256k1." OFF)
+mark_as_advanced(WITH_SYSTEM_LIBSECP256K1)
+
 cmake_dependent_option(BUILD_GUI_TESTS "Build test_elements-qt executable." ON "BUILD_GUI;BUILD_TESTS" OFF)
 if(BUILD_GUI)
   set(qt_components Core Gui Widgets LinguistTools)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 836eee441d48b2d75063487836c980d3908125d9..6a02063a2ccbbfa72c179e34e1e6c2eaf7f83a25 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -19,16 +19,62 @@ include(../cmake/crc32c.cmake)
 include(../cmake/leveldb.cmake)
 include(../cmake/minisketch.cmake)
 add_subdirectory(univalue)
+
+if(WITH_SYSTEM_LIBSECP256K1)
+
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(libsecp256k1 REQUIRED IMPORTED_TARGET libsecp256k1_zkp)
+add_library(secp256k1 ALIAS PkgConfig::libsecp256k1)
+target_include_directories(core_interface INTERFACE ${libsecp256k1_INCLUDE_DIRS})
+block()
+  string(APPEND CMAKE_REQUIRED_FLAGS " ${libsecp256k1_CFLAGS_OTHER}")
+  list(APPEND CMAKE_REQUIRED_INCLUDES ${libsecp256k1_INCLUDE_DIRS})
+  list(APPEND CMAKE_REQUIRED_LINK_OPTIONS ${libsecp256k1_LDFLAGS})
+  list(APPEND CMAKE_REQUIRED_LIBRARIES ${libsecp256k1_LIBRARIES})
+  unset(missing_modules)
+  include(CheckSymbolExists)
+  macro(check_secp256k1_module module symbol)
+    string(TOUPPER "${symbol}" VAR)
+    set(VAR "libsecp256k1_HAS_${VAR}")
+    unset(${VAR})
+    check_symbol_exists("${symbol}" "secp256k1_${module}.h" ${VAR})
+    if(NOT ${VAR})
+      list(APPEND missing_modules "${module}")
+    endif()
+  endmacro()
+  message(CHECK_START "Checking for required libsecp256k1 modules")
+  list(APPEND CMAKE_MESSAGE_INDENT "  ")
+  check_secp256k1_module(ecdh secp256k1_ecdh)
+  check_secp256k1_module(ellswift secp256k1_ellswift_encode)
+  check_secp256k1_module(extrakeys secp256k1_xonly_pubkey_parse)
+  check_secp256k1_module(generator secp256k1_generator_parse)
+  check_secp256k1_module(rangeproof secp256k1_rangeproof_verify)
+  check_secp256k1_module(recovery secp256k1_ecdsa_recover)
+  check_secp256k1_module(schnorrsig secp256k1_schnorrsig_verify)
+  check_secp256k1_module(surjectionproof secp256k1_surjectionproof_initialize)
+  check_secp256k1_module(whitelist secp256k1_whitelist_verify)
+  list(POP_BACK CMAKE_MESSAGE_INDENT)
+  if(missing_modules)
+    list(JOIN missing_modules ", " missing_modules)
+    message(FATAL_ERROR "System-installed libsecp256k1 lacks these required modules: ${missing_modules}.")
+  endif()
+  message(CHECK_PASS "all were found")
+endblock()
+
+else() # !WITH_SYSTEM_LIBSECP256K1
+
 #=============================
 # secp256k1 subtree
 #=============================
 message("")
 message("Configuring secp256k1 subtree...")
+block()
 set(SECP256K1_ENABLE_MODULE_GENERATOR ON CACHE BOOL "" FORCE)
 set(SECP256K1_ENABLE_MODULE_RANGEPROOF ON CACHE BOOL "" FORCE)
 set(SECP256K1_ENABLE_MODULE_SURJECTION ON CACHE BOOL "" FORCE)
 set(SECP256K1_ENABLE_MODULE_WHITELIST ON CACHE BOOL "" FORCE)
 set(SECP256K1_DISABLE_SHARED ON CACHE BOOL "" FORCE)
+set(BUILD_SHARED_LIBS OFF)
 set(SECP256K1_ENABLE_MODULE_ECDH ON CACHE BOOL "" FORCE)
 set(SECP256K1_ENABLE_MODULE_RECOVERY ON CACHE BOOL "" FORCE)
 set(SECP256K1_ENABLE_MODULE_MUSIG OFF CACHE BOOL "" FORCE)
@@ -71,6 +117,9 @@ set_target_properties(secp256k1 PROPERTIES
   EXCLUDE_FROM_ALL TRUE
 )
 set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+endblock()
+
+endif() # !WITH_SYSTEM_LIBSECP256K1
 
 #=============================
 # Elements simplicity library
-- 
2.55.0

