diff --git a/cmake/transcribe-install.cmake b/cmake/transcribe-install.cmake index 586799cb..5bc0a0f7 100644 --- a/cmake/transcribe-install.cmake +++ b/cmake/transcribe-install.cmake @@ -11,6 +11,7 @@ # lib/ libtranscribe (static or shared per TRANSCRIBE_BUILD_SHARED) # + ggml/ggml-base/backend libs (ggml's own install rules) # + transcribe-link.json (the link manifest, see below) +# + pkgconfig/transcribe.pc (pkg-config metadata, see below) # # transcribe-link.json is the machine-readable link interface for non-CMake # consumers: which archives to link in which order, plus the system @@ -209,6 +210,59 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/transcribe-link.json" install(FILES "${CMAKE_CURRENT_BINARY_DIR}/transcribe-link.json" DESTINATION ${CMAKE_INSTALL_LIBDIR}) +# --- pkg-config metadata (transcribe.pc) ------------------------------------- +# For consumers that speak pkg-config rather than CMake: meson, autotools, +# distro -devel packages. The manifest is also reachable from here, for +# consumers that want the full link interface: +# +# pkg-config --variable=linkmanifest transcribe +# +# Libs vs Libs.private: Libs is what a consumer of the SHARED library needs +# (libtranscribe.so already carries DT_NEEDED on the ggml libraries, so +# -ltranscribe is enough); Libs.private is what a static link additionally +# drags in, and pkg-config emits it only under --static. Both are built from +# the same lists that feed the manifest above, so the two cannot drift: in a +# static build _libraries is the whole archive set (kept in Libs, in +# single-pass-ld order, so a plain --libs is not a broken link line) and the +# system libraries/frameworks/flags land in Libs.private. In a shared build +# those lists are empty and Libs.private is empty with them — the install +# ships no archives, so there is nothing extra to link. +# +# GNUInstallDirs permits an absolute CMAKE_INSTALL_, which must not be +# re-rooted at ${prefix}; keep the ${prefix}-relative form (what makes +# `pkg-config --define-prefix` work) only when the directory is relative. +set(TRANSCRIBE_PC_LIBDIR "\${prefix}/${CMAKE_INSTALL_LIBDIR}") +if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}") + set(TRANSCRIBE_PC_LIBDIR "${CMAKE_INSTALL_LIBDIR}") +endif() +set(TRANSCRIBE_PC_INCLUDEDIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") +if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}") + set(TRANSCRIBE_PC_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}") +endif() +set(TRANSCRIBE_PC_LIBS "-L\${libdir}") +foreach(_lib IN LISTS _libraries) + string(APPEND TRANSCRIBE_PC_LIBS " -l${_lib}") +endforeach() +set(TRANSCRIBE_PC_LIBS_PRIVATE "") +foreach(_flag IN LISTS _link_flags) + string(APPEND TRANSCRIBE_PC_LIBS_PRIVATE " ${_flag}") +endforeach() +foreach(_path IN LISTS _library_paths) + string(APPEND TRANSCRIBE_PC_LIBS_PRIVATE " ${_path}") +endforeach() +foreach(_framework IN LISTS _frameworks) + string(APPEND TRANSCRIBE_PC_LIBS_PRIVATE " -framework ${_framework}") +endforeach() +foreach(_lib IN LISTS _system_libs) + string(APPEND TRANSCRIBE_PC_LIBS_PRIVATE " -l${_lib}") +endforeach() +string(STRIP "${TRANSCRIBE_PC_LIBS_PRIVATE}" TRANSCRIBE_PC_LIBS_PRIVATE) +configure_file("${CMAKE_CURRENT_LIST_DIR}/transcribe.pc.in" + "${CMAKE_CURRENT_BINARY_DIR}/transcribe.pc" + @ONLY) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/transcribe.pc" + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) + message(STATUS "transcribe install: ${PROJECT_VERSION} shared=${TRANSCRIBE_BUILD_SHARED} " "backends: ${_kinds} (link manifest: lib/transcribe-link.json)") diff --git a/cmake/transcribe.pc.in b/cmake/transcribe.pc.in new file mode 100644 index 00000000..36fbb773 --- /dev/null +++ b/cmake/transcribe.pc.in @@ -0,0 +1,12 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +libdir=@TRANSCRIBE_PC_LIBDIR@ +includedir=@TRANSCRIBE_PC_INCLUDEDIR@ +linkmanifest=${libdir}/transcribe-link.json + +Name: transcribe +Description: C/C++ speech-to-text inference library on the ggml runtime +Version: @PROJECT_VERSION@ +Libs: @TRANSCRIBE_PC_LIBS@ +Libs.private: @TRANSCRIBE_PC_LIBS_PRIVATE@ +Cflags: -I${includedir}