Skip to content

better pkg config path for devshell + access to variants from project #1760

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/reference/library.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ Then feeding its result into [mkCabalProjectPkgSet](#mkcabalprojectpkgset) passi
| `ghcWithHoogle` | Function | [`ghcWithHoogle`](#ghcwithhoogle) |
| `ghcWithPackages` | Function | [`ghcWithPackages`](#ghcwithpackages) |
| `projectCross` | Attrset | Like `pkgs.pkgsCross.<system>` from nixpkgs `p.projectCross.<system>` returns the project results for cross compilation (where system is a member of nixpkgs lib.systems.examples). So `p.projectCross.ghcjs.hsPkgs` is the same as `hsPkgs` but compiled with ghcjs |
| `projectVariants` | Attrset | Attribute set of variant for the project, mapped from `flake.variants` config values |
| `appendModule` | Function | Re-eval the project with an extra module (or module list). |
| `extend` and `appendOverlays` | Function | Modify a project, or add attributes, through overlays: `p.extend(final: prev: { })`. The overlays are carried-over `projectCross` and `appendModule` invocations. |

Expand Down
26 changes: 25 additions & 1 deletion lib/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ in {
projectOverlays = import ./project-overlays.nix {
inherit lib haskellLib;
};

# Use by `prefixFlake` to add a prefix to every attribute
prefixAttrs = prefix: x:
__listToAttrs (map (n:{
Expand Down Expand Up @@ -540,4 +540,28 @@ in {
devShells
devShell; # TODO remove devShell once everyone has nix that supports `devShells.default`
};

# Adapt a standard project shell (`project.shell` or `haskell-nix.shellFor`)
# into a devshell module (https://github.com/numtide/devshell)
# that should provide the same environnement.
devshellFor = shell: {
packages = lib.filter lib.isDerivation (shell.nativeBuildInputs
# devshell does not use pkgs.mkShell / pkgs.stdenv.mkDerivation,
# so we need to explicit required dependencies which
# are provided implicitely by stdenv when using the normal shell:
++ shell.stdenv.defaultNativeBuildInputs)
++ [shell.stdenv.cc.bintools];
# We need to expose all the necessary env variables:
env = [
{
name = "PKG_CONFIG_PATH";
value = lib.makeSearchPath "lib/pkgconfig" shell.buildInputs;
}
] ++ lib.mapAttrsToList lib.nameValuePair ({
inherit (shell) NIX_GHC_LIBDIR;
# CABAL_CONFIG is only set if the shell was built with exactDeps=true
} // lib.optionalAttrs (shell ? CABAL_CONFIG) {
inherit (shell) CABAL_CONFIG;
});
};
}
32 changes: 4 additions & 28 deletions lib/project-overlays.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,11 @@
lib
, haskellLib
}: {
# Provide a devshell profile (https://github.com/numtide/devshell),
# adapted from the project normal shell.

# TODO: remove by end of 2022.
devshell = final: prev: {
devshell = let
in {
packages = final.shell.nativeBuildInputs
# Cannot add the whole final.shell.buildInputs list because many collide with each other when fused.
# So we only add what is really used (by pkg-config):
++ map (p: p.dev or p) (lib.concatLists (lib.concatMap (p: p.components.library.pkgconfig or [] ++ p.components.setup.pkgconfig or [] ++ lib.concatMap (c: lib.concatMap (a: a.pkgconfig) (lib.attrValues c)) (lib.attrValues (removeAttrs p.components ["library" "setup"])))
(lib.attrValues final.pkg-set.config.packages)))
# devshell does not use pkgs.mkShell / pkgs.stdenv.mkDerivation,
# so we need to explicit required dependencies which
# are provided implicitely by stdenv when using the normal shell:
++ (lib.filter lib.isDerivation final.shell.stdenv.defaultNativeBuildInputs)
++ lib.optional final.shell.stdenv.targetPlatform.isGnu final.pkgs.buildPackages.binutils;
# We need to expose all the necessary env variables:
env = [
{
name = "PKG_CONFIG_PATH";
# devshell fuse every all `packages` into a single directory ($DEVSHELL_DIR), so we use it:
prefix = "$DEVSHELL_DIR/lib/pkgconfig";
}
] ++ lib.mapAttrsToList lib.nameValuePair ({
inherit (final.shell) NIX_GHC_LIBDIR;
# CABAL_CONFIG is only set if the shell was built with exactDeps=true
} // lib.optionalAttrs (final.shell ? CABAL_CONFIG) {
inherit (final.shell) CABAL_CONFIG;
});
};
devshell = builtins.trace "WARNING: `projectOverlays.devshell` is deprecated in favor of `haskellLib.devshellFor`"
(haskellLib.devshellFor final.shell);
};

# Provides easily accessible attrset for each type of
Expand Down
8 changes: 6 additions & 2 deletions overlays/haskell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,10 @@ final: prev: {
.extend project.__overlay__
) final.pkgsCross) // { recurseForDerivations = false; };

# attribute set of variant (with an extra module applied) for the project,
# mapped from `flake.variants` config values.
projectVariants = final.lib.mapAttrs (_: project.appendModule) project.args.flake.variants;

# re-eval this project with an extra module (or module list).
appendModule = extraProjectModule: (rawProject.projectFunction final.haskell-nix
((if builtins.isList rawProject.projectModule
Expand Down Expand Up @@ -762,8 +766,8 @@ final: prev: {
forAllVariants =
forAllCrossCompilers "default" project
++ final.lib.concatLists (final.lib.mapAttrsToList
(name: projectModule: forAllCrossCompilers name (project.appendModule projectModule))
project.args.flake.variants);
(name: projectVariant: forAllCrossCompilers name projectVariant)
project.projectVariants);
in haskellLib.combineFlakes ":" (builtins.foldl' (a: b: a // b) {} forAllVariants);
flake = args: (project.appendModule { flake = args; }).flake';

Expand Down