When the option "autodeps" is enabled, makepkg will add provides entries for libraries found in the directories specified in LIB_DIRS in makepkg.conf. The entries LIB_DIRS array have the format "prefix:directory". For example, the entry "lib:usr/lib" will search $pkgdir/usr/lib for library sonames and add "lib:libfoo.so.1" to the provides array. Signed-off-by: Allan McRae <allan@archlinux.org> --- doc/makepkg.conf.5.asciidoc | 11 ++++ etc/makepkg.conf.in | 2 + .../libmakepkg/autodep/library_provides.sh.in | 56 +++++++++++++++++++ scripts/libmakepkg/autodep/meson.build | 18 ++++++ scripts/libmakepkg/meson.build | 1 + 5 files changed, 88 insertions(+) create mode 100644 scripts/libmakepkg/autodep/library_provides.sh.in create mode 100644 scripts/libmakepkg/autodep/meson.build diff --git a/doc/makepkg.conf.5.asciidoc b/doc/makepkg.conf.5.asciidoc index 76c27f6a..39c5c808 100644 --- a/doc/makepkg.conf.5.asciidoc +++ b/doc/makepkg.conf.5.asciidoc @@ -193,6 +193,11 @@ Options Enable building packages using link time optimization. Adds '-flto' to both CFLAGS and CXXFLAGS. + *autodep*;; + Enable the automatic addition of libraries to the depends and + provides arrays. Search library directories are controlled by + the LIB_DIRS variable defined below. + **INTEGRITY_CHECK=(**check1 ...**)**:: File integrity checks to use. Multiple checks may be specified; this affects both generation and checking. The current valid options are: @@ -223,6 +228,12 @@ Options that are located in opt/, you may need to add the directory to this array. *NOTE:* Do not add the leading slash to the directory name. +**LIB_DIRS=(**lib:usr/lib ...**)**:: + If `autodeps` is specified in the `OPTIONS` array, this variable will + instruct makepkg where to look to find librarys to add to the `provides` + array. The format is "prefix:path", where provides will be added for + libraries found in "path" with the specified prefix added. + **PURGE_TARGETS=(**usr/{,share}/info/dir .podlist *.pod...**)**:: If `purge` is specified in the `OPTIONS` array, this variable will instruct makepkg which files to remove from the package. This is diff --git a/etc/makepkg.conf.in b/etc/makepkg.conf.in index f69a7add..0c911cce 100644 --- a/etc/makepkg.conf.in +++ b/etc/makepkg.conf.in @@ -109,6 +109,8 @@ DOC_DIRS=(usr/{,local/}{,share/}{doc,gtk-doc} opt/*/{doc,gtk-doc}) PURGE_TARGETS=(usr/{,share}/info/dir .packlist *.pod) #-- Directory to store source code in for debug packages DBGSRCDIR="/usr/src/debug" +#-- Prefix and directories for library autodeps +LIB_DIRS=('lib:/usr/lib' 'lib32:/usr/lib32') ######################################################################### # PACKAGE OUTPUT diff --git a/scripts/libmakepkg/autodep/library_provides.sh.in b/scripts/libmakepkg/autodep/library_provides.sh.in new file mode 100644 index 00000000..5cd497fa --- /dev/null +++ b/scripts/libmakepkg/autodep/library_provides.sh.in @@ -0,0 +1,56 @@ +#!/bin/bash +# +# library_provides.sh - Automatically add a packages libraries to provides +# +# Copyright (c) 2021 Pacman Development Team <pacman-dev@lists.archlinux.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +[[ -n "$LIBMAKEPKG_AUTODEP_LIBRARY_PROVIDES_SH" ]] && return +LIBMAKEPKG_AUTODEP_LIBRARY_PROVIDES_SH=1 + +LIBRARY=${LIBRARY:-'@libmakepkgdir@'} + +autodep_functions+=('library_provides') + +library_provides() { + if check_option "autodeps" "y"; then + for lib in ${LIB_DIRS[@]}; do + dir=${lib/*:} + prefix=${lib/:*} + + if [[ ! -d "$pkgdir/$dir" ]]; then + continue; + fi + + mapfile -t filenames < <(find "$pkgdir/$dir" -type f | LC_ALL=C sort) + + for fn in "${filenames[@]}"; do + # check we have a shared library + if LC_ALL=C readelf -h "$fn" 2>/dev/null | grep -q '.*Type:.*DYN (Shared object file).*'; then + # extract library soname + local sofile=$(LC_ALL=C readelf -d "$fn" 2>/dev/null | sed -n 's/.*Library soname: \[\(.*\)\].*/\1/p') + + if [[ -z "$sofile" ]]; then + # the library is not versioned + continue + fi + + provides+=("$prefix:$sofile") + fi + done + done + fi +} diff --git a/scripts/libmakepkg/autodep/meson.build b/scripts/libmakepkg/autodep/meson.build new file mode 100644 index 00000000..e0af26a6 --- /dev/null +++ b/scripts/libmakepkg/autodep/meson.build @@ -0,0 +1,18 @@ +libmakepkg_module = 'tidy' + +sources = [ + 'library_provides.sh.in', + +] + +foreach src : sources + output_dir = join_paths(get_option('datadir'), 'makepkg', libmakepkg_module) + + custom_target( + libmakepkg_module + '_' + src.underscorify(), + command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ], + input : src, + output : '@BASENAME@', + install : true, + install_dir : output_dir) +endforeach diff --git a/scripts/libmakepkg/meson.build b/scripts/libmakepkg/meson.build index 50eb905b..6e83a4a8 100644 --- a/scripts/libmakepkg/meson.build +++ b/scripts/libmakepkg/meson.build @@ -1,4 +1,5 @@ libmakepkg_modules = [ + { 'name' : 'autodep', 'has_subdir' : true }, { 'name' : 'buildenv', 'has_subdir' : true }, { 'name' : 'executable', 'has_subdir' : true }, { 'name' : 'integrity', 'has_subdir' : true }, -- 2.34.1