From 238d634e4b7cbe58c9d9fbc155ffcf19f25f2b12 Mon Sep 17 00:00:00 2001 From: Sergei Trofimovich Date: Sun, 24 Oct 2021 09:39:21 +0100 Subject: [PATCH] ocaml: enable parallel building Enable parallel building for ocaml-4.08 and above. tested as: $ nix build -f. ocaml-ng.ocamlPackages_{4_{00_1,01_0,02,03,04,05,06,07,08,09,10,11,12,13},latest}.ocaml --keep-going ocaml build system supports parallel building, but but for multiple top-level targets at the same time as it usually spawns subprocess $(MAKE) that occasionally conflict with one another. To work it around we use tiny Makefile with a single rule that calls top-level targets sequentially as makefile calls: nixpkgs_world_bootstrap_world_opt: $(MAKE) world $(MAKE) bootstrap $(MAKE) world.opt On a 16-core machine ocaml-4.12 build speeds up from 6m55s to 1m35s. Releases 4_00_1, 4_01_0, 4_04 and 4_05 still have some race in them. Thus this change enables parallel builds only for ocaml-4.06 and above. Adapted from #142723 upstreams's CI tests the parallel makefile: https://github.com/ocaml/ocaml/issues/10235#issuecomment-782100584 The limit was chosen to be 4.08 because it was released in 2019, not too long before the above link. --- .../development/compilers/ocaml/Makefile.nixpkgs | 16 ++++++++++++++++ pkgs/development/compilers/ocaml/generic.nix | 13 ++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 pkgs/development/compilers/ocaml/Makefile.nixpkgs diff --git a/pkgs/development/compilers/ocaml/Makefile.nixpkgs b/pkgs/development/compilers/ocaml/Makefile.nixpkgs new file mode 100644 index 000000000000..2d6457852fc9 --- /dev/null +++ b/pkgs/development/compilers/ocaml/Makefile.nixpkgs @@ -0,0 +1,16 @@ +# ocaml build system does not allow for parallel building of some +# top-level targets like 'world', 'bootstrap', 'world.opt' as +# then spawn '$(MAKE) all' subprocesses that conflict among each +# other. But we would still like to run each target in parallel +# individually. This file defines such entry points. + +# Re-export all existing phases to make 'make install' work as is. +include Makefile + +nixpkgs_world: + $(MAKE) world + +nixpkgs_world_bootstrap_world_opt: + $(MAKE) world + $(MAKE) bootstrap + $(MAKE) world.opt diff --git a/pkgs/development/compilers/ocaml/generic.nix b/pkgs/development/compilers/ocaml/generic.nix index e4cec4cf52ed..c8198b5b3731 100644 --- a/pkgs/development/compilers/ocaml/generic.nix +++ b/pkgs/development/compilers/ocaml/generic.nix @@ -68,7 +68,18 @@ stdenv.mkDerivation (args // { # x86_64-unknown-linux-musl-ld: -r and -pie may not be used together hardeningDisable = lib.optional (lib.versionAtLeast version "4.09" && stdenv.hostPlatform.isMusl) "pie"; - buildFlags = [ "world" ] ++ optionals useNativeCompilers [ "bootstrap" "world.opt" ]; + # Older versions have some race: + # cp: cannot stat 'boot/ocamlrun': No such file or directory + # make[2]: *** [Makefile:199: backup] Error 1 + enableParallelBuilding = lib.versionAtLeast version "4.08"; + + # Workaround lack of parallelism support among top-level targets: + # we place nixpkgs-specific targets to a separate file and set + # sequential order among them as a single rule. + makefile = ./Makefile.nixpkgs; + buildFlags = if useNativeCompilers + then ["nixpkgs_world_bootstrap_world_opt"] + else ["nixpkgs_world"]; buildInputs = optional (!lib.versionAtLeast version "4.07") ncurses ++ optionals useX11 [ libX11 xorgproto ]; propagatedBuildInputs = optional spaceTimeSupport libunwind;