[Git][haskell-team/haskell-devscripts][master] 5 commits: Move detection of missing executable nearer to the point of use.
Felix Lechner (@lechner)
gitlab at salsa.debian.org
Sun Apr 3 11:00:54 BST 2022
Felix Lechner pushed to branch master at Debian Haskell Group / haskell-devscripts
Commits:
8ed04837 by Felix Lechner at 2022-04-02T21:48:27-07:00
Move detection of missing executable nearer to the point of use.
Reduces the functionality of Dh_Haskell.sh, a shell library, so it can be
replaced more easily by a Perl module.
The Perl module will accessible directly from Debhelper.
- - - - -
f1728c58 by Felix Lechner at 2022-04-02T21:48:45-07:00
Parse command line arguments in each script; export DH_EXCLUDES.
Reduces the functionality of Dh_Haskell.sh, a shell library, so it can be
replaced more easily by a Perl module.
The Perl module will be accessible directly from Debhelper.
- - - - -
e5228c9d by Felix Lechner at 2022-04-02T21:48:45-07:00
Add a .perltidyrc (from Lintian).
- - - - -
26b6cd41 by Felix Lechner at 2022-04-02T21:48:45-07:00
Add a .perlcriticrc (from Lintian).
- - - - -
8d20067a by Felix Lechner at 2022-04-03T01:37:37-07:00
Outsource all functions in Dh_Haskell.sh to a Perl module.
- - - - -
11 changed files:
- + .perlcriticrc
- + .perltidyrc
- Dh_Haskell.sh
- debian/control
- debian/haskell-devscripts-minimal.install
- dh_haskell_blurbs
- dh_haskell_depends
- dh_haskell_extra_depends
- dh_haskell_provides
- dh_haskell_shlibdeps
- + lib/Debian/Debhelper/Buildsystem/Haskell/Recipes.pm
Changes:
=====================================
.perlcriticrc
=====================================
@@ -0,0 +1,458 @@
+# -*- conf -*-
+# the list of checks could perhaps be moved to t/scripts/critic.pl.
+
+verbose = 1
+
+# severity is ignored for our main purposes, see below
+severity = 1
+
+criticism-fatal = 1
+color = 1
+allow-unsafe = 1
+
+# to try some other stuff, uncomment the following
+# theme = security || bugs || complexity || maintenance
+
+# use a whitelist; the disabling config blocks below are for documentation only
+only = 1
+
+# use separate blocks below instead of long Lines in include
+include =
+
+[BuiltinFunctions::ProhibitBooleanGrep]
+
+[BuiltinFunctions::ProhibitComplexMappings]
+
+[BuiltinFunctions::ProhibitLvalueSubstr]
+
+[BuiltinFunctions::ProhibitReverseSortBlock]
+
+[BuiltinFunctions::ProhibitShiftRef]
+
+[BuiltinFunctions::ProhibitSleepViaSelect]
+
+[BuiltinFunctions::ProhibitStringyEval]
+allow_includes = 1
+
+[BuiltinFunctions::ProhibitStringySplit]
+
+[BuiltinFunctions::ProhibitUniversalCan]
+
+[BuiltinFunctions::ProhibitUniversalIsa]
+
+[BuiltinFunctions::ProhibitUselessTopic]
+
+[BuiltinFunctions::ProhibitVoidGrep]
+
+[BuiltinFunctions::ProhibitVoidMap]
+
+[BuiltinFunctions::RequireBlockGrep]
+
+[BuiltinFunctions::RequireBlockMap]
+
+[BuiltinFunctions::RequireGlobFunction]
+
+[BuiltinFunctions::RequireSimpleSortBlock]
+
+[ClassHierarchies::ProhibitAutoloading]
+
+[ClassHierarchies::ProhibitExplicitISA]
+
+[ClassHierarchies::ProhibitOneArgBless]
+
+[-CodeLayout::ProhibitFatCommaNewline]
+
+[-CodeLayout::ProhibitIfIfSameLine]
+
+[CodeLayout::ProhibitHardTabs]
+
+[-CodeLayout::ProhibitParensWithBuiltins]
+
+[CodeLayout::ProhibitQuotedWordLists]
+
+[CodeLayout::ProhibitTrailingWhitespace]
+
+[-CodeLayout::RequireConsistentNewlines]
+
+[-CodeLayout::RequireFinalSemicolon]
+
+[CodeLayout::RequireTidyCode]
+
+[-CodeLayout::RequireTrailingCommaAtNewline]
+
+[-CodeLayout::RequireTrailingCommas]
+
+[ControlStructures::ProhibitCStyleForLoops]
+
+[-ControlStructures::ProhibitCascadingIfElse]
+
+[-ControlStructures::ProhibitDeepNests]
+
+[ControlStructures::ProhibitLabelsWithSpecialBlockNames]
+
+[ControlStructures::ProhibitMutatingListFunctions]
+
+[ControlStructures::ProhibitNegativeExpressionsInUnlessAndUntilConditions]
+
+[-ControlStructures::ProhibitPostfixControls]
+
+[-ControlStructures::ProhibitUnlessBlocks]
+
+[ControlStructures::ProhibitUnreachableCode]
+
+[ControlStructures::ProhibitUntilBlocks]
+
+[ControlStructures::ProhibitYadaOperator]
+
+[-Compatibility::ConstantPragmaHash]
+
+[-Compatibility::ConstantLeadingUnderscore]
+
+[-Compatibility::Gtk2Constants]
+
+[-Compatibility::PerlMinimumVersionAndWhy]
+
+[-Compatibility::PodMinimumVersion]
+
+[-Compatibility::ProhibitUnixDevNull]
+
+[-Documentation::PodSpelling]
+
+[-Documentation::ProhibitAdjacentLinks]
+
+[Documentation::ProhibitDuplicateHeadings]
+
+[Documentation::ProhibitDuplicateSeeAlso]
+
+[Documentation::ProhibitBadAproposMarkup]
+
+[Documentation::ProhibitLinkToSelf]
+
+[Documentation::ProhibitParagraphEndComma]
+
+[Documentation::ProhibitParagraphTwoDots]
+
+[Documentation::ProhibitUnbalancedParens]
+
+[-Documentation::ProhibitVerbatimMarkup]
+
+[-Documentation::RequireEndBeforeLastPod]
+
+[-Documentation::RequireFilenameMarkup]
+
+[-Documentation::RequireFinalCut]
+
+[-Documentation::RequireLinkedURLs]
+
+[Documentation::RequirePackageMatchesPodName]
+
+[-Documentation::RequirePodAtEnd]
+
+[-Documentation::RequirePodSections]
+
+[-ErrorHandling::RequireCarping]
+
+[-ErrorHandling::RequireCheckingReturnValueOfEval]
+
+[Freenode::AmpersandSubCalls]
+
+[Freenode::ArrayAssignAref]
+
+[Freenode::BarewordFilehandles]
+
+[Freenode::ConditionalDeclarations]
+
+[Freenode::ConditionalImplicitReturn]
+
+[Freenode::DeprecatedFeatures]
+
+[Freenode::DiscouragedModules]
+
+[Freenode::DollarAB]
+
+[Freenode::Each]
+
+[Freenode::EmptyReturn]
+
+[Freenode::IndirectObjectNotation]
+
+[Freenode::LexicalForeachIterator]
+
+[Freenode::LoopOnHash]
+
+[-Freenode::ModPerl]
+
+[Freenode::MultidimensionalArrayEmulation]
+
+[Freenode::OpenArgs]
+
+[Freenode::OverloadOptions]
+
+[Freenode::PackageMatchesFilename]
+
+[Freenode::POSIXImports]
+
+[Freenode::PreferredAlternatives]
+
+[Freenode::Prototypes]
+
+[Freenode::StrictWarnings]
+
+[Freenode::Threads]
+
+[Freenode::Wantarray]
+
+[Freenode::WarningsSwitch]
+
+[Freenode::WhileDiamondDefaultAssignment]
+
+[InputOutput::ProhibitBacktickOperators]
+
+[InputOutput::ProhibitBarewordFileHandles]
+
+[-InputOutput::ProhibitExplicitStdin]
+
+[InputOutput::ProhibitInteractiveTest]
+
+[InputOutput::ProhibitJoinedReadline]
+
+[-InputOutput::ProhibitOneArgSelect]
+
+[InputOutput::ProhibitReadlineInForLoop]
+
+[-InputOutput::ProhibitTwoArgOpen]
+# not needed with Freenode::OpenArgs
+
+[InputOutput::RequireBracedFileHandleWithPrint]
+
+[-InputOutput::RequireBriefOpen]
+
+[-InputOutput::RequireCheckedClose]
+
+[-InputOutput::RequireCheckedOpen]
+
+[InputOutput::RequireCheckedSyscalls]
+functions = open opendir chdir read readdir readline closedir sysopen sysread sysclose mkdir link pipe readlink unlink rename symlink fork
+# possible TODO: close
+
+[-InputOutput::RequireEncodingWithUTF8Layer]
+
+[Miscellanea::ProhibitFormats]
+
+[-Miscellanea::ProhibitTies]
+
+[Miscellanea::ProhibitUnrestrictedNoCritic]
+
+[Miscellanea::ProhibitUselessNoCritic]
+
+[-Miscellanea::TextDomainPlaceholders]
+
+[-Miscellanea::TextDomainUnused]
+
+[Modules::ProhibitAutomaticExportation]
+
+[Modules::ProhibitConditionalUseStatements]
+
+[Modules::ProhibitEvilModules]
+
+[-Modules::ProhibitExcessMainComplexity]
+# Maybe some day...
+
+[Modules::ProhibitModuleShebang]
+
+[Modules::ProhibitMultiplePackages]
+
+[-Modules::ProhibitPOSIXimport]
+# not needed with Freenode::POSIXImports
+
+[Modules::ProhibitUseQuotedVersion]
+
+[Modules::RequireBarewordIncludes]
+
+[Modules::RequireEndWithOne]
+
+[Modules::RequireExplicitPackage]
+
+[-Modules::RequireFilenameMatchesPackage]
+# not needed with Freenode::PackageMatchesFilename
+
+[Modules::RequireNoMatchVarsWithUseEnglish]
+
+[-Modules::RequireVersionVar]
+# We don't use package versions atm and even if we did, it probably
+# won't have full coverage anyway.
+
+[NamingConventions::Capitalization]
+
+[NamingConventions::ProhibitAmbiguousNames]
+
+[Objects::ProhibitIndirectSyntax]
+
+[References::ProhibitDoubleSigils]
+
+[-RegularExpressions::ProhibitCaptureWithoutTest]
+
+[-RegularExpressions::ProhibitComplexRegexes]
+
+[-RegularExpressions::ProhibitEnumeratedClasses]
+
+[-RegularExpressions::ProhibitEscapedMetacharacters]
+
+[RegularExpressions::ProhibitFixedStringMatches]
+
+[RegularExpressions::ProhibitSingleCharAlternation]
+
+[RegularExpressions::ProhibitUnusedCapture]
+
+[RegularExpressions::ProhibitUnusualDelimiters]
+allow_all_brackets = 1
+
+[RegularExpressions::ProhibitUselessTopic]
+
+[RegularExpressions::RequireBracesForMultiline]
+allow_all_brackets = 1
+
+[-RegularExpressions::RequireDotMatchAnything]
+
+[-RegularExpressions::RequireExtendedFormatting]
+
+[-RegularExpressions::RequireLineBoundaryMatching]
+
+[-Subroutines::ProhibitAmpersandSigils]
+# not needed with Freenode::AmpersandSubCalls
+
+[Subroutines::ProhibitBuiltinHomonyms]
+
+[-Subroutines::ProhibitExcessComplexity]
+
+[-Subroutines::ProhibitExplicitReturnUndef]
+
+[-Subroutines::ProhibitManyArgs]
+
+[Subroutines::ProhibitNestedSubs]
+
+[Subroutines::ProhibitReturnSort]
+
+[-Subroutines::ProhibitSubroutinePrototypes]
+# not needed with Freenode::Prototypes
+
+[Subroutines::ProhibitUnusedPrivateSubroutines]
+
+[Subroutines::ProtectPrivateSubs]
+
+[Subroutines::RequireArgUnpacking]
+
+[Subroutines::RequireFinalReturn]
+terminal_funcs = CORE::exec fatal_error internal_error Lintian::Util::internal_error Die error
+
+[TestingAndDebugging::ProhibitNoStrict]
+
+[-TestingAndDebugging::ProhibitNoWarnings]
+
+[-TestingAndDebugging::ProhibitProlongedStrictureOverride]
+
+[-TestingAndDebugging::RequireTestLabels]
+
+[-TestingAndDebugging::RequireUseStrict]
+# not needed with Freenode::StrictWarnings]
+
+[-TestingAndDebugging::RequireUseWarnings]
+# not needed with Freenode::StrictWarnings]
+
+[ValuesAndExpressions::ConstantBeforeLt]
+
+[ValuesAndExpressions::NotWithCompare]
+
+[-ValuesAndExpressions::ProhibitArrayAssignAref]
+# not needed with Freenode::ArrayAssignAref
+
+[ValuesAndExpressions::ProhibitBarewordDoubleColon]
+
+[ValuesAndExpressions::ProhibitCommaSeparatedStatements]
+
+[-ValuesAndExpressions::ProhibitComplexVersion]
+
+[-ValuesAndExpressions::ProhibitConstantPragma]
+
+[ValuesAndExpressions::ProhibitDuplicateHashKeys]
+
+[ValuesAndExpressions::ProhibitEmptyCommas]
+
+[ValuesAndExpressions::ProhibitEmptyQuotes]
+
+[-ValuesAndExpressions::ProhibitEscapedCharacters]
+
+[ValuesAndExpressions::ProhibitFiletest_f]
+
+[ValuesAndExpressions::ProhibitImplicitNewlines]
+
+[ValuesAndExpressions::ProhibitInterpolationOfLiterals]
+
+[ValuesAndExpressions::ProhibitLeadingZeros]
+
+[ValuesAndExpressions::ProhibitLongChainsOfMethodCalls]
+
+[ValuesAndExpressions::ProhibitMagicNumbers]
+
+[ValuesAndExpressions::ProhibitMismatchedOperators]
+
+[ValuesAndExpressions::ProhibitMixedBooleanOperators]
+
+[ValuesAndExpressions::ProhibitNoisyQuotes]
+
+[ValuesAndExpressions::ProhibitNullStatements]
+
+[ValuesAndExpressions::ProhibitQuotesAsQuotelikeOperatorDelimiters]
+
+[ValuesAndExpressions::ProhibitSpecialLiteralHeredocTerminator]
+
+[ValuesAndExpressions::ProhibitUnknownBackslash]
+
+[-ValuesAndExpressions::ProhibitVersionStrings]
+
+[-ValuesAndExpressions::RequireConstantVersion]
+
+[-ValuesAndExpressions::RequireInterpolationOfMetachars]
+
+[ValuesAndExpressions::RequireNumberSeparators]
+
+[-ValuesAndExpressions::RequireNumericVersion]
+
+[ValuesAndExpressions::RequireQuotedHeredocTerminator]
+
+[ValuesAndExpressions::RequireUpperCaseHeredocTerminator]
+
+[ValuesAndExpressions::UnexpandedSpecialLiteral]
+
+[Variables::ProhibitAugmentedAssignmentInDeclaration]
+
+[Variables::ProhibitConditionalDeclarations]
+
+[-Variables::ProhibitEvilVariables]
+
+[-Variables::ProhibitLocalVars]
+
+[Variables::ProhibitMatchVars]
+
+[Variables::ProhibitPackageVars]
+add_packages = Devel::Size Module::CoreList Text::Glob Text::Wrap YAML::XS
+
+[Variables::ProhibitPerl4PackageNames]
+
+[-Variables::ProhibitPunctuationVars]
+# Requires "use English" and our style is against that.
+
+[Variables::ProhibitReusedNames]
+
+[Variables::ProhibitUnusedVariables]
+
+[Variables::ProtectPrivateVars]
+
+[Variables::RequireInitializationForLocalVars]
+
+[Variables::RequireLexicalLoopIterators]
+
+[Variables::RequireLocalizedPunctuationVars]
+allow = %ENV %SIG $! $? $0
+
+[Variables::RequireNegativeIndices]
=====================================
.perltidyrc
=====================================
@@ -0,0 +1,19 @@
+# -*- conf -*-
+#
+# Default options for perltidy for proper Perl code reformatting.
+#
+# This file is based on the one from the rra-c-util package,
+# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
+
+-bbao # put line breaks before any operator
+-nbbc # don't force blank lines before comments (bad for else blocks)
+-ce # cuddle braces around else
+-l=79 # usually use 78, but don't want 79-long lines reformatted
+-pt=2 # don't add extra whitespace around parentheses
+-sbt=2 # ...or square brackets
+-sfs # no space before semicolon in for (not that I use this form)
+-bar # opening-brace-always-on-right
+-sot # avoid lines with isolated opening tokens
+-sct # ... same for closing tokens
+-fs # allow "perltidy, please don't touch this" sections
+-fws # don't add or delete whitespace
=====================================
Dh_Haskell.sh
=====================================
@@ -1,706 +1,193 @@
+recipe(){
+ local -x RECIPE="$1"
+ shift
+ perl -d:Confess \
+ -MDebian::Debhelper::Buildsystem::Haskell::Recipes=/.*/ \
+ -MUnicode::UTF8=decode_utf8,encode_utf8 \
+ -E 'my @decoded = map { decode_utf8($_) } @ARGV; my @results = $ENV{RECIPE}->(@decoded); my $output = join(q{ }, @results); say encode_utf8($output) if length $output;' "$@" \
+ || exit
+}
+
run () {
- set -eo pipefail
- echo -n "Running" >&2
- printf " %q" "$@" >&2
- echo >&2
- "$@"
+ recipe "${FUNCNAME[0]}" "$@"
}
cpu(){
- set -eo pipefail
- ghc -e 'putStr System.Info.arch'
+ recipe "${FUNCNAME[0]}" "$@"
}
os(){
- set -eo pipefail
- ghc -e 'putStr System.Info.os'
+ recipe "${FUNCNAME[0]}" "$@"
}
ghcjs_version(){
- set -eo pipefail
- ghcjs --numeric-ghcjs-version
+ recipe "${FUNCNAME[0]}" "$@"
}
ghcjs_ghc_version(){
- set -eo pipefail
- ghcjs --numeric-ghc-version
+ recipe "${FUNCNAME[0]}" "$@"
}
package_prefix(){
- set -eo pipefail
- echo $1 | sed -n -e 's|^\([^-]*\)-.*-[^-]*$|\1|p'
+ recipe "${FUNCNAME[0]}" "$@"
}
package_hc(){
- set -eo pipefail
- case $1 in
- ghc|ghc-prof) echo "ghc";;
- *) echo $1 | sed -n -e 's|^lib\([^-]*\)-.*-[^-]*$|\1|p';;
- esac
+ recipe "${FUNCNAME[0]}" "$@"
}
package_ext(){
- set -eo pipefail
- case $1 in
- # I'm told the ghc build uses these scripts, hence these special cases
- ghc) echo "dev";;
- ghc-prof) echo "prof";;
- *) echo $1 | sed -n -e 's|^[^-]*-.*-\([^-]*\)$|\1|p';;
- esac
+ recipe "${FUNCNAME[0]}" "$@"
}
packages_hc(){
- set -eo pipefail
- hcs=`{ for i in ${DEB_PACKAGES}; do package_hc $i; done; } | LC_ALL=C sort -u`
- if [ `echo ${hcs} | wc -w` = 0 ]; then hcs=${DEB_DEFAULT_COMPILER}; fi
- if [ `echo ${hcs} | wc -w` != 1 ]; then echo "Multiple compilers not supported: ${hc}"; exit 1; fi
- echo ${hcs}
+ recipe "${FUNCNAME[0]}" "$@"
}
hc_libdir(){
- set -eo pipefail
- case $1 in
- ghc) echo "usr/lib/haskell-packages/ghc/lib";;
- ghcjs) echo "usr/lib/ghcjs/.cabal/lib";;
- *) echo "Don't know package_libdir for $1" >&2; exit 1;;
- esac
+ recipe "${FUNCNAME[0]}" "$@"
}
package_libdir(){
- set -eo pipefail
- hc_libdir `package_hc $1`
+ recipe "${FUNCNAME[0]}" "$@"
}
hc_pkgdir(){
- set -eo pipefail
- case $1 in
- ghc) echo "var/lib/ghc/package.conf.d";;
- ghcjs) echo "usr/lib/ghcjs/.ghcjs/`cpu`-`os`-`ghcjs_version`-`ghcjs_ghc_version`/ghcjs/package.conf.d";;
- *) echo "Don't know pkgdir for $1" >&2; exit 1;;
- esac
+ recipe "${FUNCNAME[0]}" "$@"
}
package_pkgdir(){
- set -eo pipefail
- hc_pkgdir `package_hc $1`
+ recipe "${FUNCNAME[0]}" "$@"
}
hc_prefix(){
- set -eo pipefail
- case $1 in
- ghc) echo "usr";;
- ghcjs) echo "usr/lib/ghcjs";;
- *) echo "Don't know prefix for compiler $1" >&2; exit 1;;
- esac
+ recipe "${FUNCNAME[0]}" "$@"
}
hc_haddock(){
- set -eo pipefail
- case $1 in
- ghc) echo "haddock";;
- ghcjs) echo "haddock-ghcjs";;
- *) echo "Don't know pkgdir for $1" >&2; exit 1;;
- esac
+ recipe "${FUNCNAME[0]}" "$@"
}
hc_docdir(){
- set -eo pipefail
- hc=$1
- pkgid=$2
- echo "usr/lib/${hc}-doc/haddock/${pkgid}/"
+ recipe "${FUNCNAME[0]}" "$@"
}
hc_htmldir(){
- set -eo pipefail
- hc=$1
- CABAL_PACKAGE=$2
- echo "usr/share/doc/lib${hc}-${CABAL_PACKAGE}-doc/html/"
+ recipe "${FUNCNAME[0]}" "$@"
}
hc_hoogle(){
- set -eo pipefail
- local hc
- hc=$1
- echo "/usr/lib/${hc}-doc/hoogle/"
+ recipe "${FUNCNAME[0]}" "$@"
}
strip_hash(){
- set -eo pipefail
- echo "$1" | sed 's/-................................$//'
+ recipe "${FUNCNAME[0]}" "$@"
}
sort_uniq(){
- set -eo pipefail
- {
- for i in "$@" ; do
- echo $i
- done
- } | LC_ALL=C sort -u | tr "\n" " "
+ recipe "${FUNCNAME[0]}" "$@"
}
dependency(){
- set -eo pipefail
- local package
- local version
- local next_upstream_version
- package=$1
- version=`dpkg-query --showformat='${Version}' -W $package`
- next_upstream_version=`echo $version | sed -e 's/-[^-]*$//' -e 's/$/+/'`
- echo "$package (>= $version), $package (<< $next_upstream_version)"
+ recipe "${FUNCNAME[0]}" "$@"
}
ghc_pkg_field(){
- set -eo pipefail
- hc=$1
- pkg=$2
- field=$3
- ${hc}-pkg --global field ${pkg} ${field} | head -n1
+ recipe "${FUNCNAME[0]}" "$@"
}
providing_package_for_ghc(){
- set -eo pipefail
- local package
- local dep
- local dir
- local dirs
- local lib
- local hc
- local ghcversion=`dpkg-query --showformat '${Version}' --show ghc`
- hc=$1
- if dpkg --compare-versions "${ghcversion}" '>=' 8
- then
- dep=$2
- else
- dep=`strip-hash $2`
- fi
- dirs=`ghc_pkg_field $hc $dep library-dirs | grep -i ^library-dirs | cut -d':' -f 2`
- lib=`ghc_pkg_field $hc $dep hs-libraries | grep -i ^hs-libraries | sed -e 's|hs-libraries: *\([^ ]*\).*|\1|' `
- for dir in $dirs ; do
- if [ -e "${dir}/lib${lib}.a" ] ; then
- package=`dpkg-query -S ${dir}/lib${lib}.a | cut -d':' -f 1`
- continue
- fi
- done
- echo $package
+ recipe "${FUNCNAME[0]}" "$@"
}
providing_package_for_ghc_prof(){
- set -eo pipefail
- local package
- local dep
- local dir
- local dirs
- local lib
- local hc
- local ghcversion=`dpkg-query --showformat '${Version}' --show ghc`
- hc=$1
- if dpkg --compare-versions "${ghcversion}" '>=' 8
- then
- dep=$2
- else
- dep=`strip-hash $2`
- fi
- dirs=`ghc_pkg_field $hc $dep library-dirs | grep -i ^library-dirs | cut -d':' -f 2`
- lib=`ghc_pkg_field $hc $dep hs-libraries | grep -i ^hs-libraries | sed -e 's|hs-libraries: *\([^ ]*\).*|\1|' `
- for dir in $dirs ; do
- if [ -e "${dir}/lib${lib}_p.a" ] ; then
- package=`dpkg-query -S ${dir}/lib${lib}_p.a | cut -d':' -f 1`
- continue
- fi
- done
- echo $package
+ recipe "${FUNCNAME[0]}" "$@"
}
cabal_package_ids(){
- set -eo pipefail
- local pkg
- local package_ids
- local ghcpkg
- ghcpkg="`tmp_package_db $@`"
- until [ -z "$1" ]
- do
- pkg="`basename "$1" .conf`"
- package_ids="$package_ids `${ghcpkg} --simple-output field "${pkg}" id`"
- shift
- done
- echo $package_ids
+ recipe "${FUNCNAME[0]}" "$@"
}
cabal_depends(){
- set -eo pipefail
- local pkg
- local dep
- local depends
- local final_depends
- local ghcpkg
- ghcpkg="`tmp_package_db $@`"
- until [ -z "$1" ]
- do
- pkg="`basename "$1" .conf`"
- depends="$depends `${ghcpkg} --simple-output field "${pkg}" depends`"
- shift
- done
- for dep in `sort_uniq $depends` ; do
- # The package is not mentioned in the ignored package list with the same version
- # or mentioned without any version in the ignored package list?
- if echo " $ignores " | grep -qv " $dep " &&
- echo " $ignores " | grep -qv " `echo $dep | sed s%-[0-9][.0-9a-zA-Z]*$%%` " ;
- then
- final_depends="$final_depends $dep"
- fi
- done
- echo $final_depends
+ recipe "${FUNCNAME[0]}" "$@"
}
hashed_dependency(){
- set -eo pipefail
- local hc
- local type
- local pkgid
- local virpkg
- local ghcpkg
- hc=$1
- type=$2
- pkgid=$3
- ghcpkg="`usable_ghc_pkg`"
- virtual_pkg=`package_id_to_virtual_package "${hc}" "$type" $pkgid "${ghcpkg}"`
- # As a transition measure, check if dpkg knows about this virtual package
- if dpkg-query -W $virtual_pkg >/dev/null 2>/dev/null;
- then
- echo $virtual_pkg
- fi
+ recipe "${FUNCNAME[0]}" "$@"
}
depends_for_ghc(){
- set -eo pipefail
- local dep
- local packages
- local pkgid
- local hc
- hc=$1
- shift
- for pkgid in `cabal_depends $@` ; do
- dep=`hashed_dependency ${hc} dev $pkgid`
- if [ -z "$dep" ]
- then
- pkg=`providing_package_for_ghc $hc $pkgid`
- if [ -n "$pkg" ]
- then
- dep=`dependency $pkg`
- packages="$packages, $dep"
- else
- echo "WARNING: No Debian package provides haskell package $pkgid." >&2
- fi
- else
- packages="$packages, $dep"
- fi
- done
-
- echo $packages | sed -e 's/^,[ ]*//'
+ recipe "${FUNCNAME[0]}" "$@"
}
depends_for_ghc_prof(){
- set -eo pipefail
- local dep
- local packages
- local pkgid
- local hc
- hc=$1
- shift
- for pkgid in `cabal_depends $@` ; do
- dep=`hashed_dependency ${hc} prof $pkgid`
- if [ -z "$dep" ]
- then
- pkg=`providing_package_for_ghc_prof $hc $pkgid`
- if [ -n "$pkg" ]
- then
- dep=`dependency $pkg`
- packages="$packages, $dep"
- else
- echo "WARNING: No Debian package provides haskell package $pkgid." >&2
- fi
- else
- packages="$packages, $dep"
- fi
- done
-
- echo $packages | sed -e 's/^,[ ]*//'
+ recipe "${FUNCNAME[0]}" "$@"
}
usable_ghc_pkg() {
- set -eo pipefail
- local ghcpkg
- local version
- if [ -x inplace/bin/ghc-pkg ]
- then
- # We are building ghc and need to use the new ghc-pkg
- ghcpkg="inplace/bin/ghc-pkg"
- version="`dpkg-parsechangelog -S Version`"
- else
- ghcpkg="ghc-pkg"
- version="`dpkg-query --showformat '${Version}' --show ghc`"
- fi
- # ghc-pkg prior to version 8 is unusable for our purposes.
- if dpkg --compare-versions "$version" '>=' 8
- then
- echo "${ghcpkg}"
- fi
+ recipe "${FUNCNAME[0]}" "$@"
}
tmp_package_db() {
- set -eo pipefail
- local ghcpkg
- ghcpkg="`usable_ghc_pkg`"
- if [ -n "${ghcpkg}" ]
- then
- if [ ! -f debian/tmp-db/package.cache ]
- then
- mkdir debian/tmp-db
- cp $@ debian/tmp-db/
- # Silence GHC 8.4's "ignoring (possibly broken) abi-depends field
- # for packages" warning. See also, https://ghc.haskell.org/trac/ghc/ticket/14381
- $ghcpkg --package-db debian/tmp-db/ recache >/dev/null
- fi
- echo "${ghcpkg} --package-db debian/tmp-db"
- fi
+ recipe "${FUNCNAME[0]}" "$@"
}
provides_for_ghc(){
- set -eo pipefail
- local hc
- local dep
- local packages
- hc=$1
- shift
- ghcpkg="`tmp_package_db $@`"
- for package_id in `cabal_package_ids $@` ; do
- packages="$packages, `package_id_to_virtual_package "${hc}" dev $package_id "${ghcpkg}"`"
- done
- echo $packages | sed -e 's/^,[ ]*//'
+ recipe "${FUNCNAME[0]}" "$@"
}
provides_for_ghc_prof(){
- set -eo pipefail
- local hc
- local dep
- local packages
- hc=$1
- shift
- ghcpkg="`tmp_package_db $@`"
- for package_id in `cabal_package_ids $@` ; do
- packages="$packages, `package_id_to_virtual_package "${hc}" prof $package_id "${ghcpkg}"`"
- done
- echo $packages | sed -e 's/^,[ ]*//'
+ recipe "${FUNCNAME[0]}" "$@"
}
package_id_to_virtual_package(){
- set -eo pipefail
- local hc
- local type
- local pkgid
- local ghcpkg
- hc="$1"
- type="$2"
- pkgid="$3"
- ghcpkg="$4"
- if [ -n "$ghcpkg" ]
- then
- name=`${ghcpkg} --simple-output --unit-id field "${pkgid}" name`
- version=`${ghcpkg} --simple-output --unit-id field "${pkgid}" version`
- abi=`${ghcpkg} --simple-output --unit-id field "${pkgid}" abi | cut -c1-5`
- echo "lib${hc}-${name}-${type}-${version}-${abi}" | tr A-Z a-z
- else
- # We don't have a usable ghc-pkg, so we fall back to parsing the package id.
- echo ${pkgid} | tr A-Z a-z | \
- grep '[a-z0-9]\+-[0-9\.]\+-................................' | \
- perl -pe 's/([a-z0-9-]+)-([0-9\.]+)-(.....).........................../lib'${hc}'-\1-'$type'-\2-\3/'
- fi
+ recipe "${FUNCNAME[0]}" "$@"
}
depends_for_hugs(){
- set -eo pipefail
- local version
- local upstream_version
- version=`dpkg-query --showformat='${Version}' -W hugs`
- upstream_version=`echo $version | sed -e 's/-[^-]*$//'`
- echo "hugs (>= $upstream_version)"
+ recipe "${FUNCNAME[0]}" "$@"
}
find_config_for_ghc(){
- set -eo pipefail
- local f
- local pkg
- pkg=$1
- pkgdir=`package_pkgdir ${pkg}`
- case "$pkg" in
- ghc-prof)
- pkg=ghc
- ;;
- *-prof)
- pkg=`echo $pkg | sed -e 's/-prof$/-dev/'`
- ;;
- *)
- ;;
- esac
- for f in debian/$pkg/${pkgdir}/*.conf ; do
- if [ -f "$f" ] ; then
- echo $f
- echo " "
- fi
- done
+ recipe "${FUNCNAME[0]}" "$@"
}
clean_recipe(){
- set -eo pipefail
- # local PS5=$PS4; PS4=" + clean_recipe> "; set -x
- [ ! -x "${DEB_SETUP_BIN_NAME}" ] || run ${DEB_SETUP_BIN_NAME} clean
- run rm -rf dist dist-ghc dist-ghcjs dist-hugs ${DEB_SETUP_BIN_NAME} Setup.hi Setup.ho Setup.o .*config*
- run rm -f configure-ghc-stamp configure-ghcjs-stamp build-ghc-stamp build-ghcjs-stamp build-hugs-stamp build-haddock-stamp
- run rm -rf debian/tmp-inst-ghc debian/tmp-inst-ghcjs
- run rm -f debian/extra-depends-ghc debian/extra-depends-ghcjs
- if [ -f ${DEB_LINTIAN_OVERRIDES_FILE} ] ; then
- run sed -i '/binary-or-shlib-defines-rpath/ d' ${DEB_LINTIAN_OVERRIDES_FILE}
- run find ${DEB_LINTIAN_OVERRIDES_FILE} -empty -delete;
- fi
-
- run rm -f ${MAKEFILE}
- run rm -rf debian/dh_haskell_shlibdeps
- run rm -rf debian/tmp-db
- # PS4=$PS5
+ recipe "${FUNCNAME[0]}" "$@"
}
make_setup_recipe(){
- set -eo pipefail
- # local PS5=$PS4; PS4=" + make_setup_recipe> "; set -x
- for setup in Setup.lhs Setup.hs
- do
- if test -e $setup
- then
- run ghc --make $setup -o ${DEB_SETUP_BIN_NAME}
- exit 0
- fi
- done
- # Having a Setup.hs is considered good practice, but there are a few
- # Haskell packages that don't, since cabal does not use it for build types
- # other than 'Custom'. Find out the build type and use the corresponding
- # standardized Setup.hs file. For more information, see
- # https://www.haskell.org/cabal/users-guide/developing-packages.html#pkg-field-build-type
- if grep -qi '^build-type: \+Simple' ${CABAL_PACKAGE}.cabal; then
- setup="/usr/share/haskell-devscripts/Setup-Simple.hs"
- elif grep -qi 'build-type: \+Configure' ${CABAL_PACKAGE}.cabal; then
- setup="/usr/share/haskell-devscripts/Setup-Configure.hs"
- elif grep -qi 'build-type: \+Make' ${CABAL_PACKAGE}.cabal; then
- setup="/usr/share/haskell-devscripts/Setup-Make.hs"
- else
- echo "Could not find a suitable Setup.hs file" >&2
- exit 1
- fi
- run ghc --make $setup -o ${DEB_SETUP_BIN_NAME} -outputdir debian/tmp-setup-hs
- # PS4=$PS5
+ recipe "${FUNCNAME[0]}" "$@"
}
configure_recipe(){
- set -eo pipefail
- # local PS5=$PS4; PS4=" + configure_recipe> "; set -x
-
- # dak gets all neurotic about file timestamps older than 1975
- # new tarballs from Hackage have files with mtimes at the
- # beginning of the epoch, so work around this pair of silliness
- # by setting old mtimes to 1998
- reftime=$(mktemp)
- touch -d "1975-01-01 UTC" "${reftime}"
- find . \! -newer "${reftime}" -exec touch -d "1998-01-01 UTC" {} \;
- rm "${reftime}"
-
- hc=`packages_hc`
-
- ENABLE_PROFILING=""
- for i in ${DEB_PACKAGES}; do
- pkg_ext="`package_ext $i`"
- if [ "$pkg_ext" == "prof" ]; then
- ENABLE_PROFILING="--enable-library-profiling"
- break
- fi
- done
- local GHC_OPTIONS
- for i in `dpkg-buildflags --get LDFLAGS`
- do
- GHC_OPTIONS="$GHC_OPTIONS --ghc-option=-optl$i"
- done
-
- # DEB_SETUP_GHC_CONFIGURE_ARGS can contain multiple arguments with their own quoting,
- # so run this through eval
- eval run ${DEB_SETUP_BIN_NAME} \
- configure "--${hc}" \
- -v2 \
- --package-db=/`hc_pkgdir ${hc}` \
- --prefix=/`hc_prefix ${hc}` \
- --libdir=/`hc_libdir ${hc}` \
- --libexecdir=/usr/lib \
- --builddir=dist-${hc} \
- ${GHC_OPTIONS} \
- --haddockdir=/`hc_docdir ${hc} ${CABAL_PACKAGE}-${CABAL_VERSION}` \
- --datasubdir=${CABAL_PACKAGE}\
- --htmldir=/`hc_htmldir ${hc} ${CABAL_PACKAGE}` \
- ${ENABLE_PROFILING} \
- ${NO_GHCI_FLAG} \
- ${DEB_SETUP_GHC6_CONFIGURE_ARGS} \
- ${DEB_SETUP_GHC_CONFIGURE_ARGS} \
- ${OPTIMIZATION} \
- ${TESTS}
- # PS4=$PS5
+ recipe "${FUNCNAME[0]}" "$@"
}
build_recipe(){
- set -eo pipefail
- # local PS5=$PS4; PS4=" + build_recipe> "; set -x
- hc=`packages_hc`
- run ${DEB_SETUP_BIN_NAME} build --builddir=dist-${hc}
- # PS4=$PS5
+ recipe "${FUNCNAME[0]}" "$@"
}
check_recipe(){
- set -eo pipefail
- # local PS5=$PS4; PS4=" + check_recipe> "; set -x
- hc=`packages_hc`
- run ${DEB_SETUP_BIN_NAME} test --builddir=dist-${hc} --show-details=direct
- # PS4=$PS5
+ recipe "${FUNCNAME[0]}" "$@"
}
haddock_recipe(){
- set -eo pipefail
- # local PS5=$PS4; PS4=" + haddock_recipe> "; set -x
- hc=`packages_hc`
- haddock=`hc_haddock ${hc}`
- if [ -x /usr/bin/${haddock} ] && \
- ! run ${DEB_SETUP_BIN_NAME} haddock --builddir=dist-${hc} --with-haddock=/usr/bin/${haddock} --with-ghc=${hc} --verbose=2 ${DEB_HADDOCK_OPTS} ; then
- echo "Haddock failed (no modules?), refusing to create empty documentation package."
- exit 1
- fi
- # PS4=$PS5
+ recipe "${FUNCNAME[0]}" "$@"
}
extra_depends_recipe(){
- set -eo pipefail
- # local PS5=$PS4; PS4=" + extra_depends_recipe> "; set -x
- hc=$1
- pkg_config=$(LC_ALL=C.UTF-8 ${DEB_SETUP_BIN_NAME} register --builddir=dist-${hc} --gen-pkg-config --verbose=verbose+nowrap | sed -r -n '/^Creating package registration file: /s///p')
- run dh_haskell_extra_depends ${hc} $pkg_config
- rm $pkg_config
- # PS4=$PS5
+ recipe "${FUNCNAME[0]}" "$@"
}
install_dev_recipe(){
- set -eo pipefail
- # local PS5=$PS4; PS4=" + install_dev_recipe> "; set -x
- PKG=$1
-
- hc=`package_hc ${PKG}`
- libdir=`package_libdir ${PKG}`
- pkgdir=`package_pkgdir ${PKG}`
-
- ( run cd debian/tmp-inst-${hc} ; run mkdir -p ${libdir} ; run find ${libdir}/ \
- \( ! -name "*_p.a" ! -name "*.p_hi" ! -type d \) \
- -exec install -Dm 644 '{}' ../${PKG}/'{}' ';' )
- pkg_config=$(LC_ALL=C.UTF-8 ${DEB_SETUP_BIN_NAME} register --builddir=dist-${hc} --gen-pkg-config --verbose=verbose+nowrap | sed -r -n '/^Creating package registration file: /s///p')
- if [ "${HASKELL_HIDE_PACKAGES}" ]; then sed -i 's/^exposed: True$/exposed: False/' $pkg_config; fi
- run install -Dm 644 $pkg_config debian/${PKG}/${pkgdir}/$pkg_config
- run rm -f $pkg_config
- if [ "z${DEB_GHC_EXTRA_PACKAGES}" != "z" ] ; then
- EP_DIR=debian/${PKG}/usr/lib/haskell-packages/extra-packages
- run mkdir -p $EP_DIR
- echo "${DEB_GHC_EXTRA_PACKAGES}" > ${EP_DIR}/${CABAL_PACKAGE}-${CABAL_VERSION}
- fi
-
- grep -s binary-or-shlib-defines-rpath ${DEB_LINTIAN_OVERRIDES_FILE} \
- || echo binary-or-shlib-defines-rpath >> ${DEB_LINTIAN_OVERRIDES_FILE}
- run dh_haskell_provides -p${PKG}
- run dh_haskell_depends -p${PKG}
- run dh_haskell_shlibdeps -p${PKG}
- # PS4=$PS5
+ recipe "${FUNCNAME[0]}" "$@"
}
install_prof_recipe(){
- set -eo pipefail
- # local PS5=$PS4; PS4=" + install_prof_recipe> "; set -x
- PKG=$1
- libdir=`package_libdir ${PKG}`
- ( run cd debian/tmp-inst-`package_hc ${PKG}`
- run mkdir -p ${libdir}
- run find ${libdir}/ \
- ! \( ! -name "*_p.a" ! -name "*.p_hi" \) \
- -exec install -Dm 644 '{}' ../${PKG}/'{}' ';' )
- run dh_haskell_provides -p${PKG}
- run dh_haskell_depends -p${PKG}
- # PS4=$PS5
+ recipe "${FUNCNAME[0]}" "$@"
}
install_doc_recipe(){
- set -eo pipefail
- # local PS5=$PS4; PS4=" + install_doc_recipe> "; set -x
- PKG=$1
- hc=`package_hc ${PKG}`
- pkgid=${CABAL_PACKAGE}-${CABAL_VERSION}
- docdir=`hc_docdir ${hc} ${pkgid}`
- htmldir=`hc_htmldir ${hc} ${CABAL_PACKAGE}`
- hoogle=`hc_hoogle ${hc}`
- run mkdir -p debian/${PKG}/${htmldir}
- ( run cd debian/tmp-inst-${hc}/ ;
- run find ./${htmldir} \
- ! -name "*.haddock" ! -type d -exec install -Dm 644 '{}' \
- ../${PKG}/'{}' ';' )
- run mkdir -p debian/${PKG}/${docdir}
- [ 0 = `ls debian/tmp-inst-${hc}/${docdir}/ 2>/dev/null | wc -l` ] ||
- run cp -r debian/tmp-inst-${hc}/${docdir}/*.haddock debian/${PKG}/${docdir}
- if [ "${DEB_ENABLE_HOOGLE}" = "yes" ]
- then
- # We cannot just invoke dh_link here because that acts on
- # either libghc-*-dev or all the binary packages, neither of
- # which is desirable (see dh_link (1)). So we just create a
- # (policy-compliant) symlink ourselves
- source="debian/${PKG}/${htmldir}/${CABAL_PACKAGE}.txt"
- dest=debian/${PKG}${hoogle}${PKG}.txt
- if [ -f ${source} ]; then
- run mkdir -p `dirname $dest`
- run ln -rs -T $source $dest
- fi
- fi
- run dh_haskell_depends -p${PKG}
- # PS4=$PS5
-}
-
-if ! command -v grep-dctrl > /dev/null; then
- echo "grep-dctrl is missing" >&2
- exit 1
-fi
-
-args=
-ignores=
-files=
-until [ -z "$1" ]
-do
- case "$1" in
- -X*)
- pkg=${1##-X}
- ignores="$ignores $pkg"
- ;;
-
- --exclude=*)
- pkg=${1##--exclude=}
- ignores="$ignores $pkg"
- ;;
-
- -*)
- args="$args $1"
- ;;
- *)
- if [ -f $1 ] ; then
- files="$files $1"
- else
- echo "Installed package description file $1 can not be found" >&2
- exit 1
- fi
- ;;
- esac
- shift
-done
+ recipe "${FUNCNAME[0]}" "$@"
+}
=====================================
debian/control
=====================================
@@ -22,6 +22,12 @@ Depends: dctrl-tools
, ${misc:Depends}
, html-xml-utils
, ghc-haddock
+ , libconst-fast-perl
+ , libdatetime-perl
+ , libipc-run3-perl
+ , liblist-someutils-perl
+ , libpath-tiny-perl
+ , libunicode-utf8-perl
Breaks: haskell-devscripts (<= 0.10.2.3)
Replaces: haskell-devscripts (<= 0.10.2.3)
Suggests: haskell-devscripts
=====================================
debian/haskell-devscripts-minimal.install
=====================================
@@ -5,6 +5,7 @@ dh_haskell_extra_depends usr/bin/
dh_haskell_blurbs usr/bin/
Dh_Haskell.sh usr/share/haskell-devscripts/
hlibrary.mk usr/share/cdbs/1/class
+lib/* usr/share/perl5/
Setup-Make.hs usr/share/haskell-devscripts/
Setup-Simple.hs usr/share/haskell-devscripts/
Setup-Configure.hs usr/share/haskell-devscripts/
=====================================
dh_haskell_blurbs
=====================================
@@ -6,10 +6,48 @@
set -e
+. /usr/share/haskell-devscripts/Dh_Haskell.sh
+
DEB_DEFAULT_COMPILER=$1
shift
-. /usr/share/haskell-devscripts/Dh_Haskell.sh
+args=
+ignores=
+files=
+until [ -z "$1" ]
+do
+ case "$1" in
+ -X*)
+ pkg=${1##-X}
+ ignores="$ignores $pkg"
+ ;;
+
+ --exclude=*)
+ pkg=${1##--exclude=}
+ ignores="$ignores $pkg"
+ ;;
+
+ -*)
+ args="$args $1"
+ ;;
+ *)
+ if [ -f $1 ] ; then
+ files="$files $1"
+ else
+ echo "Installed package description file $1 can not be found" >&2
+ exit 1
+ fi
+ ;;
+ esac
+ shift
+done
+
+export DH_EXCLUDES="$ignores"
+
+if ! command -v grep-dctrl > /dev/null; then
+ echo "grep-dctrl is missing" >&2
+ exit 1
+fi
# PS4=" + dh_haskell_blurbs> "
# set -x
=====================================
dh_haskell_depends
=====================================
@@ -56,6 +56,39 @@ set -e
. /usr/share/haskell-devscripts/Dh_Haskell.sh
+args=
+ignores=
+files=
+until [ -z "$1" ]
+do
+ case "$1" in
+ -X*)
+ pkg=${1##-X}
+ ignores="$ignores $pkg"
+ ;;
+
+ --exclude=*)
+ pkg=${1##--exclude=}
+ ignores="$ignores $pkg"
+ ;;
+
+ -*)
+ args="$args $1"
+ ;;
+ *)
+ if [ -f $1 ] ; then
+ files="$files $1"
+ else
+ echo "Installed package description file $1 can not be found" >&2
+ exit 1
+ fi
+ ;;
+ esac
+ shift
+done
+
+export DH_EXCLUDES="$ignores"
+
# PS4=" + dh_haskell_depends> "
# set -x
=====================================
dh_haskell_extra_depends
=====================================
@@ -54,10 +54,43 @@
set -e
+. /usr/share/haskell-devscripts/Dh_Haskell.sh
+
hc=$1
shift
-. /usr/share/haskell-devscripts/Dh_Haskell.sh
+args=
+ignores=
+files=
+until [ -z "$1" ]
+do
+ case "$1" in
+ -X*)
+ pkg=${1##-X}
+ ignores="$ignores $pkg"
+ ;;
+
+ --exclude=*)
+ pkg=${1##--exclude=}
+ ignores="$ignores $pkg"
+ ;;
+
+ -*)
+ args="$args $1"
+ ;;
+ *)
+ if [ -f $1 ] ; then
+ files="$files $1"
+ else
+ echo "Installed package description file $1 can not be found" >&2
+ exit 1
+ fi
+ ;;
+ esac
+ shift
+done
+
+export DH_EXCLUDES="$ignores"
# PS4=" + dh_haskell_extra_depends> "
# set -x
=====================================
dh_haskell_provides
=====================================
@@ -62,6 +62,39 @@ else
. /usr/share/haskell-devscripts/Dh_Haskell.sh
fi
+args=
+ignores=
+files=
+until [ -z "$1" ]
+do
+ case "$1" in
+ -X*)
+ pkg=${1##-X}
+ ignores="$ignores $pkg"
+ ;;
+
+ --exclude=*)
+ pkg=${1##--exclude=}
+ ignores="$ignores $pkg"
+ ;;
+
+ -*)
+ args="$args $1"
+ ;;
+ *)
+ if [ -f $1 ] ; then
+ files="$files $1"
+ else
+ echo "Installed package description file $1 can not be found" >&2
+ exit 1
+ fi
+ ;;
+ esac
+ shift
+done
+
+export DH_EXCLUDES="$ignores"
+
# PS4=" + dh_haskell_provides> "
# set -x
=====================================
dh_haskell_shlibdeps
=====================================
@@ -27,6 +27,39 @@ set -e
. /usr/share/haskell-devscripts/Dh_Haskell.sh
+args=
+ignores=
+files=
+until [ -z "$1" ]
+do
+ case "$1" in
+ -X*)
+ pkg=${1##-X}
+ ignores="$ignores $pkg"
+ ;;
+
+ --exclude=*)
+ pkg=${1##--exclude=}
+ ignores="$ignores $pkg"
+ ;;
+
+ -*)
+ args="$args $1"
+ ;;
+ *)
+ if [ -f $1 ] ; then
+ files="$files $1"
+ else
+ echo "Installed package description file $1 can not be found" >&2
+ exit 1
+ fi
+ ;;
+ esac
+ shift
+done
+
+export DH_EXCLUDES="$ignores"
+
# PS4=" + dh_haskell_shlibdeps> "
# set -x
=====================================
lib/Debian/Debhelper/Buildsystem/Haskell/Recipes.pm
=====================================
@@ -0,0 +1,1268 @@
+# Copyright © 2022 Felix Lechner <felix.lechner at lease-up.com>
+#
+# 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, you can find it on the World Wide
+# Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+package Debian::Debhelper::Buildsystem::Haskell::Recipes;
+
+use v5.20;
+use warnings;
+use utf8;
+
+use Exporter qw(import);
+
+our @EXPORT_OK;
+
+BEGIN {
+
+ @EXPORT_OK = qw(
+ run
+ cpu
+ os
+ ghcjs_version
+ ghcjs_ghc_version
+ package_prefix
+ package_hc
+ package_ext
+ packages_hc
+ hc_libdir
+ package_libdir
+ hc_pkgdir
+ package_pkgdir
+ hc_prefix
+ hc_haddock
+ hc_docdir
+ hc_htmldir
+ hc_hoogle
+ strip_hash
+ sort_uniq
+ dependency
+ ghc_pkg_field
+ providing_package_for_ghc
+ providing_package_for_ghc_prof
+ cabal_package_ids
+ cabal_depends
+ hashed_dependency
+ depends_for_ghc
+ depends_for_ghc_prof
+ usable_ghc_pkg
+ tmp_package_db
+ provides_for_ghc
+ provides_for_ghc_prof
+ package_id_to_virtual_package
+ depends_for_hugs
+ find_config_for_ghc
+ clean_recipe
+ make_setup_recipe
+ configure_recipe
+ build_recipe
+ check_recipe
+ haddock_recipe
+ extra_depends_recipe
+ install_dev_recipe
+ install_prof_recipe
+ install_doc_recipe
+ );
+}
+
+use Const::Fast;
+use Cwd;
+use Date::Parse qw(str2time);
+use File::Basename;
+use IPC::Run3;
+use List::SomeUtils qw(uniq any first_value);
+use Path::Tiny;
+use Unicode::UTF8 qw(encode_utf8 decode_utf8);
+
+const my $EMPTY => q{};
+const my $SPACE => q{ };
+const my $PLUS => q{+};
+const my $HYPHEN => q{-};
+const my $COMMA => q{,};
+const my $SEMICOLON => q{;};
+const my $LESS_THAN => q{<};
+const my $DOUBLE_LESS_THAN => $LESS_THAN x 2;
+const my $NEWLINE => qq{\n};
+
+const my $WAIT_STATUS_SHIFT => 8;
+
+const my $MINIMUM_GHC_VERSION => 8;
+const my $CABAL_VERSION_IMPLYING_SIMPLE_BUILDS => 2.2;
+
+=head1 NAME
+
+Debian::Debhelper::Buildsystem::Haskell::Recipes -- Recipes for the Haskell build system in Debhelper
+
+=head1 SYNOPSIS
+
+ Debian::Debhelper::Buildsystem::Haskell::Recipes;
+
+=head1 DESCRIPTION
+
+A library with recipes for the Haskell build system in Debhelper.
+
+=head1 SUBROUTINES
+
+=over 4
+
+=item run_quiet
+
+=cut
+
+sub run_quiet {
+ my (@command) = @_;
+
+ my @command_bytes = map { encode_utf8($_) } @command;
+
+ my $stdout_bytes;
+ my $stderr_bytes;
+ run3(\@command_bytes, \undef, \$stdout_bytes, \$stderr_bytes);
+
+ my $wait_status = $?;
+ my $exitcode = ($wait_status >> $WAIT_STATUS_SHIFT);
+
+ # already in UTF-8
+ die encode_utf8("Non-zero exit code $exitcode.")
+ . $NEWLINE
+ . $stdout_bytes
+ . $stderr_bytes
+ if $exitcode;
+
+ my $output = decode_utf8($stdout_bytes // $EMPTY);
+ chomp $output;
+
+ return $output;
+}
+
+=item run
+
+=cut
+
+sub run {
+ my (@command) = @_;
+
+ my @filtered = grep { length } @command;
+
+ say {*STDERR} encode_utf8("Running @filtered")
+ if !$ENV{DH_QUIET} || $ENV{DH_VERBOSE};
+
+ my $output = run_quiet(@filtered);
+
+ say {*STDERR} encode_utf8($output)
+ if !$ENV{DH_QUIET} || $ENV{DH_VERBOSE};
+
+ return $output;
+}
+
+=item cpu
+
+=cut
+
+sub cpu {
+ my () = @_;
+
+ my $output = run(qw{ghc -e}, 'putStr System.Info.arch');
+
+ return $output;
+}
+
+=item os
+
+=cut
+
+sub os {
+ my () = @_;
+
+ my $output = run(qw{ghc -e}, 'putStr System.Info.os');
+
+ return $output;
+}
+
+=item ghcjs_version
+
+=cut
+
+sub ghcjs_version {
+ my () = @_;
+
+ my $output = run(qw{ghcjs --numeric-ghcjs-version});
+
+ return $output;
+}
+
+=item ghcjs_ghc_version
+
+=cut
+
+sub ghcjs_ghc_version {
+ my () = @_;
+
+ my $output = run(qw{ghcjs --numeric-ghc-version});
+
+ return $output;
+}
+
+=item package_prefix
+
+=cut
+
+sub package_prefix {
+ my ($installable) = @_;
+
+ my $prefix = $installable;
+
+ # strip hackage name
+ $prefix =~ s{ - .* $}{}x;
+
+ return $prefix;
+}
+
+=item package_hc
+
+=cut
+
+sub package_hc {
+ my ($installable) = @_;
+
+ return 'ghc'
+ if $installable =~ m{^ ghc (:? -prof )? $};
+
+ my $compiler = $installable;
+
+ # strip hackage name
+ $compiler =~ s{ - .* $}{}x;
+
+ # strip lib prefix
+ $compiler =~ s{^ lib }{}x;
+
+ return $compiler;
+}
+
+=item package_ext
+
+=cut
+
+sub package_ext {
+ my ($installable) = @_;
+
+ return 'dev'
+ if $installable eq 'ghc';
+
+ return 'prof'
+ if $installable eq 'ghc-prof';
+
+ my $suffix = $installable;
+
+ # strip hackage name
+ $suffix =~ s{^ .* - }{}x;
+
+ return $suffix;
+}
+
+=item packages_hc
+
+=cut
+
+sub packages_hc {
+ my () = @_;
+
+ # fix sort order
+ local $ENV{LC_ALL} = 'C';
+
+ # should be in UTF-8
+ my @installables = split($SPACE, $ENV{DEB_PACKAGES} // $EMPTY);
+
+ my @compilers = uniq map { package_hc($_) } @installables;
+
+ die encode_utf8(
+ 'Multiple compilers not supported: ' . join($SPACE, (sort @compilers)))
+ if @compilers > 1;
+
+ return $ENV{DEB_DEFAULT_COMPILER}
+ if !@compilers;
+
+ return $compilers[0];
+}
+
+=item hc_libdir
+
+=cut
+
+sub hc_libdir {
+ my ($compiler) = @_;
+
+ return 'usr/lib/haskell-packages/ghc/lib'
+ if $compiler eq 'ghc';
+
+ return 'usr/lib/ghcjs/.cabal/lib'
+ if $compiler eq 'ghcjs';
+
+ die encode_utf8("Don't know package_libdir for $compiler");
+}
+
+=item package_libdir
+
+=cut
+
+sub package_libdir {
+ my ($installable) = @_;
+
+ my $compiler = package_hc($installable);
+
+ return hc_libdir($compiler);
+}
+
+=item hc_pkgdir
+
+=cut
+
+sub hc_pkgdir {
+ my ($compiler) = @_;
+
+ return 'var/lib/ghc/package.conf.d'
+ if $compiler eq 'ghc';
+
+ if ($compiler eq 'ghcjs') {
+
+ my $quadruplet
+ = cpu()
+ . $HYPHEN
+ . os()
+ . $HYPHEN
+ . ghcjs_version()
+ . $HYPHEN
+ . ghcjs_ghc_version();
+
+ return "usr/lib/ghcjs/.ghcjs/$quadruplet/ghcjs/package.conf.d";
+ }
+
+ die encode_utf8("Don't know pkgdir for $compiler");
+}
+
+=item package_pkgdir
+
+=cut
+
+sub package_pkgdir {
+ my ($installable) = @_;
+
+ my $compiler = package_hc($installable);
+
+ return hc_pkgdir($compiler);
+}
+
+=item hc_prefix
+
+=cut
+
+sub hc_prefix {
+ my ($compiler) = @_;
+
+ return 'usr'
+ if $compiler eq 'ghc';
+
+ return 'usr/lib/ghcjs'
+ if $compiler eq 'ghcjs';
+
+ die encode_utf8("Don't know prefix for $compiler");
+}
+
+=item hc_haddock
+
+=cut
+
+sub hc_haddock {
+ my ($compiler) = @_;
+
+ return 'haddock'
+ if $compiler eq 'ghc';
+
+ return 'haddock-ghcjs'
+ if $compiler eq 'ghcjs';
+
+ die encode_utf8("Don't know haddock command for $compiler");
+}
+
+=item hc_docdir
+
+=cut
+
+sub hc_docdir {
+ my ($compiler, $hackage_name_version) = @_;
+
+ return "usr/lib/$compiler-doc/haddock/$hackage_name_version/";
+}
+
+=item hc_htmldir
+
+=cut
+
+sub hc_htmldir {
+ my ($compiler, $hackage_name) = @_;
+
+ $ENV{CABAL_PACKAGE} = $hackage_name;
+
+ return "usr/share/doc/lib$compiler-$hackage_name-doc/html/";
+}
+
+=item hc_hoogle
+
+=cut
+
+sub hc_hoogle {
+ my ($compiler) = @_;
+
+ return "/usr/lib/$compiler-doc/hoogle/";
+}
+
+=item strip_hash
+
+=cut
+
+sub strip_hash {
+ my ($with_hash) = @_;
+
+ my $without_hash = $with_hash;
+ $without_hash =~ s{ - [^-]{32} $}{}x;
+
+ return $without_hash;
+}
+
+=item sort_uniq
+
+=cut
+
+sub sort_uniq {
+ my (@items) = @_;
+
+ # fix sort order
+ local $ENV{LC_ALL} = 'C';
+
+ my @sorted = sort +uniq @items;
+
+ return @sorted;
+}
+
+=item dependency
+
+=cut
+
+sub dependency {
+ my ($installable) = @_;
+
+ my $version
+ = run(qw{dpkg-query --showformat=${Version} --show}, $installable);
+
+ my $next_upstream_version = $version;
+ $next_upstream_version =~ s{ - [^-]* $}{}x;
+ $next_upstream_version .= $PLUS;
+
+ return
+ "$installable (>= $version), $installable (<< $next_upstream_version)";
+}
+
+=item ghc_pkg_field
+
+=cut
+
+sub ghc_pkg_field {
+ my ($compiler, $hackage_name, $field) = @_;
+
+ my $output
+ = run("$compiler-pkg", qw{--global field}, $hackage_name, $field);
+
+ # may not process multi-line fields correctly
+ my ($value) = split($NEWLINE, $output, 2);
+
+ return ($value // $EMPTY);
+}
+
+=item providing_package_for_ghc
+
+=cut
+
+sub providing_package_for_ghc {
+ my ($compiler, $package_id, $extension) = @_;
+
+ $extension //= $EMPTY;
+
+ my $ghc_version= run(qw{dpkg-query --showformat=${Version} --show ghc});
+
+ my $hackage_name;
+ if (
+ system(
+ qw{dpkg --compare-versions}, $ghc_version,
+ $DOUBLE_LESS_THAN, $MINIMUM_GHC_VERSION
+ ) == 0
+ ) {
+ $hackage_name = strip_hash($package_id);
+ } else {
+ $hackage_name = $package_id;
+ }
+
+ my $directory_line
+ = ghc_pkg_field($compiler, $hackage_name, 'library-dirs');
+ my (undef, $directory_list) = split(m{ \s* : \s* }x, $directory_line, 2);
+ my @library_dirs = split(m{ \s* , \s* }x, $directory_list);
+
+ my $library_line = ghc_pkg_field($compiler, $hackage_name, 'hs-libraries');
+ my (undef, $library_list) = split(m{ \s* : \s* }x, $library_line, 2);
+ my @libraries = split(m{ \s* , \s* }x, $library_list);
+
+ # look only at the first one
+ my $library = $libraries[0];
+
+ for my $directory (@library_dirs) {
+
+ my $library_path = "$directory/lib$library$extension.a";
+ next
+ unless -e $library_path;
+
+ my $line = run(qw{dpkg-query --search}, $library_path);
+ my ($installable) = split(m{ \s* : \s* }x, $line, 2);
+
+ return $installable;
+ }
+
+ return ();
+}
+
+=item providing_package_for_ghc_prof
+
+=cut
+
+sub providing_package_for_ghc_prof {
+ my ($compiler, $package_id) = @_;
+
+ return providing_package_for_ghc($compiler, $package_id, '_p');
+}
+
+=item cabal_pkg_ids
+
+=cut
+
+sub cabal_package_ids {
+ my (@configs) = @_;
+
+ my @ghc_pkg = tmp_package_db(@configs);
+
+ my @package_ids;
+ for my $config (@configs) {
+
+ my $name = path($config)->basename(qr{ [.]conf $}x);
+ push(@package_ids,
+ run(@ghc_pkg, qw{--simple-output field}, $name, 'id'));
+ }
+
+ return @package_ids;
+}
+
+=item cabal_depends
+
+=cut
+
+sub cabal_depends {
+ my (@configs) = @_;
+
+ # fix sort order
+ local $ENV{LC_ALL} = 'C';
+
+ my @ghc_pkg = tmp_package_db(@configs);
+
+ my @constraints;
+ for my $config (@configs) {
+
+ my $name = path($config)->basename(qr{ [.]conf $}x);
+ my $depends
+ = run(@ghc_pkg, qw{--simple-output field}, $name, 'depends');
+ push(@constraints, split($SPACE, $depends // $EMPTY));
+ }
+
+ my @have = sort +uniq @constraints;
+ my @exclude_patterns = split($SPACE, $ENV{DH_EXCLUDES} // $EMPTY);
+
+ # not sure this complies with Debhelper expectations
+ # excluded installables matching the patterns with or without version
+ # the versions should probably be dropped by the caller
+ s{ - [0-9] [.0-9a-zA-Z]* $}{}x for @exclude_patterns;
+
+ my @retained;
+ for my $constraint (@have) {
+
+ next
+ if any { $constraint =~ m{\Q$_\E} } @exclude_patterns;
+
+ push(@retained, $constraint);
+ }
+
+ return @retained;
+}
+
+=item hashed_dependency
+
+=cut
+
+sub hashed_dependency {
+ my ($compiler, $type, $package_id) = @_;
+
+ my @ghc_pkg = usable_ghc_pkg();
+ my $virtual_pkg
+ = package_id_to_virtual_package($compiler, $type, $package_id, @ghc_pkg);
+
+ # as a transition measure, check if dpkg knows about this virtual package
+ return $virtual_pkg
+ if system("dpkg-query --show $virtual_pkg > /dev/null 2> /dev/null")== 0;
+
+ return ();
+}
+
+=item composite_constraints
+
+=cut
+
+sub composite_constraints {
+ my ($compiler, $type, @configs) = @_;
+
+ my @package_ids = cabal_depends(@configs);
+
+ my @constraints;
+ for my $package_id (@package_ids) {
+
+ my $constraint = hashed_dependency($compiler, $type, $package_id);
+
+ if (!length $constraint) {
+
+ my $installable= providing_package_for_ghc($compiler, $package_id);
+
+ $constraint = dependency($installable);
+ if (!length $constraint) {
+
+ warn encode_utf8(
+"WARNING: No Debian package provides haskell package $package_id.\n"
+ );
+ next;
+ }
+ }
+
+ push(@constraints, $constraint);
+ }
+
+ return join($COMMA . $SPACE, @constraints);
+}
+
+=item depends_for_ghc_prof
+
+=cut
+
+sub depends_for_ghc {
+ my ($compiler, @configs) = @_;
+
+ return composite_constraints($compiler, 'dev', @configs);
+}
+
+=item depends_for_ghc_prof
+
+=cut
+
+sub depends_for_ghc_prof {
+ my ($compiler, @configs) = @_;
+
+ return composite_constraints($compiler, 'prof', @configs);
+}
+
+=item usable_ghc_pkg
+
+=cut
+
+sub usable_ghc_pkg {
+ my () = @_;
+
+ my @ghc_pkg;
+ my $version;
+
+ my $inplace_ghc_pkg = 'inplace/bin/ghc-pkg';
+ if (-x $inplace_ghc_pkg) {
+
+ # we are building ghc and need to use the new ghc-pkg
+ @ghc_pkg = ($inplace_ghc_pkg);
+ $version = run(qw{dpkg-parsechangelog --show-field Version});
+
+ } else {
+ @ghc_pkg = qw{ghc-pkg};
+ $version= run(qw{dpkg-query --showformat=${Version} --show ghc});
+ }
+
+ # ghc-pkg prior to version 8 is unusable for our purposes.
+ return ()
+ if system(qw{dpkg --compare-versions},
+ $version, $DOUBLE_LESS_THAN, $MINIMUM_GHC_VERSION)== 0;
+
+ return @ghc_pkg;
+}
+
+=item tmp_package_db
+
+=cut
+
+sub tmp_package_db {
+ my (@configs) = @_;
+
+ my @ghc_pkg = usable_ghc_pkg();
+ return ()
+ unless @ghc_pkg;
+
+ if (!-e 'debian/tmp-db/package.cache') {
+
+ run(qw{mkdir debian/tmp-db});
+ run(qw{cp}, @configs, 'debian/tmp-db/');
+
+ # Silence GHC 8.4's warning
+ # "ignoring (possibly broken) abi-depends field for packages"
+ # see also https://ghc.haskell.org/trac/ghc/ticket/14381
+ run(@ghc_pkg, qw{--package-db debian/tmp-db/ recache});
+ }
+
+ return (@ghc_pkg, qw{--package-db debian/tmp-db});
+}
+
+=item composite_provides
+
+=cut
+
+sub composite_provides {
+ my ($compiler, $type, @configs) = @_;
+
+ my @ghc_pkg = tmp_package_db(@configs);
+ my @package_ids = cabal_package_ids(@configs);
+
+ my @virtual;
+ push(@virtual,
+ package_id_to_virtual_package($compiler, $type, $_, @ghc_pkg))
+ for @package_ids;
+
+ return join($COMMA . $SPACE, @virtual);
+}
+
+=item provide_for_ghc
+
+=cut
+
+sub provides_for_ghc {
+ my ($compiler, @configs) = @_;
+
+ return composite_provides($compiler, 'dev', @configs);
+}
+
+=item provide_for_ghc_prof
+
+=cut
+
+sub provides_for_ghc_prof {
+ my ($compiler, @configs) = @_;
+
+ return composite_provides($compiler, 'prof', @configs);
+}
+
+=item package_id_to_virtual_package
+
+=cut
+
+sub package_id_to_virtual_package {
+ my ($compiler, $type, $package_id, @ghc_pkg) = @_;
+
+ my $name;
+ my $version;
+ my $long_abi;
+
+ if (@ghc_pkg) {
+
+ $name = run(@ghc_pkg, qw{--simple-output --unit-id field},
+ $package_id, 'name');
+ $version = run(@ghc_pkg, qw{--simple-output --unit-id field},
+ $package_id, 'version');
+ $long_abi = run(@ghc_pkg, qw{--simple-output --unit-id field},
+ $package_id, 'abi');
+
+ } else {
+
+ # no usable ghc-pkg; parse package id
+ my $lowercase = lc $package_id;
+
+ ($name, $version, $long_abi)
+ = ($lowercase =~ m{^ ([a-z0-9-]+) - ([0-9.]+) - (\S{32}) $}x);
+ }
+
+ # retain only the first five hex digits from abi out of 32
+ my ($short_abi) = ($long_abi =~ m{^ (\S{5}) }x);
+
+ my $virtual = lc "lib$compiler-$name-$type-$version-$short_abi";
+
+ return $virtual;
+}
+
+=item depends_for_hugs
+
+=cut
+
+sub depends_for_hugs {
+ my () = @_;
+
+ my $version= run(qw{dpkg-query --showformat=${Version} --show hugs});
+ my $upstream_version = $version;
+ $upstream_version =~ s{ - [^-]* $}{}x;
+
+ return "hugs (>= $upstream_version)";
+}
+
+=item find_config_for_ghc
+
+=cut
+
+sub find_config_for_ghc {
+ my ($installable) = @_;
+
+ my $pkgdir = package_pkgdir($installable);
+
+ if ($installable =~ s{ - prof $}{}x) {
+
+ $installable .= '-dev'
+ unless $installable eq 'ghc';
+ }
+
+ my @configs = grep { $_->is_file }
+ path("debian/$installable/$pkgdir")->children(qr{ [.]conf $}x);
+
+ return @configs;
+}
+
+=item clean_recipe
+
+=cut
+
+sub clean_recipe {
+ my () = @_;
+
+ run($ENV{DEB_SETUP_BIN_NAME}, qw{clean})
+ if -x $ENV{DEB_SETUP_BIN_NAME};
+
+ run(
+ qw{rm -rf dist dist-ghc dist-ghcjs dist-hugs},
+ $ENV{DEB_SETUP_BIN_NAME},
+ qw{Setup.hi Setup.ho Setup.o},
+ glob('.*config*'));
+ run(
+ qw{rm -f configure-ghc-stamp configure-ghcjs-stamp build-ghc-stamp build-ghcjs-stamp build-hugs-stamp build-haddock-stamp}
+ );
+ run(qw{rm -rf debian/tmp-inst-ghc debian/tmp-inst-ghcjs});
+ run(qw{rm -f debian/extra-depends-ghc debian/extra-depends-ghcjs});
+
+ if (-e $ENV{DEB_LINTIAN_OVERRIDES_FILE}) {
+ run(
+ qw{sed -i},
+ '/binary-or-shlib-defines-rpath/ d',
+ $ENV{DEB_LINTIAN_OVERRIDES_FILE});
+ run('find',$ENV{DEB_LINTIAN_OVERRIDES_FILE},qw{-empty -delete});
+ }
+
+ run(qw{rm -f}, $ENV{MAKEFILE});
+ run(qw{rm -rf debian/dh_haskell_shlibdeps});
+ run(qw{rm -rf debian/tmp-db});
+
+ return;
+}
+
+=item make_setup_recipe
+
+=cut
+
+sub make_setup_recipe {
+ my () = @_;
+
+ my $shipped_setup = first_value { -e } qw{Setup.lhs Setup.hs};
+
+ if (length $shipped_setup) {
+
+ run(qw{ghc --make}, $shipped_setup, '-o',$ENV{DEB_SETUP_BIN_NAME});
+ return;
+ }
+
+# Having a Setup.hs is considered good practice, but there are a few
+# Haskell packages that don't, since cabal does not use it for build types
+# other than 'Custom'. Find out the build type and use the corresponding
+# standardized Setup.hs file. For more information, see
+# https://www.haskell.org/cabal/users-guide/developing-packages.html#pkg-field-build-type
+
+ my $cabal_path = "$ENV{CABAL_PACKAGE}.cabal";
+ my $cabal_contents = path($cabal_path)->slurp_utf8;
+
+ my $cabal_version= first_value { length }
+ ($cabal_contents
+ =~ m{^ cabal-version: (?: \s+ [<>=]+ )? \s+ (\S+) \s* $}mix);
+ die encode_utf8("No cabal-version in $cabal_path")
+ unless length $cabal_version;
+
+ my $build_type= first_value { length }
+ ($cabal_contents =~ m{^ build-type: \s+ (\w+) \s* }mix);
+
+ # https://cabal.readthedocs.io/en/3.4/cabal-package.html#pkg-field-build-type
+ my $default_build_type = 'Simple';
+ $default_build_type = 'Custom'
+ if $cabal_version < $CABAL_VERSION_IMPLYING_SIMPLE_BUILDS
+ || $cabal_contents =~ m{^ custom-setup \s+ }mi;
+
+ $build_type //= $default_build_type;
+
+ my $stock_setup = "/usr/share/haskell-devscripts/Setup-$build_type.hs";
+ die encode_utf8("Could not find a suitable Setup.hs file for $build_type")
+ unless -e $stock_setup;
+
+ run(
+ qw{ghc --make}, $stock_setup, '-o',
+ $ENV{DEB_SETUP_BIN_NAME},
+ qw{-outputdir debian/tmp-setup-hs}
+ );
+
+ return;
+}
+
+=item configure_recipe
+
+=cut
+
+sub configure_recipe {
+ my () = @_;
+
+ # deleted when out of scope
+ my $time_reference = Path::Tiny->tempfile;
+ $time_reference->touch(str2time('1975-01-01', 'UTC'));
+
+ # dak does not like file timestamps older than 1975
+ # new tarballs from Hackage have files with mtimes at the
+ # beginning of the epoch, so set old mtimes to 1998
+ run(
+ qw{find . ! -newer},
+ $time_reference->stringify,
+ qw{-exec touch -d "1998-01-01 UTC" {} ; }
+ );
+
+ my $compiler = packages_hc();
+
+ my @installables = split($SPACE, $ENV{DEB_PACKAGES} // $EMPTY);
+ my @extensions = map { package_ext($_) } @installables;
+
+ my $profiling;
+ $profiling = '--enable-library-profiling'
+ if any { $_ eq 'prof' } @extensions;
+
+ my $ldflags_line = run(qw{dpkg-buildflags --get LDFLAGS});
+ my @ldflags = split($SPACE, $ldflags_line);
+ my @ghc_options = map { "--ghc-option=-optl$_" } @ldflags;
+
+ my $pkgdir = hc_pkgdir($compiler);
+ my $prefix = hc_prefix($compiler);
+ my $libdir = hc_libdir($compiler);
+ my $docdir
+ = hc_docdir($compiler, "$ENV{CABAL_PACKAGE}-$ENV{CABAL_VERSION}");
+ my $htmldir = hc_htmldir($compiler, $ENV{CABAL_PACKAGE});
+
+ # DEB_SETUP_GHC_CONFIGURE_ARGS can contain multiple arguments
+ # with their own quoting so run through shell a expansion
+ my $ghc_configure_args = run_quiet(qw{sh -c echo -n},
+ split($SPACE, $ENV{DEB_SETUP_GHC_CONFIGURE_ARGS} // $EMPTY));
+
+ # the versioned form DEB_SETUP_GHC6_CONFIGURE_ARGS should perhaps be
+ # abandoned in favor of the unversioned DEB_SETUP_GHC_CONFIGURE_ARGS
+
+ run(
+ $ENV{DEB_SETUP_BIN_NAME},
+ 'configure',
+ "--$compiler",
+ '-v2',
+ "--package-db=/$pkgdir",
+ "--prefix=/$prefix",
+ "--libdir=/$libdir",
+ '--libexecdir=/usr/lib',
+ "--builddir=dist-$compiler",
+ @ghc_options,
+ "--haddockdir=/$docdir",
+ "--datasubdir=$ENV{CABAL_PACKAGE}",
+ "--htmldir=/$htmldir",
+ $profiling,
+ $ENV{NO_GHCI_FLAG},
+ split($SPACE, $ENV{DEB_SETUP_GHC6_CONFIGURE_ARGS} // $EMPTY),
+ split($SPACE, $ghc_configure_args // $EMPTY),
+ split($SPACE, $ENV{OPTIMIZATION} // $EMPTY),
+ split($SPACE, $ENV{TESTS} // $EMPTY));
+
+ return;
+}
+
+=item build_recipe
+
+=cut
+
+sub build_recipe {
+ my () = @_;
+
+ my $compiler = packages_hc();
+ my $output
+ = run($ENV{DEB_SETUP_BIN_NAME},'build', "--builddir=dist-$compiler");
+
+ return;
+}
+
+=item check_recipe
+
+=cut
+
+sub check_recipe {
+ my () = @_;
+
+ my $compiler = packages_hc();
+ my $output = run($ENV{DEB_SETUP_BIN_NAME},
+ 'test', "--builddir=dist-$compiler", '--show-details=direct');
+
+ return;
+}
+
+=item haddock_recipe
+
+=cut
+
+sub haddock_recipe {
+ my () = @_;
+
+ my $compiler = packages_hc();
+ my $haddock = hc_haddock($compiler);
+
+ return
+ unless -x "/usr/bin/$haddock";
+
+ run(
+ $ENV{DEB_SETUP_BIN_NAME},
+ 'haddock',
+ "--builddir=dist-$compiler",
+ "--with-haddock=/usr/bin/$haddock",
+ "--with-ghc=$compiler",
+ '--verbose=2',
+ split($SPACE, $ENV{DEB_HADDOCK_OPTS} // $EMPTY));
+
+ return;
+}
+
+=item extra_depends_recipe
+
+=cut
+
+sub extra_depends_recipe {
+ my ($compiler) = @_;
+
+ local $ENV{LC_ALL} = 'C.UTF-8';
+
+ my $output = run($ENV{DEB_SETUP_BIN_NAME},
+ 'register', "--builddir=dist-$compiler",
+ qw{--gen-pkg-config --verbose=verbose+nowrap});
+
+ die encode_utf8('Cannot get name of package registration file.')
+ unless $output
+ =~ m{^Creating \s package \s registration \s file: \s+ (\S+) $}mx;
+
+ my $pkg_config = $1;
+
+ run('dh_haskell_extra_depends', $compiler, $pkg_config);
+ run(qw{rm -f}, $pkg_config);
+
+ return;
+}
+
+=item install_dev_recipe
+
+=cut
+
+sub install_dev_recipe {
+ my ($installable) = @_;
+
+ local $ENV{LC_ALL} = 'C.UTF-8';
+
+ my $compiler = package_hc($installable);
+ my $libdir = package_libdir($installable);
+ my $pkgdir = package_pkgdir($installable);
+
+ my $savedir = Cwd::getcwd;
+ chdir("debian/tmp-inst-$compiler")
+ or warn encode_utf8("Cannot change folder to debian/tmp-inst-$compiler");
+
+ run(qw{mkdir --parents}, $libdir);
+ run(
+ 'find', $libdir,
+ qw{ ( ! -name *_p.a ! -name *.p_hi ! -type d ) },
+ qw{-exec install -Dm 644},
+ '{}', "../$installable/{}", $SEMICOLON
+ );
+
+ chdir($savedir)
+ or warn encode_utf8("Cannot change folder to $savedir");
+
+ my $output = run($ENV{DEB_SETUP_BIN_NAME},
+ 'register', "--builddir=dist-$compiler",
+ qw{--gen-pkg-config --verbose=verbose+nowrap});
+
+ die encode_utf8('Cannot get name of package registration file.')
+ unless $output
+ =~ m{^Creating \s package \s registration \s file: \s+ (\S+) $}mx;
+
+ my $pkg_config = $1;
+
+ run(qw{sed -i}, 's/^exposed: True$/exposed: False/', $pkg_config)
+ if length $ENV{HASKELL_HIDE_PACKAGES};
+
+ run(qw{install -Dm 644},
+ $pkg_config, "debian/$installable/$pkgdir/$pkg_config");
+ run(qw{rm -f}, $pkg_config);
+
+ if (length $ENV{DEB_GHC_EXTRA_PACKAGES}) {
+
+ my $EP_DIR
+ = "debian/$installable/usr/lib/haskell-packages/extra-packages";
+ run(qw{mkdir --parents}, $EP_DIR);
+
+ path("$EP_DIR/$ENV{CABAL_PACKAGE}-$ENV{CABAL_VERSION}")
+ ->spew_utf8($ENV{DEB_GHC_EXTRA_PACKAGES});
+ }
+
+ path($ENV{DEB_LINTIAN_OVERRIDES_FILE})
+ ->append_utf8('binary-or-shlib-defines-rpath' . $NEWLINE)
+ unless -e $ENV{DEB_LINTIAN_OVERRIDES_FILE}
+ && path($ENV{DEB_LINTIAN_OVERRIDES_FILE})->slurp_utf8
+ =~ m{^ binary-or-shlib-defines-rpath }x;
+
+ run('dh_haskell_provides', "--package=$installable");
+ run('dh_haskell_depends', "--package=$installable");
+ run('dh_haskell_shlibdeps', "--package=$installable");
+
+ return;
+}
+
+=item install_prof_recipe
+
+=cut
+
+sub install_prof_recipe {
+ my ($installable) = @_;
+
+ my $compiler = package_hc($installable);
+ my $libdir = package_libdir($installable);
+
+ my $savedir = Cwd::getcwd;
+ chdir("debian/tmp-inst-$compiler")
+ or warn encode_utf8("Cannot change folder to debian/tmp-inst-$compiler");
+
+ run(qw{mkdir --parents}, $libdir);
+ run(
+ 'find', $libdir,
+ qw{ ( -name *_p.a -o -name *.p_hi ) },
+ qw{-exec install -Dm 644},
+ '{}', "../$installable/{}", $SEMICOLON
+ );
+
+ chdir($savedir)
+ or warn encode_utf8("Cannot change folder to $savedir");
+
+ run('dh_haskell_provides', "--package=$installable");
+ run('dh_haskell_depends', "--package=$installable");
+
+ return;
+}
+
+=item install_doc_recipe
+
+=cut
+
+sub install_doc_recipe {
+ my ($installable) = @_;
+
+ my $compiler = package_hc($installable);
+
+ my $htmldir = hc_htmldir($compiler, $ENV{CABAL_PACKAGE});
+ run(qw{mkdir --parents}, "debian/$installable/$htmldir");
+
+ my $savedir = Cwd::getcwd;
+ chdir("debian/tmp-inst-$compiler")
+ or warn encode_utf8("Cannot change folder to debian/tmp-inst-$compiler");
+
+ run(
+ 'find', "./$htmldir",
+ qw{ ! -name *.haddock ! -type d},
+ qw{-exec install -Dm 644},
+ '{}', "../$installable/{}", $SEMICOLON
+ );
+
+ chdir($savedir)
+ or warn encode_utf8("Cannot change folder to $savedir");
+
+ my $docdir
+ = hc_docdir($compiler, "$ENV{CABAL_PACKAGE}-$ENV{CABAL_VERSION}");
+
+ my $tmp_inst_docdir = "debian/tmp-inst-$compiler/$docdir";
+ my $installable_docdir = "debian/$installable/$docdir";
+
+ run(qw{mkdir --parents}, $installable_docdir);
+
+ run(qw{cp --recursive}, $_->stringify, $installable_docdir)
+ for path($tmp_inst_docdir)->children(qr{ [.]haddock $}x);
+
+ if ($ENV{DEB_ENABLE_HOOGLE} eq 'yes') {
+
+ # We cannot just invoke dh_link here because that acts on
+ # either libghc-*-dev or all the binary packages, neither of
+ # which is desirable (see dh_link (1)). So we just create a
+ # (policy-compliant) symlink ourselves
+
+ my $target = "debian/$installable/$htmldir/$ENV{CABAL_PACKAGE}.txt";
+ if (-e $target) {
+
+ my $hoogle = hc_hoogle($compiler);
+ my $name = "debian/$installable$hoogle$installable.txt";
+
+ run(qw{mkdir --parents}, dirname($name));
+ run(qw{ln --symbolic --relative --no-target-directory},
+ $target, $name);
+ }
+ }
+
+ run('dh_haskell_depends', "--package=$installable");
+
+ return;
+}
+
+=head1 AUTHOR
+
+Written by Felix Lechner <felix.lechner at lease-up.com> for Haskell Devscripts.
+Based on Dh_Haskell.sh.
+
+=head1 SEE ALSO
+
+Debian::Debhelper::Buildsystem::haskell(3pm)
+
+=cut
+
+1;
+
+# Local Variables:
+# indent-tabs-mode: nil
+# cperl-indent-level: 4
+# End:
+# vim: syntax=perl sw=4 sts=4 sr et
View it on GitLab: https://salsa.debian.org/haskell-team/haskell-devscripts/-/compare/2bb0ad436d03b33ca148149c999ed86193ec9a2e...8d20067a2a3ce3a6c40775e36f8d265520b70922
--
View it on GitLab: https://salsa.debian.org/haskell-team/haskell-devscripts/-/compare/2bb0ad436d03b33ca148149c999ed86193ec9a2e...8d20067a2a3ce3a6c40775e36f8d265520b70922
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-haskell-commits/attachments/20220403/7e6ffd27/attachment-0001.htm>
More information about the Pkg-haskell-commits
mailing list