forked from gentoo/gentoo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ltprune.eclass: Split prune_libtool_files out of eutils
Move the prune_libtool_files into a dedicated ltprune.eclass. The function is quite complex and depends on toolchain-funcs. It has a separate maintainer, is not useful to non-autotools ebuilds, and even there it is frequently replaced by the simpler 'find ... -delete' call. The new eclass is implicitly inherited by eutils in EAPI 6 and older in order to preserve compatibility with existing ebuilds. However, all ebuilds should switch to inheriting it directly. The split has been suggested by Ulrich Müller.
- Loading branch information
Showing
2 changed files
with
168 additions
and
149 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
# Copyright 1999-2017 Gentoo Foundation | ||
# Distributed under the terms of the GNU General Public License v2 | ||
|
||
# @ECLASS: ltprune.eclass | ||
# @MAINTAINER: | ||
# Michał Górny <[email protected]> | ||
# @BLURB: Smart .la file pruning | ||
# @DESCRIPTION: | ||
# A function to locate and remove unnecessary .la files. | ||
# | ||
# Discouraged. Whenever possible, please use much simpler: | ||
# @CODE | ||
# find "${D}" -name '*.la' -delete || die | ||
# @CODE | ||
|
||
if [[ -z ${_LTPRUNE_ECLASS} ]]; then | ||
|
||
inherit toolchain-funcs | ||
|
||
# @FUNCTION: prune_libtool_files | ||
# @USAGE: [--all|--modules] | ||
# @DESCRIPTION: | ||
# Locate unnecessary libtool files (.la) and libtool static archives | ||
# (.a) and remove them from installation image. | ||
# | ||
# By default, .la files are removed whenever the static linkage can | ||
# either be performed using pkg-config or doesn't introduce additional | ||
# flags. | ||
# | ||
# If '--modules' argument is passed, .la files for modules (plugins) are | ||
# removed as well. This is usually useful when the package installs | ||
# plugins and the plugin loader does not use .la files. | ||
# | ||
# If '--all' argument is passed, all .la files are removed without | ||
# performing any heuristic on them. You shouldn't ever use that, | ||
# and instead report a bug in the algorithm instead. | ||
# | ||
# The .a files are only removed whenever corresponding .la files state | ||
# that they should not be linked to, i.e. whenever these files | ||
# correspond to plugins. | ||
# | ||
# Note: if your package installs both static libraries and .pc files | ||
# which use variable substitution for -l flags, you need to add | ||
# pkg-config to your DEPEND. | ||
prune_libtool_files() { | ||
debug-print-function ${FUNCNAME} "$@" | ||
|
||
local removing_all removing_modules opt | ||
for opt; do | ||
case "${opt}" in | ||
--all) | ||
removing_all=1 | ||
removing_modules=1 | ||
;; | ||
--modules) | ||
removing_modules=1 | ||
;; | ||
*) | ||
die "Invalid argument to ${FUNCNAME}(): ${opt}" | ||
esac | ||
done | ||
|
||
local f | ||
local queue=() | ||
while IFS= read -r -d '' f; do # for all .la files | ||
local archivefile=${f/%.la/.a} | ||
|
||
# The following check is done by libtool itself. | ||
# It helps us avoid removing random files which match '*.la', | ||
# see bug #468380. | ||
if ! sed -n -e '/^# Generated by .*libtool/q0;4q1' "${f}"; then | ||
continue | ||
fi | ||
|
||
[[ ${f} != ${archivefile} ]] || die 'regex sanity check failed' | ||
local reason= pkgconfig_scanned= | ||
local snotlink=$(sed -n -e 's:^shouldnotlink=::p' "${f}") | ||
|
||
if [[ ${snotlink} == yes ]]; then | ||
|
||
# Remove static libs we're not supposed to link against. | ||
if [[ -f ${archivefile} ]]; then | ||
einfo "Removing unnecessary ${archivefile#${D%/}} (static plugin)" | ||
queue+=( "${archivefile}" ) | ||
fi | ||
|
||
# The .la file may be used by a module loader, so avoid removing it | ||
# unless explicitly requested. | ||
if [[ ${removing_modules} ]]; then | ||
reason='module' | ||
fi | ||
|
||
else | ||
|
||
# Remove .la files when: | ||
# - user explicitly wants us to remove all .la files, | ||
# - respective static archive doesn't exist, | ||
# - they are covered by a .pc file already, | ||
# - they don't provide any new information (no libs & no flags). | ||
|
||
if [[ ${removing_all} ]]; then | ||
reason='requested' | ||
elif [[ ! -f ${archivefile} ]]; then | ||
reason='no static archive' | ||
elif [[ ! $(sed -nre \ | ||
"s/^(dependency_libs|inherited_linker_flags)='(.*)'$/\2/p" \ | ||
"${f}") ]]; then | ||
reason='no libs & flags' | ||
else | ||
if [[ ! ${pkgconfig_scanned} ]]; then | ||
# Create a list of all .pc-covered libs. | ||
local pc_libs=() | ||
if [[ ! ${removing_all} ]]; then | ||
local pc | ||
local tf=${T}/prune-lt-files.pc | ||
local pkgconf=$(tc-getPKG_CONFIG) | ||
|
||
while IFS= read -r -d '' pc; do # for all .pc files | ||
local arg libs | ||
|
||
# Use pkg-config if available (and works), | ||
# fallback to sed. | ||
if ${pkgconf} --exists "${pc}" &>/dev/null; then | ||
sed -e '/^Requires:/d' "${pc}" > "${tf}" | ||
libs=$(${pkgconf} --libs "${tf}") | ||
else | ||
libs=$(sed -ne 's/^Libs://p' "${pc}") | ||
fi | ||
|
||
for arg in ${libs}; do | ||
if [[ ${arg} == -l* ]]; then | ||
if [[ ${arg} == '*$*' ]]; then | ||
eerror "${FUNCNAME}: variable substitution likely failed in ${pc}" | ||
eerror "(arg: ${arg})" | ||
eerror "Most likely, you need to add virtual/pkgconfig to DEPEND." | ||
die "${FUNCNAME}: unsubstituted variable found in .pc" | ||
fi | ||
|
||
pc_libs+=( lib${arg#-l}.la ) | ||
fi | ||
done | ||
done < <(find "${D}" -type f -name '*.pc' -print0) | ||
|
||
rm -f "${tf}" | ||
fi | ||
|
||
pkgconfig_scanned=1 | ||
fi # pkgconfig_scanned | ||
|
||
has "${f##*/}" "${pc_libs[@]}" && reason='covered by .pc' | ||
fi # removal due to .pc | ||
|
||
fi # shouldnotlink==no | ||
|
||
if [[ ${reason} ]]; then | ||
einfo "Removing unnecessary ${f#${D%/}} (${reason})" | ||
queue+=( "${f}" ) | ||
fi | ||
done < <(find "${D}" -xtype f -name '*.la' -print0) | ||
|
||
if [[ ${queue[@]} ]]; then | ||
rm -f "${queue[@]}" | ||
fi | ||
} | ||
|
||
_LTPRUNE_ECLASS=1 | ||
fi #_LTPRUNE_ECLASS |