Closed tfausak closed 4 years ago
Looks like we have to do the same as for https://github.com/nh2/static-haskell-nix/blob/ff7715e0e13fb3f615e64a8d8c2e43faa4429b0f/survey/default.nix#L988-L992
Using this slightly modified default.nix
for your project fixes it:
# Run using:
#
# $(nix-build --no-link -A fullBuildScript)
{
stack2nix-output-path ? "custom-stack2nix-output.nix",
}:
let
cabalPackageName = "example-project";
compiler = "ghc865"; # matching stack.yaml
# Pin static-haskell-nix version.
static-haskell-nix =
if builtins.pathExists ../.in-static-haskell-nix
then toString ../. # for the case that we're in static-haskell-nix itself, so that CI always builds the latest version.
# Update this hash to use a different `static-haskell-nix` version:
else fetchTarball https://github.com/nh2/static-haskell-nix/archive/8e73cdc0bebb58577978f319a5c3c8a3b0da98f4.tar.gz;
# Pin nixpkgs version
# By default to the one `static-haskell-nix` provides, but you may also give
# your own as long as it has the necessary patches, using e.g.
# pkgs = import (fetchTarball https://github.com/nh2/nixpkgs/archive/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa123.tar.gz) {};
pkgs = import "${static-haskell-nix}/nixpkgs.nix";
stack2nix-script = import "${static-haskell-nix}/static-stack2nix-builder/stack2nix-script.nix" {
inherit pkgs;
stack-project-dir = toString ./.; # where stack.yaml is
hackageSnapshot = "2019-10-08T00:00:00Z"; # pins e.g. extra-deps without hashes or revisions
};
static-stack2nix-builder = import "${static-haskell-nix}/static-stack2nix-builder/default.nix" {
normalPkgs = pkgs;
inherit cabalPackageName compiler stack2nix-output-path;
# disableOptimization = true; # for compile speed
};
# Full invocation, including pinning `nix` version itself.
fullBuildScript = pkgs.writeScript "stack2nix-and-build-script.sh" ''
#!/usr/bin/env bash
set -eu -o pipefail
STACK2NIX_OUTPUT_PATH=$(${stack2nix-script})
export NIX_PATH=nixpkgs=${pkgs.path}
${pkgs.nix}/bin/nix-build --no-link -A static_package --argstr stack2nix-output-path "$STACK2NIX_OUTPUT_PATH" "$@"
'';
static_package =
static-stack2nix-builder.haskell-static-nix_output.pkgs.staticHaskellHelpers.addStaticLinkerFlagsWithPkgconfig
static-stack2nix-builder.static_package
(with static-stack2nix-builder.haskell-static-nix_output.pkgs; [ openssl postgresql ])
"--libs libpq";
in
{
inherit static_package;
inherit fullBuildScript;
# For debugging:
inherit stack2nix-script;
inherit static-stack2nix-builder;
}
The new part in it is:
static_package =
static-stack2nix-builder.haskell-static-nix_output.pkgs.staticHaskellHelpers.addStaticLinkerFlagsWithPkgconfig
static-stack2nix-builder.static_package
(with static-stack2nix-builder.haskell-static-nix_output.pkgs; [ openssl postgresql ])
"--libs libpq";
in
{
inherit static_package;
Here we modify the static_package
returned by the static-stack2nix-builder
a little bit before building (using the addStaticLinkerFlagsWithPkgconfig
function I've just exported in PR #58): We force the libpq
libs to be linked in, which also includes its openssl
dependency libraries.
This is currently required for all apps that link in libpq
.
A better, fundamental solution would be if we could somehow remember in postgresql-simple
itself that any package that uses it will have to link those libs in, but I haven't figured out yet how to do that.
Hmm, I tried that and ended up with a different error:
Preprocessing executable 'example-project' for example-project-1..
Building executable 'example-project' for example-project-1..
[1 of 2] Compiling Main ( example-project.hs, dist/build/example-project/example-project-tmp/Main.o )
[2 of 2] Compiling Paths_example_project ( dist/build/example-project/autogen/Paths_example_project.hs, dist/build/example-project/example-project-tmp/Paths_example_project.o )
Linking dist/build/example-project/example-project ...
haddockPhase
installing
Installing executable example-project in /nix/store/gr764dvk09mb2xg10pwz4yximnf80kgy-example-project-1/bin
Warning: The directory
/nix/store/gr764dvk09mb2xg10pwz4yximnf80kgy-example-project-1/bin is not in
the system search path.
post-installation fixup
shrinking RPATHs of ELF executables and libraries in /nix/store/gr764dvk09mb2xg10pwz4yximnf80kgy-example-project-1
shrinking /nix/store/gr764dvk09mb2xg10pwz4yximnf80kgy-example-project-1/bin/example-project
cannot find section .dynamic
strip is /nix/store/bprb8jwawnsfnrmjwvazl3r84869f0g3-binutils-2.31.1/bin/strip
stripping (with command strip and flags -S) in /nix/store/gr764dvk09mb2xg10pwz4yximnf80kgy-example-project-1/bin
patching script interpreter paths in /nix/store/gr764dvk09mb2xg10pwz4yximnf80kgy-example-project-1
checking for references to /tmp/nix-build-example-project-1.drv-0/ in /nix/store/gr764dvk09mb2xg10pwz4yximnf80kgy-example-project-1...
cannot find section .dynamic
/nix/store/gr764dvk09mb2xg10pwz4yximnf80kgy-example-project-1
@tfausak Is that an error?
It seems it printed the result output path /nix/store/gr764dvk09mb2xg10pwz4yximnf80kgy-example-project-1
at the end.
Oops! You’re absolutely right. I skimmed through that output too quickly. The “cannot find section .dynamic” threw me for a loop.
The build succeeded and I was able to run the executable. And ldd
reported it as not dynamic. Thanks so much!
I've tried to apply the same workaround but the build fails with:
Linking dist/build/my-project/my-project ...
/nix/store/f1v9hcm7pxdrgmmarf5ldss9xc480l0n-binutils-2.31.1/bin/ld: /nix/store/9lyjgijs7cix0scxql46lik6v57qbydq-openssl-1.1.1d/lib/libcrypto.a(f_impl.o): in function `gf_mul':
/build/openssl-1.1.1d/crypto/ec/curve448/arch_32/f_impl.c:16:0: error:
multiple definition of `gf_mul'; /nix/store/qhnylp3ia57kwzihghrnmlng758mpcni-cipher-aes-0.2.11/lib/ghc-8.6.5/x86_64-linux-ghc-8.6.5/cipher-aes-0.2.11-B94prXb0Uot719rucDUpNG/libHScipher-aes-0.2.11-B94prXb0Uot719rucDUpNG.a(gf.o):(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
`cc' failed in phase `Linker'. (Exit code: 1)
builder for '/nix/store/483dzvsmmdawv6gjsajnbp5p1zr8lgjn-my-project-0.0.0.drv' failed with exit code 1
error: build of '/nix/store/483dzvsmmdawv6gjsajnbp5p1zr8lgjn-my-project-0.0.0.drv' failed
apparently cipher-aes-0.2.11
defines gf_mul
which conflicts with openssl.
cipher-aes
is deprecated but it's still being used by clientsession
which is yesod-core
dependency :/
@wedens The simplest fix to that would likely be a PR to cipher-aes
, namespacing the function, calling it e.g. hs_cipher_aes_gf_mul
.
I am trying to build a simple Haskell project that uses PostgreSQL. I can't get it to statically link successfully. Here are the exact steps I'm going through:
After all of the normal output I get these errors: