From adf0e3890fa46f3751870e3b32d2be332131dd96 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Sun, 11 Jun 2023 14:05:05 +0200 Subject: [PATCH 1/6] enable fully static toolchain --- WORKSPACE.bazel | 26 +++++++++++++++++++++++--- backend/BUILD.bazel | 1 + 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel index 42f38a9..1a7c5d0 100644 --- a/WORKSPACE.bazel +++ b/WORKSPACE.bazel @@ -76,7 +76,17 @@ stack_snapshot( load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_git_repository") load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_cc_configure") -nixpkgs_cc_configure(repository = "@nixpkgs") +nixpkgs_cc_configure( + repository = "@nixpkgs", + nix_file_content = """\ +with import { config = {}; overlays = []; }; +buildEnv { + name = "bazel-cc-toolchain"; + paths = [ pkgsMusl.stdenv.cc pkgsMusl.binutils ]; + passthru = { isClang = pkgsMusl.stdenv.cc.isClang; }; +} +""", +) load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_python_configure") @@ -85,16 +95,26 @@ nixpkgs_python_configure(repository = "@nixpkgs") load("@rules_haskell//haskell:nixpkgs.bzl", "haskell_register_ghc_nixpkgs") haskell_register_ghc_nixpkgs( - attribute_path = "ghc", + attribute_path = "", + nix_file_content = """\ +with import {}; +pkgsMusl.haskell.compiler.ghc902.override { enableRelocatedStaticLibs = true; enableShared = false; } +""", repository = "@nixpkgs", version = "9.0.2", + static_runtime = True, + fully_static_link = True, ) load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_package") nixpkgs_package( name = "nixpkgs_zlib", - attribute_path = "zlib", + nix_file_content = """\ +with import { config = {}; overlays = []; }; +( pkgsMusl.zlib.override { static=true; shared=false; } +).overrideAttrs (_:{ dontDisableStatic=true; }) +""", repository = "@nixpkgs", ) diff --git a/backend/BUILD.bazel b/backend/BUILD.bazel index 1e81cf5..25cb226 100644 --- a/backend/BUILD.bazel +++ b/backend/BUILD.bazel @@ -62,6 +62,7 @@ haskell_binary( "@stackage//:warp", "@stackage//:zlib", ], + features = ["fully_static_link"], ) cc_library( From c79d23372c0b4a4d1bdd9462780019a0a9441f2b Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Sun, 11 Jun 2023 16:25:37 +0200 Subject: [PATCH 2/6] Use static haskell nix to provide GHC So that libffi and libgmp include .a files. --- WORKSPACE.bazel | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel index 1a7c5d0..a4e7186 100644 --- a/WORKSPACE.bazel +++ b/WORKSPACE.bazel @@ -4,9 +4,9 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "io_tweag_rules_nixpkgs", - sha256 = "1f3d86577eb1b85881f60c9eb1eb420c64d2ec8b9c951dbd66394db20cb5ddb1", - strip_prefix = "rules_nixpkgs-d28e07001f2c2386162cb51964f02f6c9b67628a", - urls = ["https://github.com/tweag/rules_nixpkgs/archive/d28e07001f2c2386162cb51964f02f6c9b67628a.tar.gz"], + sha256 = "9e3898a33c5f21f634aa9e2d45620e7c4b6d54d16d473571a891193bbd4725ca", + strip_prefix = "rules_nixpkgs-0c1f8f5470c7f292b7620762e224f53d837929d3", + urls = ["https://github.com/tweag/rules_nixpkgs/archive/0c1f8f5470c7f292b7620762e224f53d837929d3.tar.gz"], ) load("@io_tweag_rules_nixpkgs//nixpkgs:repositories.bzl", "rules_nixpkgs_dependencies") @@ -97,10 +97,21 @@ load("@rules_haskell//haskell:nixpkgs.bzl", "haskell_register_ghc_nixpkgs") haskell_register_ghc_nixpkgs( attribute_path = "", nix_file_content = """\ -with import {}; -pkgsMusl.haskell.compiler.ghc902.override { enableRelocatedStaticLibs = true; enableShared = false; } +let + pkgs = import {}; + static-haskell-nix = import { normalPkgs = pkgs; }; + inherit (static-haskell-nix) pkgsWithArchiveFiles; +in +pkgsWithArchiveFiles.haskell.compiler.ghc902.override { + enableRelocatedStaticLibs = true; + enableShared = false; +} """, - repository = "@nixpkgs", + repositories = { + "nixpkgs": "@nixpkgs", + "static-haskell-nix": "@static-haskell-nix//:survey/default.nix", + }, + nixopts = ["--builders", "@/etc/nix/machines", "-j0"], version = "9.0.2", static_runtime = True, fully_static_link = True, @@ -131,6 +142,14 @@ nixpkgs_local_repository( nix_flake_lock_file = "//:flake.lock", ) +load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_http_repository") + +nixpkgs_http_repository( + name = "static-haskell-nix", + url = "https://github.com/nh2/static-haskell-nix/archive/bd66b86b72cff4479e1c76d5916a853c38d09837.tar.gz", + strip_prefix = "static-haskell-nix-bd66b86b72cff4479e1c76d5916a853c38d09837", +) + nixpkgs_package( name = "esbuild", repository = "@nixpkgs", From 90c8d52bc91880360fe47fc0c322fa62910b47cd Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Sun, 11 Jun 2023 16:45:07 +0200 Subject: [PATCH 3/6] Move static-nixpkgs.nix into file repository --- WORKSPACE.bazel | 47 +++++++++++++++------------------------------- static-nixpkgs.nix | 20 ++++++++++++++++++++ 2 files changed, 35 insertions(+), 32 deletions(-) create mode 100644 static-nixpkgs.nix diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel index a4e7186..c5405d4 100644 --- a/WORKSPACE.bazel +++ b/WORKSPACE.bazel @@ -76,16 +76,11 @@ stack_snapshot( load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_git_repository") load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_cc_configure") +static_nixopts = ["--builders", "@/etc/nix/machines", "-j0"] + nixpkgs_cc_configure( - repository = "@nixpkgs", - nix_file_content = """\ -with import { config = {}; overlays = []; }; -buildEnv { - name = "bazel-cc-toolchain"; - paths = [ pkgsMusl.stdenv.cc pkgsMusl.binutils ]; - passthru = { isClang = pkgsMusl.stdenv.cc.isClang; }; -} -""", + repository = "@static-nixpkgs", + nixopts = static_nixopts, ) load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_python_configure") @@ -97,21 +92,14 @@ load("@rules_haskell//haskell:nixpkgs.bzl", "haskell_register_ghc_nixpkgs") haskell_register_ghc_nixpkgs( attribute_path = "", nix_file_content = """\ -let - pkgs = import {}; - static-haskell-nix = import { normalPkgs = pkgs; }; - inherit (static-haskell-nix) pkgsWithArchiveFiles; -in -pkgsWithArchiveFiles.haskell.compiler.ghc902.override { +with import { config = {}; overlays = []; }; +haskell.compiler.ghc902.override { enableRelocatedStaticLibs = true; enableShared = false; } """, - repositories = { - "nixpkgs": "@nixpkgs", - "static-haskell-nix": "@static-haskell-nix//:survey/default.nix", - }, - nixopts = ["--builders", "@/etc/nix/machines", "-j0"], + repository = "@static-nixpkgs", + nixopts = static_nixopts, version = "9.0.2", static_runtime = True, fully_static_link = True, @@ -121,12 +109,9 @@ load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_package") nixpkgs_package( name = "nixpkgs_zlib", - nix_file_content = """\ -with import { config = {}; overlays = []; }; -( pkgsMusl.zlib.override { static=true; shared=false; } -).overrideAttrs (_:{ dontDisableStatic=true; }) -""", - repository = "@nixpkgs", + attribute_path = "zlib.static", + repository = "@static-nixpkgs", + nixopts = static_nixopts, ) nixpkgs_package( @@ -142,12 +127,10 @@ nixpkgs_local_repository( nix_flake_lock_file = "//:flake.lock", ) -load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_http_repository") - -nixpkgs_http_repository( - name = "static-haskell-nix", - url = "https://github.com/nh2/static-haskell-nix/archive/bd66b86b72cff4479e1c76d5916a853c38d09837.tar.gz", - strip_prefix = "static-haskell-nix-bd66b86b72cff4479e1c76d5916a853c38d09837", +nixpkgs_local_repository( + name = "static-nixpkgs", + nix_file = "//:static-nixpkgs.nix", + nix_file_deps = ["//:flake.lock"], ) nixpkgs_package( diff --git a/static-nixpkgs.nix b/static-nixpkgs.nix new file mode 100644 index 0000000..5bb08c5 --- /dev/null +++ b/static-nixpkgs.nix @@ -0,0 +1,20 @@ +{...}@args: +let + lock = builtins.fromJSON (builtins.readFile ./flake.lock); + nixpkgs = + let + src = lock.nodes.nixpkgs.locked; + in + assert src.type == "github"; + fetchTarball { + url = "https://github.com/${src.owner}/${src.repo}/archive/${src.rev}.tar.gz"; + sha256 = src.narHash; + }; + normalPkgs = import nixpkgs args; + static-haskell-nix = + fetchTarball { + url = "https://github.com/nh2/static-haskell-nix/archive/bd66b86b72cff4479e1c76d5916a853c38d09837.tar.gz"; + sha256 = "sha256:0rnsxaw7v27znsg9lgqk1i4007ydqrc8gfgimrmhf24lv6galbjh"; + }; +in +(import "${static-haskell-nix}/survey" { inherit normalPkgs; }).pkgsWithArchiveFiles From 409863d87970c4b1af7676537a27f9d3a50a7dd8 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Sun, 11 Jun 2023 17:04:27 +0200 Subject: [PATCH 4/6] todo-note --- WORKSPACE.bazel | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel index c5405d4..11a6164 100644 --- a/WORKSPACE.bazel +++ b/WORKSPACE.bazel @@ -76,6 +76,7 @@ stack_snapshot( load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_git_repository") load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_cc_configure") +# TODO[AH] Replace this by global Nix configuration for appropriate Nix cache. static_nixopts = ["--builders", "@/etc/nix/machines", "-j0"] nixpkgs_cc_configure( @@ -91,6 +92,7 @@ load("@rules_haskell//haskell:nixpkgs.bzl", "haskell_register_ghc_nixpkgs") haskell_register_ghc_nixpkgs( attribute_path = "", + # TODO[AH] Upstream and expose through a Nix cache. nix_file_content = """\ with import { config = {}; overlays = []; }; haskell.compiler.ghc902.override { From 0fbff29e540f40994949a3aea26bb6ccf10272a0 Mon Sep 17 00:00:00 2001 From: Ben Radford Date: Thu, 10 Aug 2023 11:48:48 +0100 Subject: [PATCH 5/6] Support both fully static and regular linking. As static-haskell-nix doesn't yet support MacOS, and as we don't have a Nix cache with an appropriate GHC, it will be convenient to allow both types of linking for the time being. The default will be to link dynamically. To build a fully static binary pass: --host_platform=//backend:static_executable --- .bazelrc | 4 ++-- WORKSPACE.bazel | 43 +++++++++++++++++++++++++++++++++++++- backend/BUILD.bazel | 41 ++++++++++++++++++++++++++++++++++-- backend/sqlite.BUILD.bazel | 10 ++++++++- backend/zlib.BUILD.bazel | 5 ++++- 5 files changed, 96 insertions(+), 7 deletions(-) diff --git a/.bazelrc b/.bazelrc index 74fd43b..526f129 100644 --- a/.bazelrc +++ b/.bazelrc @@ -7,8 +7,8 @@ build:ci-windows --crosstool_top=@rules_haskell_ghc_windows_amd64//:cc_toolchain # This project uses a GHC provisioned via nix. # We need to use the rules_haskell nix toolchain accordingly: -build --host_platform=@io_tweag_rules_nixpkgs//nixpkgs/platforms:host -run --host_platform=@io_tweag_rules_nixpkgs//nixpkgs/platforms:host +build --host_platform=//backend:regular_executable --incompatible_enable_cc_toolchain_resolution +run --host_platform=//backend:regular_executable --incompatible_enable_cc_toolchain_resolution # test environment does not propagate locales by default # some tests reads files written in UTF8, we need to propagate the correct diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel index d5b9615..b756625 100644 --- a/WORKSPACE.bazel +++ b/WORKSPACE.bazel @@ -76,12 +76,22 @@ stack_snapshot( load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_git_repository") load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_cc_configure") +nixpkgs_cc_configure( + name = "local_config_cc_regular", + repository = "@nixpkgs", + exec_constraints = ["@//backend:regular_linking"], + target_constraints = ["@//backend:regular_linking"], +) + # TODO[AH] Replace this by global Nix configuration for appropriate Nix cache. -static_nixopts = ["--builders", "@/etc/nix/machines", "-j0"] +static_nixopts = [] #["--builders", "@/etc/nix/machines", "-j0"] nixpkgs_cc_configure( + name = "local_config_cc_static", repository = "@static-nixpkgs", nixopts = static_nixopts, + exec_constraints = ["@//backend:fully_static_linking"], + target_constraints = ["@//backend:fully_static_linking"], ) load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_python_configure") @@ -91,6 +101,16 @@ nixpkgs_python_configure(repository = "@nixpkgs") load("@rules_haskell//haskell:nixpkgs.bzl", "haskell_register_ghc_nixpkgs") haskell_register_ghc_nixpkgs( + name = "rules_haskell_regular", + attribute_path = "ghc", + repository = "@nixpkgs", + version = "9.0.2", + exec_constraints = ["@//backend:regular_linking"], + target_constraints = ["@//backend:regular_linking"], +) + +haskell_register_ghc_nixpkgs( + name = "rules_haskell_static", attribute_path = "", # TODO[AH] Upstream and expose through a Nix cache. nix_file_content = """\ @@ -105,12 +125,20 @@ haskell.compiler.ghc902.override { version = "9.0.2", static_runtime = True, fully_static_link = True, + exec_constraints = ["@//backend:fully_static_linking"], + target_constraints = ["@//backend:fully_static_linking"], ) load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_package") nixpkgs_package( name = "nixpkgs_zlib", + attribute_path = "zlib", + repository = "@nixpkgs", +) + +nixpkgs_package( + name = "nixpkgs_zlib.static", attribute_path = "zlib.static", repository = "@static-nixpkgs", nixopts = static_nixopts, @@ -135,6 +163,19 @@ nixpkgs_package( repository = "@nixpkgs", ) +nixpkgs_package( + name = "sqlite.dev.static", + build_file = "//backend:sqlite.BUILD.bazel", + nix_file_content = """ + let pkgs = import { }; + in pkgs.buildEnv { + name = "sqlite"; + paths = [ pkgs.sqlite.dev pkgs.sqlite.out ]; + } + """, + repository = "@static-nixpkgs", +) + load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_local_repository") nixpkgs_local_repository( diff --git a/backend/BUILD.bazel b/backend/BUILD.bazel index 3e0f2b1..3fedad5 100644 --- a/backend/BUILD.bazel +++ b/backend/BUILD.bazel @@ -1,5 +1,36 @@ load("@rules_haskell//haskell:defs.bzl", "haskell_binary", "haskell_toolchain_library") +constraint_setting( + name = "executable_linking", + visibility = ["//visibility:public"], +) + +constraint_value( + name = "fully_static_linking", + constraint_setting = ":executable_linking", + visibility = ["//visibility:public"], +) + +platform( + name = "static_executable", + constraint_values = [":fully_static_linking"], + parents = ["@io_tweag_rules_nixpkgs//nixpkgs/platforms:host"], + visibility = ["//visibility:public"], +) + +constraint_value( + name = "regular_linking", + constraint_setting = ":executable_linking", + visibility = ["//visibility:public"], +) + +platform( + name = "regular_executable", + constraint_values = [":regular_linking"], + parents = ["@io_tweag_rules_nixpkgs//nixpkgs/platforms:host"], + visibility = ["//visibility:public"], +) + haskell_toolchain_library(name = "base") haskell_binary( @@ -63,7 +94,10 @@ haskell_binary( "@stackage//:warp", "@stackage//:zlib", ], - features = ["fully_static_link"], + features = select({ + "@//backend:regular_linking": [], + "@//backend:fully_static_linking": ["fully_static_link"], + }), ) copts = [ @@ -84,5 +118,8 @@ cc_library( srcs = [":src/import.cpp"], copts = copts, linkstatic = True, - deps = ["@sqlite.dev"], + deps = select({ + "@//backend:regular_linking": ["@sqlite.dev"], + "@//backend:fully_static_linking": ["@sqlite.dev.static//:sqlite.dev"], + }), ) diff --git a/backend/sqlite.BUILD.bazel b/backend/sqlite.BUILD.bazel index ae4aedd..0534567 100644 --- a/backend/sqlite.BUILD.bazel +++ b/backend/sqlite.BUILD.bazel @@ -2,7 +2,15 @@ load("@rules_cc//cc:defs.bzl", "cc_library") cc_library( name = "sqlite.dev", - srcs = glob(["lib/*.so*"]), + srcs = select({ + "@//backend:regular_linking": glob(["lib/*.so*"]), + "@//backend:fully_static_linking": [ + # No need to link anything for sqlite when building a fully static executable. + # The direct-sqlite Haskell library already links against it so we can just + # assume the appropriate symbols will already be available in the executable + # and let the linker sort it out. + ], + }), hdrs = glob(["include/*.h"]), strip_include_prefix = "include", visibility = ["//visibility:public"], diff --git a/backend/zlib.BUILD.bazel b/backend/zlib.BUILD.bazel index e4165d3..77c03f1 100644 --- a/backend/zlib.BUILD.bazel +++ b/backend/zlib.BUILD.bazel @@ -7,7 +7,10 @@ filegroup( ) cc_library( name = "zlib", - srcs = ["@nixpkgs_zlib//:lib"], + srcs = select({ + "@//backend:regular_linking": ["@nixpkgs_zlib//:lib"], + "@//backend:fully_static_linking": ["@nixpkgs_zlib.static//:lib"], + }), hdrs = [":include"], strip_include_prefix = "include", visibility = ["//visibility:public"], From a24690087267ef76058959685052a92aa83913ef Mon Sep 17 00:00:00 2001 From: Ben Radford Date: Tue, 15 Aug 2023 10:55:50 +0100 Subject: [PATCH 6/6] Run buildifier. --- WORKSPACE.bazel | 22 +++++++++++----------- backend/BUILD.bazel | 8 ++++---- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel index b756625..600a3e2 100644 --- a/WORKSPACE.bazel +++ b/WORKSPACE.bazel @@ -78,19 +78,19 @@ load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_cc_configure") nixpkgs_cc_configure( name = "local_config_cc_regular", - repository = "@nixpkgs", exec_constraints = ["@//backend:regular_linking"], + repository = "@nixpkgs", target_constraints = ["@//backend:regular_linking"], ) # TODO[AH] Replace this by global Nix configuration for appropriate Nix cache. -static_nixopts = [] #["--builders", "@/etc/nix/machines", "-j0"] +static_nixopts = [] #["--builders", "@/etc/nix/machines", "-j0"] nixpkgs_cc_configure( name = "local_config_cc_static", - repository = "@static-nixpkgs", - nixopts = static_nixopts, exec_constraints = ["@//backend:fully_static_linking"], + nixopts = static_nixopts, + repository = "@static-nixpkgs", target_constraints = ["@//backend:fully_static_linking"], ) @@ -103,15 +103,17 @@ load("@rules_haskell//haskell:nixpkgs.bzl", "haskell_register_ghc_nixpkgs") haskell_register_ghc_nixpkgs( name = "rules_haskell_regular", attribute_path = "ghc", - repository = "@nixpkgs", - version = "9.0.2", exec_constraints = ["@//backend:regular_linking"], + repository = "@nixpkgs", target_constraints = ["@//backend:regular_linking"], + version = "9.0.2", ) haskell_register_ghc_nixpkgs( name = "rules_haskell_static", attribute_path = "", + exec_constraints = ["@//backend:fully_static_linking"], + fully_static_link = True, # TODO[AH] Upstream and expose through a Nix cache. nix_file_content = """\ with import { config = {}; overlays = []; }; @@ -120,13 +122,11 @@ haskell.compiler.ghc902.override { enableShared = false; } """, - repository = "@static-nixpkgs", nixopts = static_nixopts, - version = "9.0.2", + repository = "@static-nixpkgs", static_runtime = True, - fully_static_link = True, - exec_constraints = ["@//backend:fully_static_linking"], target_constraints = ["@//backend:fully_static_linking"], + version = "9.0.2", ) load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_package") @@ -140,8 +140,8 @@ nixpkgs_package( nixpkgs_package( name = "nixpkgs_zlib.static", attribute_path = "zlib.static", - repository = "@static-nixpkgs", nixopts = static_nixopts, + repository = "@static-nixpkgs", ) nixpkgs_package( diff --git a/backend/BUILD.bazel b/backend/BUILD.bazel index 3fedad5..b8108b1 100644 --- a/backend/BUILD.bazel +++ b/backend/BUILD.bazel @@ -52,6 +52,10 @@ haskell_binary( "//frontend:src/theme.css", "//backend:src/schema.sql", ], + features = select({ + "@//backend:regular_linking": [], + "@//backend:fully_static_linking": ["fully_static_link"], + }), ghcopts = [ "-O2", "-Wall", @@ -94,10 +98,6 @@ haskell_binary( "@stackage//:warp", "@stackage//:zlib", ], - features = select({ - "@//backend:regular_linking": [], - "@//backend:fully_static_linking": ["fully_static_link"], - }), ) copts = [