diff --git a/pkgs/build-support/make-pkgconfigitem/default.nix b/pkgs/build-support/make-pkgconfigitem/default.nix new file mode 100644 index 000000000000..288ca3810eb8 --- /dev/null +++ b/pkgs/build-support/make-pkgconfigitem/default.nix @@ -0,0 +1,69 @@ +{ lib, writeTextFile, buildPackages }: + +# See https://people.freedesktop.org/~dbn/pkg-config-guide.html#concepts +{ name # The name of the pc file + # keywords + # provide a default description for convenience. it's not important but still required by pkg-config. +, description ? "A pkg-config file for ${name}" +, url ? "" +, version ? "" +, requires ? [ ] +, requiresPrivate ? [ ] +, conflicts ? [ ] +, cflags ? [ ] +, libs ? [ ] +, libsPrivate ? [ ] +, variables ? { } +}: + +let + # only 'out' has to be changed, otherwise it would be replaced by the out of the writeTextFile + placeholderToSubstVar = builtins.replaceStrings [ "${placeholder "out"}" ] [ "@out@" ]; + + replacePlaceholderAndListToString = x: + if builtins.isList x + then placeholderToSubstVar (builtins.concatStringsSep " " x) + else placeholderToSubstVar x; + + keywordsSection = + let + mustBeAList = attr: attrName: lib.throwIfNot (lib.isList attr) "'${attrName}' must be a list" attr; + in + { + "Name" = name; + "Description" = description; + "URL" = url; + "Version" = version; + "Requires" = mustBeAList requires "requires"; + "Requires.private" = mustBeAList requiresPrivate "requiresPrivate"; + "Conflicts" = mustBeAList conflicts "conflicts"; + "Cflags" = mustBeAList cflags "cflags"; + "Libs" = mustBeAList libs "libs"; + "Libs.private" = mustBeAList libsPrivate "libsPrivate"; + }; + + renderVariable = name: value: + lib.optionalString (value != "" && value != [ ]) "${name}=${replacePlaceholderAndListToString value}"; + renderKeyword = name: value: + lib.optionalString (value != "" && value != [ ]) "${name}: ${replacePlaceholderAndListToString value}"; + + renderSomething = renderFunc: attrs: + lib.pipe attrs [ + (lib.mapAttrsToList renderFunc) + (builtins.filter (v: v != "")) + (builtins.concatStringsSep "\n") + (section: ''${section} + '') + ]; + + variablesSectionRendered = renderSomething renderVariable variables; + keywordsSectionRendered = renderSomething renderKeyword keywordsSection; + + content = [ variablesSectionRendered keywordsSectionRendered ]; +in +writeTextFile { + name = "${name}.pc"; + destination = "/lib/pkgconfig/${name}.pc"; + text = builtins.concatStringsSep "\n" content; + checkPhase = ''${buildPackages.pkg-config}/bin/pkg-config --validate "$target"''; +} diff --git a/pkgs/build-support/setup-hooks/copy-pkgconfig-items.sh b/pkgs/build-support/setup-hooks/copy-pkgconfig-items.sh new file mode 100644 index 000000000000..8c04ec9b5f0e --- /dev/null +++ b/pkgs/build-support/setup-hooks/copy-pkgconfig-items.sh @@ -0,0 +1,46 @@ +# shellcheck shell=bash + +# Setup hook that installs specified pkgconfig items. +# +# Example usage in a derivation: +# +# { …, makePkgconfigItem, copyPkgconfigItems, … }: +# +# let pkgconfigItem = makePkgconfigItem { … }; in +# stdenv.mkDerivation { +# … +# nativeBuildInputs = [ copyPkgconfigItems ]; +# +# pkgconfigItems = [ pkgconfigItem ]; +# … +# } +# +# This hook will copy files which are either given by full path +# or all '*.pc' files placed inside the 'lib/pkgconfig' +# folder of each `pkgconfigItems` argument. + +postInstallHooks+=(copyPkgconfigItems) + +copyPkgconfigItems() { + if [ "${dontCopyPkgconfigItems-}" = 1 ]; then return; fi + + if [ -z "$pkgconfigItems" ]; then + return + fi + + pkgconfigdir="${!outputDev}/lib/pkgconfig" + for pkgconfigItem in $pkgconfigItems; do + if [[ -f "$pkgconfigItem" ]]; then + substituteAllInPlace "$pkgconfigItem" + echo "Copying '$pkgconfigItem' into '${pkgconfigdir}'" + install -D -m 444 -t "${pkgconfigdir}" "$pkgconfigItem" + substituteAllInPlace "${pkgconfigdir}"/* + else + for f in "$pkgconfigItem"/lib/pkgconfig/*.pc; do + echo "Copying '$f' into '${pkgconfigdir}'" + install -D -m 444 -t "${pkgconfigdir}" "$f" + substituteAllInPlace "${pkgconfigdir}"/* + done + fi + done +} diff --git a/pkgs/development/compilers/tinycc/default.nix b/pkgs/development/compilers/tinycc/default.nix index 8664b54afbdc..97a86a3fa783 100644 --- a/pkgs/development/compilers/tinycc/default.nix +++ b/pkgs/development/compilers/tinycc/default.nix @@ -1,6 +1,8 @@ { lib , stdenv , fetchFromRepoOrCz +, copyPkgconfigItems +, makePkgconfigItem , perl , texinfo , which @@ -17,11 +19,32 @@ stdenv.mkDerivation rec { }; nativeBuildInputs = [ + copyPkgconfigItems perl texinfo which ]; + pkgconfigItems = [ + (makePkgconfigItem rec { + name = "libtcc"; + inherit version; + cflags = [ "-I${variables.includedir}" ]; + libs = [ + "-L${variables.libdir}" + "-Wl,--rpath ${variables.libdir}" + "-ltcc" + "-ldl" + ]; + variables = rec { + prefix = "${placeholder "out"}"; + includedir = "${prefix}/include"; + libdir = "${prefix}/lib"; + }; + description = "Tiny C compiler backend"; + }) + ]; + postPatch = '' patchShebangs texi2pod.pl ''; @@ -43,17 +66,6 @@ stdenv.mkDerivation rec { configureFlagsArray+=("--elfinterp=$(< $NIX_CC/nix-support/dynamic-linker)") ''; - postFixup = '' - cat >libtcc.pc <