aboutsummaryrefslogtreecommitdiff
path: root/cmake
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-13 11:46:01 +0000
committer_ov4 <ov4@ov4.org>2026-10-13 11:46:01 +0000
commit17c484d6502a2547e4807b9a5b888497175e5424 (patch)
tree06fdb47edf1935b214ce06e3821dbdb4b954b2b4 /cmake
parentec0ae47dd798e48e2409cbc544e17e2b13f550eb (diff)
build: share local-first dependency lookup across tools and libraries
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat (limited to 'cmake')
-rw-r--r--cmake/BuildTools.cmake43
-rw-r--r--cmake/DependencyPaths.cmake32
-rw-r--r--cmake/ExtractPackages.cmake3
-rw-r--r--cmake/FindDependency.cmake72
-rw-r--r--cmake/GenerateManual.cmake.in21
-rw-r--r--cmake/HomebrewPackages.cmake11
-rw-r--r--cmake/Install.cmake.in12
-rw-r--r--cmake/LLVMDependencies.cmake23
-rw-r--r--cmake/LinuxPackages.cmake3
-rw-r--r--cmake/LocalDependencies.cmake107
-rw-r--r--cmake/Manual.cmake3
-rw-r--r--cmake/Release.cmake2
12 files changed, 198 insertions, 134 deletions
diff --git a/cmake/BuildTools.cmake b/cmake/BuildTools.cmake
new file mode 100644
index 0000000..d6928bb
--- /dev/null
+++ b/cmake/BuildTools.cmake
@@ -0,0 +1,43 @@
+# Resolve tools before project() performs its compiler and generator checks.
+if(CMAKE_GENERATOR MATCHES "Makefiles|Ninja")
+ foreach(language C CXX)
+ if(language STREQUAL "C")
+ set(names clang cc gcc)
+ else()
+ set(names clang++ c++ g++)
+ endif()
+ if(CMAKE_${language}_COMPILER)
+ get_filename_component(requested "${CMAKE_${language}_COMPILER}" NAME)
+ list(INSERT names 0 "${requested}")
+ endif()
+ cpsc_find_dependency(PROGRAM CMAKE_${language}_COMPILER NAMES ${names} REQUIRED)
+ # project() would otherwise restore the previous path from this file.
+ set(compiler_info "${CMAKE_BINARY_DIR}/CMakeFiles/${CMAKE_VERSION}/CMake${language}Compiler.cmake")
+ if(EXISTS "${compiler_info}")
+ file(STRINGS "${compiler_info}" previous
+ REGEX "^set\\(CMAKE_${language}_COMPILER \"")
+ string(REGEX REPLACE "^set\\(CMAKE_${language}_COMPILER \"([^\"]*)\"\\)$"
+ "\\1" previous "${previous}")
+ if(NOT previous STREQUAL CMAKE_${language}_COMPILER)
+ file(REMOVE "${compiler_info}")
+ endif()
+ endif()
+ endforeach()
+endif()
+
+if(CMAKE_GENERATOR MATCHES "Ninja")
+ set(names ninja ninja-build)
+elseif(CMAKE_GENERATOR STREQUAL "MinGW Makefiles")
+ set(names mingw32-make)
+elseif(CMAKE_GENERATOR MATCHES "NMake")
+ set(names nmake)
+elseif(CMAKE_GENERATOR STREQUAL "MSYS Makefiles")
+ set(names make)
+elseif(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
+ set(names gmake make)
+else()
+ set(names)
+endif()
+if(names)
+ cpsc_find_dependency(PROGRAM CMAKE_MAKE_PROGRAM NAMES ${names} REQUIRED)
+endif()
diff --git a/cmake/DependencyPaths.cmake b/cmake/DependencyPaths.cmake
new file mode 100644
index 0000000..d31d5eb
--- /dev/null
+++ b/cmake/DependencyPaths.cmake
@@ -0,0 +1,32 @@
+# Recompute after extraction and after project() learns the library architecture.
+macro(cpsc_dependency_paths build_directory)
+ set(CPSC_LOCAL_PREFIXES "${build_directory}")
+ foreach(prefix "${CPSC_DEPS_ROOT}" "${CPSC_DEPS_ROOT}/usr"
+ "${CPSC_DEPS_ROOT}/mingw64" "${CPSC_DEPS_ROOT}/ucrt64"
+ "${CPSC_DEPS_ROOT}/clang64")
+ if(IS_DIRECTORY "${prefix}")
+ list(APPEND CPSC_LOCAL_PREFIXES "${prefix}")
+ endif()
+ endforeach()
+ file(GLOB llvm_prefixes LIST_DIRECTORIES TRUE "${CPSC_DEPS_ROOT}/usr/lib/llvm-*")
+ file(GLOB brew_prefixes LIST_DIRECTORIES TRUE "${CPSC_DEPS_ROOT}/Cellar/*/*")
+ list(APPEND CPSC_LOCAL_PREFIXES ${llvm_prefixes} ${brew_prefixes})
+
+ set(CPSC_LOCAL_LIBRARY_DIRS)
+ set(CPSC_LOCAL_INCLUDE_DIRS)
+ set(CPSC_LOCAL_BIN_DIRS "${build_directory}")
+ foreach(prefix IN LISTS CPSC_LOCAL_PREFIXES)
+ list(APPEND CPSC_LOCAL_LIBRARY_DIRS "${prefix}/lib")
+ list(APPEND CPSC_LOCAL_INCLUDE_DIRS "${prefix}/include" "${prefix}/include/libxml2")
+ list(APPEND CPSC_LOCAL_BIN_DIRS "${prefix}/bin")
+ endforeach()
+ file(GLOB pandoc_directories LIST_DIRECTORIES TRUE "${CPSC_DEPS_ROOT}/pandoc-*")
+ list(APPEND CPSC_LOCAL_BIN_DIRS ${pandoc_directories})
+ if(CMAKE_LIBRARY_ARCHITECTURE)
+ list(INSERT CPSC_LOCAL_LIBRARY_DIRS 0
+ "${CPSC_DEPS_ROOT}/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}"
+ "${CPSC_DEPS_ROOT}/lib/${CMAKE_LIBRARY_ARCHITECTURE}")
+ list(APPEND CPSC_LOCAL_INCLUDE_DIRS
+ "${CPSC_DEPS_ROOT}/usr/include/${CMAKE_LIBRARY_ARCHITECTURE}")
+ endif()
+endmacro()
diff --git a/cmake/ExtractPackages.cmake b/cmake/ExtractPackages.cmake
index 71a9dea..375c5cd 100644
--- a/cmake/ExtractPackages.cmake
+++ b/cmake/ExtractPackages.cmake
@@ -42,7 +42,7 @@ function(cpsc_extract_packages)
file(SHA256 "${archive}" hash)
string(APPEND signature "${archive}:${hash}\n")
endforeach()
- foreach(module ExtractPackages LinuxPackages WindowsPackages HomebrewPackages)
+ foreach(module ExtractPackages LinuxPackages WindowsPackages HomebrewPackages FindDependency DependencyPaths)
file(SHA256 "${CPSC_DEPS_MODULE_DIR}/${module}.cmake" hash)
string(APPEND signature "${module}:${hash}\n")
endforeach()
@@ -76,6 +76,7 @@ function(cpsc_extract_packages)
cpsc_extract_archive("${archive}" "${CPSC_DEPS_ROOT}")
endif()
endforeach()
+ cpsc_dependency_paths("${CMAKE_BINARY_DIR}")
if(CMAKE_HOST_APPLE)
cpsc_prepare_homebrew_packages()
elseif(CMAKE_HOST_WIN32)
diff --git a/cmake/FindDependency.cmake b/cmake/FindDependency.cmake
new file mode 100644
index 0000000..559bdde
--- /dev/null
+++ b/cmake/FindDependency.cmake
@@ -0,0 +1,72 @@
+# Installation policy belongs in doc/build.md. All lookups use local, then system.
+function(cpsc_find_dependency kind output)
+ cmake_parse_arguments(dependency "REQUIRED" "" "NAMES;PATH_SUFFIXES" ${ARGN})
+ if(kind STREQUAL "PROGRAM")
+ set(directories ${CPSC_LOCAL_BIN_DIRS})
+ set(cache_type FILEPATH)
+ elseif(kind STREQUAL "LIBRARY")
+ set(directories ${CPSC_LOCAL_LIBRARY_DIRS})
+ set(cache_type FILEPATH)
+ elseif(kind STREQUAL "PATH")
+ set(directories ${CPSC_LOCAL_PREFIXES} ${CPSC_LOCAL_INCLUDE_DIRS})
+ set(cache_type PATH)
+ else()
+ message(FATAL_ERROR "Unknown dependency kind: ${kind}")
+ endif()
+
+ # Preserve a system path supplied by the caller, after checking local paths.
+ set(system_hint)
+ if(DEFINED ${output} AND EXISTS "${${output}}")
+ if(IS_DIRECTORY "${${output}}")
+ set(system_hint "${${output}}")
+ else()
+ get_filename_component(system_hint "${${output}}" DIRECTORY)
+ endif()
+ endif()
+ set(selected "${output}-NOTFOUND")
+ set(is_local FALSE)
+ foreach(location LOCAL SYSTEM)
+ unset(candidate CACHE)
+ unset(candidate)
+ if(location STREQUAL "LOCAL")
+ if(NOT directories)
+ continue()
+ endif()
+ set(search PATHS ${directories} NO_DEFAULT_PATH)
+ else()
+ set(search HINTS ${system_hint})
+ endif()
+ if(kind STREQUAL "PROGRAM")
+ find_program(candidate NAMES ${dependency_NAMES}
+ PATH_SUFFIXES ${dependency_PATH_SUFFIXES} ${search})
+ elseif(kind STREQUAL "LIBRARY")
+ find_library(candidate NAMES ${dependency_NAMES}
+ PATH_SUFFIXES ${dependency_PATH_SUFFIXES} ${search})
+ else()
+ find_path(candidate NAMES ${dependency_NAMES}
+ PATH_SUFFIXES ${dependency_PATH_SUFFIXES} ${search})
+ endif()
+ if(candidate)
+ set(selected "${candidate}")
+ if(location STREQUAL "LOCAL")
+ set(is_local TRUE)
+ endif()
+ break()
+ endif()
+ endforeach()
+ unset(candidate CACHE)
+ if(NOT selected AND dependency_REQUIRED)
+ message(FATAL_ERROR "Required dependency ${output} (${dependency_NAMES}) was not found locally or in the system")
+ endif()
+ set(${output} "${selected}" CACHE ${cache_type} "Resolved dependency" FORCE)
+ set(${output} "${selected}" PARENT_SCOPE)
+ set(${output}_LOCAL "${is_local}" PARENT_SCOPE)
+endfunction()
+
+macro(cpsc_find_library output)
+ cpsc_find_dependency(LIBRARY ${output} NAMES ${ARGN})
+endmacro()
+
+macro(cpsc_find_include output name)
+ cpsc_find_dependency(PATH ${output} NAMES "${name}")
+endmacro()
diff --git a/cmake/GenerateManual.cmake.in b/cmake/GenerateManual.cmake.in
index dd1db2e..23b3929 100644
--- a/cmake/GenerateManual.cmake.in
+++ b/cmake/GenerateManual.cmake.in
@@ -1,27 +1,20 @@
# Pandoc is optional until the doc/install/release target actually needs it.
-set(local_bins "@CPSC_LOCAL_BIN_DIRS@")
-find_program(pandoc NAMES pandoc PATHS ${local_bins} NO_DEFAULT_PATH)
-if(pandoc)
- set(local_pandoc TRUE)
-else()
- find_program(pandoc NAMES pandoc)
-endif()
-if(NOT pandoc)
- message(FATAL_ERROR "Generating the manual requires Pandoc; download it to deps/packages or install it in PATH")
-endif()
+set(CPSC_LOCAL_BIN_DIRS "@CPSC_LOCAL_BIN_DIRS@")
+include("@CPSC_DEPS_MODULE_DIR@/FindDependency.cmake")
+cpsc_find_dependency(PROGRAM pandoc NAMES pandoc REQUIRED)
message(STATUS "Using Pandoc: ${pandoc}")
set(arguments --standalone --from=markdown --to=@cpsc_manual_format@)
if("@cpsc_manual_format@" STREQUAL "html5")
list(APPEND arguments --metadata "title=cpsc manual")
endif()
-if(local_pandoc AND IS_DIRECTORY "@CPSC_DEPS_ROOT@/usr/share/pandoc/data")
+if(pandoc_LOCAL AND IS_DIRECTORY "@CPSC_DEPS_ROOT@/usr/share/pandoc/data")
list(APPEND arguments "--data-dir=@CPSC_DEPS_ROOT@/usr/share/pandoc/data")
endif()
-if(local_pandoc AND WIN32)
- set(ENV{PATH} "${local_bins};$ENV{PATH}")
-elseif(local_pandoc AND UNIX AND NOT APPLE)
+if(pandoc_LOCAL AND WIN32)
+ set(ENV{PATH} "${CPSC_LOCAL_BIN_DIRS};$ENV{PATH}")
+elseif(pandoc_LOCAL AND UNIX AND NOT APPLE)
string(REPLACE ";" ":" libraries "@CPSC_LOCAL_LIBRARY_DIRS@")
if(NOT "$ENV{LD_LIBRARY_PATH}" STREQUAL "")
string(APPEND libraries ":$ENV{LD_LIBRARY_PATH}")
diff --git a/cmake/HomebrewPackages.cmake b/cmake/HomebrewPackages.cmake
index 30c0e70..cfd8d61 100644
--- a/cmake/HomebrewPackages.cmake
+++ b/cmake/HomebrewPackages.cmake
@@ -35,13 +35,10 @@ function(cpsc_prepare_homebrew_packages)
endforeach()
# Bottles carry placeholder install names; extraction alone is insufficient.
- find_program(cpsc_otool otool)
- find_program(cpsc_install_name_tool install_name_tool)
- find_program(cpsc_codesign codesign)
- find_program(cpsc_brew brew)
- if(NOT cpsc_otool OR NOT cpsc_install_name_tool OR NOT cpsc_codesign)
- message(FATAL_ERROR "Local Homebrew bottles require otool, install_name_tool and codesign")
- endif()
+ cpsc_find_dependency(PROGRAM cpsc_otool NAMES otool REQUIRED)
+ cpsc_find_dependency(PROGRAM cpsc_install_name_tool NAMES install_name_tool REQUIRED)
+ cpsc_find_dependency(PROGRAM cpsc_codesign NAMES codesign REQUIRED)
+ cpsc_find_dependency(PROGRAM cpsc_brew NAMES brew)
if(cpsc_brew)
execute_process(COMMAND "${cpsc_brew}" --prefix
OUTPUT_VARIABLE system_prefix OUTPUT_STRIP_TRAILING_WHITESPACE
diff --git a/cmake/Install.cmake.in b/cmake/Install.cmake.in
index b4d2c8f..c6cd83f 100644
--- a/cmake/Install.cmake.in
+++ b/cmake/Install.cmake.in
@@ -1,18 +1,17 @@
# The ordinary build does not require Pandoc; generate the manual on installation.
+set(CPSC_LOCAL_BIN_DIRS "@CPSC_LOCAL_BIN_DIRS@")
+include("@CPSC_DEPS_MODULE_DIR@/FindDependency.cmake")
execute_process(
COMMAND "@CMAKE_COMMAND@" --build "@CMAKE_CURRENT_BINARY_DIR@" --target doc
RESULT_VARIABLE cpsc_doc_result
)
if(NOT cpsc_doc_result STREQUAL "0")
- message(FATAL_ERROR "Cannot build the manual; make sure Pandoc is installed")
+ message(FATAL_ERROR "Cannot build the manual; Pandoc must be available locally or in PATH")
endif()
set(cpsc_install_windows "@WIN32@")
if(cpsc_install_windows)
- find_program(cpsc_powershell NAMES powershell.exe)
- if(NOT cpsc_powershell)
- message(FATAL_ERROR "Windows installation requires Windows PowerShell (powershell.exe)")
- endif()
+ cpsc_find_dependency(PROGRAM cpsc_powershell NAMES powershell.exe REQUIRED)
execute_process(
COMMAND "${cpsc_powershell}" -NoProfile -NonInteractive -ExecutionPolicy Bypass
-File "@CMAKE_CURRENT_SOURCE_DIR@/install.ps1"
@@ -21,8 +20,9 @@ if(cpsc_install_windows)
RESULT_VARIABLE cpsc_install_result
)
else()
+ cpsc_find_dependency(PROGRAM cpsc_shell NAMES sh bash REQUIRED)
execute_process(
- COMMAND sh "@CMAKE_CURRENT_SOURCE_DIR@/install.sh"
+ COMMAND "${cpsc_shell}" "@CMAKE_CURRENT_SOURCE_DIR@/install.sh"
--source-dir "@CMAKE_CURRENT_BINARY_DIR@"
--prefix "${CMAKE_INSTALL_PREFIX}"
RESULT_VARIABLE cpsc_install_result
diff --git a/cmake/LLVMDependencies.cmake b/cmake/LLVMDependencies.cmake
new file mode 100644
index 0000000..585f379
--- /dev/null
+++ b/cmake/LLVMDependencies.cmake
@@ -0,0 +1,23 @@
+cpsc_dependency_paths("${CMAKE_BINARY_DIR}")
+list(INSERT CMAKE_PREFIX_PATH 0 ${CPSC_LOCAL_PREFIXES})
+list(INSERT CMAKE_LIBRARY_PATH 0 ${CPSC_LOCAL_LIBRARY_DIRS})
+list(INSERT CMAKE_INCLUDE_PATH 0 ${CPSC_LOCAL_INCLUDE_DIRS})
+
+cpsc_find_dependency(PATH LLVM_DIR NAMES LLVMConfig.cmake
+ PATH_SUFFIXES lib/cmake/llvm cmake)
+# find_package(LLVM REQUIRED CONFIG) also checks standard system package layouts.
+cpsc_find_dependency(PATH zstd_DIR NAMES zstdConfig.cmake
+ PATH_SUFFIXES lib/cmake/zstd "lib/${CMAKE_LIBRARY_ARCHITECTURE}/cmake/zstd")
+cpsc_find_library(ZLIB_LIBRARY_RELEASE z)
+cpsc_find_library(zstd_LIBRARY zstd zstd_static)
+cpsc_find_library(zstd_STATIC_LIBRARY libzstd.a libzstd_static.a)
+cpsc_find_library(Terminfo_LIBRARIES terminfo tinfo curses ncurses ncursesw)
+cpsc_find_library(FFI_LIBRARIES ffi)
+cpsc_find_library(FFI_STATIC_LIBRARIES libffi.a)
+cpsc_find_library(LibEdit_LIBRARIES edit)
+cpsc_find_library(LIBXML2_LIBRARY xml2)
+cpsc_find_include(ZLIB_INCLUDE_DIR zlib.h)
+cpsc_find_include(zstd_INCLUDE_DIR zstd.h)
+cpsc_find_include(FFI_INCLUDE_DIRS ffi.h)
+cpsc_find_include(LibEdit_INCLUDE_DIRS histedit.h)
+cpsc_find_include(LIBXML2_INCLUDE_DIR libxml/xpath.h)
diff --git a/cmake/LinuxPackages.cmake b/cmake/LinuxPackages.cmake
index 9e9f26b..0412c4a 100644
--- a/cmake/LinuxPackages.cmake
+++ b/cmake/LinuxPackages.cmake
@@ -1,9 +1,10 @@
function(cpsc_prepare_linux_packages)
+ cpsc_find_dependency(PROGRAM cpsc_readlink NAMES readlink REQUIRED)
# Development packages can contain absolute links to runtime packages.
file(GLOB_RECURSE files LIST_DIRECTORIES FALSE "${CPSC_DEPS_ROOT}/*")
foreach(path IN LISTS files)
if(IS_SYMLINK "${path}")
- execute_process(COMMAND readlink "${path}" OUTPUT_VARIABLE target
+ execute_process(COMMAND "${cpsc_readlink}" "${path}" OUTPUT_VARIABLE target
OUTPUT_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE result)
if(NOT result EQUAL 0)
message(FATAL_ERROR "Cannot read dependency symlink ${path}")
diff --git a/cmake/LocalDependencies.cmake b/cmake/LocalDependencies.cmake
index 8b80ee3..2ee503a 100644
--- a/cmake/LocalDependencies.cmake
+++ b/cmake/LocalDependencies.cmake
@@ -1,112 +1,11 @@
set(CPSC_DEPS_MODULE_DIR "${CMAKE_CURRENT_LIST_DIR}")
set(CPSC_DEPS_DIR "${CMAKE_BINARY_DIR}/deps")
set(CPSC_DEPS_ROOT "${CPSC_DEPS_DIR}/root")
+include("${CPSC_DEPS_MODULE_DIR}/FindDependency.cmake")
+include("${CPSC_DEPS_MODULE_DIR}/DependencyPaths.cmake")
include("${CPSC_DEPS_MODULE_DIR}/ExtractPackages.cmake")
include("${CPSC_DEPS_MODULE_DIR}/LinuxPackages.cmake")
include("${CPSC_DEPS_MODULE_DIR}/WindowsPackages.cmake")
include("${CPSC_DEPS_MODULE_DIR}/HomebrewPackages.cmake")
cpsc_extract_packages()
-
-set(cpsc_local_prefixes)
-foreach(prefix "${CPSC_DEPS_ROOT}/usr" "${CPSC_DEPS_ROOT}/mingw64"
- "${CPSC_DEPS_ROOT}/ucrt64" "${CPSC_DEPS_ROOT}/clang64")
- if(IS_DIRECTORY "${prefix}")
- list(APPEND cpsc_local_prefixes "${prefix}")
- endif()
-endforeach()
-file(GLOB llvm_prefixes LIST_DIRECTORIES TRUE "${CPSC_DEPS_ROOT}/usr/lib/llvm-*")
-file(GLOB brew_prefixes LIST_DIRECTORIES TRUE "${CPSC_DEPS_ROOT}/opt/*")
-list(APPEND cpsc_local_prefixes ${llvm_prefixes} ${brew_prefixes})
-
-set(CPSC_LOCAL_LIBRARY_DIRS)
-set(CPSC_LOCAL_INCLUDE_DIRS)
-set(CPSC_LOCAL_BIN_DIRS)
-foreach(prefix IN LISTS cpsc_local_prefixes)
- list(APPEND CPSC_LOCAL_LIBRARY_DIRS "${prefix}/lib")
- list(APPEND CPSC_LOCAL_INCLUDE_DIRS "${prefix}/include")
- list(APPEND CPSC_LOCAL_INCLUDE_DIRS "${prefix}/include/libxml2")
- list(APPEND CPSC_LOCAL_BIN_DIRS "${prefix}/bin")
-endforeach()
-file(GLOB pandoc_directories LIST_DIRECTORIES TRUE "${CPSC_DEPS_ROOT}/pandoc-*")
-foreach(directory IN LISTS pandoc_directories)
- if(IS_DIRECTORY "${directory}")
- list(APPEND CPSC_LOCAL_BIN_DIRS "${directory}")
- endif()
-endforeach()
-if(CMAKE_LIBRARY_ARCHITECTURE)
- list(INSERT CPSC_LOCAL_LIBRARY_DIRS 0
- "${CPSC_DEPS_ROOT}/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}"
- "${CPSC_DEPS_ROOT}/lib/${CMAKE_LIBRARY_ARCHITECTURE}")
- list(APPEND CPSC_LOCAL_INCLUDE_DIRS
- "${CPSC_DEPS_ROOT}/usr/include/${CMAKE_LIBRARY_ARCHITECTURE}")
-endif()
-if(cpsc_local_prefixes)
- list(INSERT CMAKE_PREFIX_PATH 0 ${cpsc_local_prefixes})
-endif()
-list(INSERT CMAKE_LIBRARY_PATH 0 ${CPSC_LOCAL_LIBRARY_DIRS})
-list(INSERT CMAKE_INCLUDE_PATH 0 ${CPSC_LOCAL_INCLUDE_DIRS})
-
-# Search afresh so cached system paths do not defeat newly downloaded packages.
-function(cpsc_find_library output)
- unset(cpsc_local_library CACHE)
- find_library(cpsc_local_library NAMES ${ARGN}
- PATHS ${CPSC_LOCAL_LIBRARY_DIRS} NO_DEFAULT_PATH)
- if(cpsc_local_library)
- set(selected "${cpsc_local_library}")
- else()
- unset(cpsc_system_library CACHE)
- find_library(cpsc_system_library NAMES ${ARGN})
- set(selected "${cpsc_system_library}")
- endif()
- set(${output} "${selected}" CACHE FILEPATH "Resolved dependency library" FORCE)
- set(${output} "${selected}" PARENT_SCOPE)
-endfunction()
-
-function(cpsc_find_include output name)
- unset(cpsc_local_include CACHE)
- find_path(cpsc_local_include NAMES "${name}"
- PATHS ${CPSC_LOCAL_INCLUDE_DIRS} NO_DEFAULT_PATH)
- if(cpsc_local_include)
- set(${output} "${cpsc_local_include}" CACHE PATH "Local dependency headers" FORCE)
- set(${output} "${cpsc_local_include}" PARENT_SCOPE)
- elseif(DEFINED ${output} AND "${${output}}" MATCHES "^${CPSC_DEPS_ROOT}/")
- unset(${output} CACHE)
- unset(${output} PARENT_SCOPE)
- endif()
-endfunction()
-
-unset(cpsc_local_llvm CACHE)
-find_path(cpsc_local_llvm LLVMConfig.cmake PATHS ${cpsc_local_prefixes}
- PATH_SUFFIXES lib/cmake/llvm cmake NO_DEFAULT_PATH)
-if(cpsc_local_llvm)
- set(LLVM_DIR "${cpsc_local_llvm}" CACHE PATH "LLVM CMake package directory" FORCE)
- set(LLVM_DIR "${cpsc_local_llvm}")
-elseif(LLVM_DIR MATCHES "^${CPSC_DEPS_ROOT}/")
- unset(LLVM_DIR CACHE)
- unset(LLVM_DIR)
-endif()
-# Config-mode dependencies also need to override earlier system cache entries.
-unset(cpsc_local_zstd CACHE)
-find_path(cpsc_local_zstd zstdConfig.cmake PATHS ${cpsc_local_prefixes}
- PATH_SUFFIXES lib/cmake/zstd "lib/${CMAKE_LIBRARY_ARCHITECTURE}/cmake/zstd"
- NO_DEFAULT_PATH)
-if(cpsc_local_zstd)
- set(zstd_DIR "${cpsc_local_zstd}" CACHE PATH "zstd CMake package directory" FORCE)
- set(zstd_DIR "${cpsc_local_zstd}")
-elseif(zstd_DIR MATCHES "^${CPSC_DEPS_ROOT}/")
- unset(zstd_DIR CACHE)
- unset(zstd_DIR)
-endif()
-cpsc_find_library(ZLIB_LIBRARY_RELEASE z)
-cpsc_find_library(zstd_LIBRARY zstd zstd_static)
-cpsc_find_library(zstd_STATIC_LIBRARY libzstd.a libzstd_static.a)
-cpsc_find_library(Terminfo_LIBRARIES terminfo tinfo curses ncurses ncursesw)
-cpsc_find_library(FFI_LIBRARIES ffi)
-cpsc_find_library(FFI_STATIC_LIBRARIES libffi.a)
-cpsc_find_library(LibEdit_LIBRARIES edit)
-cpsc_find_library(LIBXML2_LIBRARY xml2)
-cpsc_find_include(ZLIB_INCLUDE_DIR zlib.h)
-cpsc_find_include(zstd_INCLUDE_DIR zstd.h)
-cpsc_find_include(FFI_INCLUDE_DIRS ffi.h)
-cpsc_find_include(LibEdit_INCLUDE_DIRS histedit.h)
-cpsc_find_include(LIBXML2_INCLUDE_DIR libxml/xpath.h)
+cpsc_dependency_paths("${CMAKE_BINARY_DIR}")
diff --git a/cmake/Manual.cmake b/cmake/Manual.cmake
index 0ba4ccb..ce47a41 100644
--- a/cmake/Manual.cmake
+++ b/cmake/Manual.cmake
@@ -9,7 +9,8 @@ endif()
configure_file("${CMAKE_CURRENT_LIST_DIR}/GenerateManual.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/GenerateManual.cmake" @ONLY)
set(cpsc_manual_dependencies "${CMAKE_CURRENT_SOURCE_DIR}/doc/cpsc.md"
- "${CMAKE_CURRENT_BINARY_DIR}/GenerateManual.cmake")
+ "${CMAKE_CURRENT_BINARY_DIR}/GenerateManual.cmake"
+ "${CPSC_DEPS_MODULE_DIR}/FindDependency.cmake")
if(EXISTS "${CPSC_DEPS_DIR}/packages.sha256")
list(APPEND cpsc_manual_dependencies "${CPSC_DEPS_DIR}/packages.sha256")
endif()
diff --git a/cmake/Release.cmake b/cmake/Release.cmake
index fe78711..49dee98 100644
--- a/cmake/Release.cmake
+++ b/cmake/Release.cmake
@@ -1,4 +1,6 @@
# Read HEAD at packaging time so subsequent commits do not require reconfiguration.
+include("${CPSC_SOURCE_DIR}/cmake/FindDependency.cmake")
+cpsc_find_dependency(PROGRAM GIT_EXECUTABLE NAMES git REQUIRED)
find_package(Git REQUIRED)
execute_process(
COMMAND "${GIT_EXECUTABLE}" -C "${CPSC_SOURCE_DIR}" log -1 "--format=%ct:%h"