-
-
Notifications
You must be signed in to change notification settings - Fork 14.6k
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
buildRebar3: use rebar3 bare compile
#122633
Conversation
I have opened this PR to get feedback on this idea which I think could simplify @petabyteboy you mentioned that you were using I removed the |
buildPhase = '' | ||
runHook preBuild | ||
HOME=. rebar3 compile | ||
${if compilePorts then '' | ||
HOME=. rebar3 pc compile |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that removal of this and use of rebar3 bare compile
will break projects which use the recommended rebar3 NIF/port compilation mechanism as described here: https://github.com/blt/port_compiler#use-in-your-project
Previously one could set compilePorts
to true and the ports would have been force-compiled. If compilePorts
is not set, the hooks in rebar.config
could have triggered to compile them. Now both mechanisms are gone.
I suspect that if we ditch rebar3 compile
we'll be forced to reproduce a lot of rebar3's logic, while in reality we want to replace just the dependency fetching part (or any other network-using functionality).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thinking was that if a project used the pc
configuration with provider_hooks
, then hopefully it would be sufficient to make pc
available through the buildPlugins
argument? I guess what we need to do is find a few packages with native dependencies and test them.
Regarding the rebar3 logic we might be missing out on, I'm also worried about this. From these docs it looks like compile
depends on install_deps
which depends on lock
. I'll look into what those steps do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the link to packages using compilePorts
, that looks like a good starting point for testing this!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that packages should use the hooks, but IIRC a lot of packages in hex.pm in ~2015 did not do that in practice. Also the provider_hooks
recommended in the port_compiler
README won't trigger for rebar3 bare compile
, since it is not the rebar3 compile
which everyone sets the hooks for.
Do you know if we can use rebar3 bare compile
and rebar3 pc compile
together at all? If so, maybe keeping compilePorts
flag as an option might be a good middle ground.
IMO the best solution is to introduce a REBAR3_HERMETIC
flag of sorts into upstream of rebar3 so we can use it. I tried and failed to convince rebar maintainers to make it so.
Second best might be to maintain an always-included rebar3 patch, so that we can set the flag only inside of buildRebar3
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fortunately it looks like rebar3 bare compile
still triggers the provider_hooks
! I tested a few different nif-containing packages below (some use pc
, others like katipo
and jiffy
have their own custom compilation) and it all seems to work, I'm quite surprised actually. So I think we can drop compilePorts
, at this stage I think if we encounter any packages for which it doesn't work, the best approach would be to fix those specific packages
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unexpected and great news!
@dlesl There were some packages in nixpkgs which used to use |
Found its use in https://raw.githubusercontent.com/NixOS/nixpkgs/a21cb752426a57888d8bc0ef957b45e7033177e7/pkgs/development/beam-modules/hex-packages.nix in multiple packages, e.g. |
Result of 1 package marked as broken and skipped:
1 package failed to build:
3 packages built successfully:
Note that build failures may predate this PR, and could be nondeterministic or hardware dependent. Result of 1 package marked as broken and skipped:
1 package failed to build:
3 packages built successfully:
2 suggestions:
Note that build failures may predate this PR, and could be nondeterministic or hardware dependent. |
[ -d "$fd" ] || continue | ||
cp -Hrt "$out/lib/erlang/lib/${name}-${version}" "$fd" | ||
success=1 | ||
[ -d "$reldir" ] || continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just asking a question since I'm not sure of what was happening before and after.
As I understand it
Before
- in the build phase files are compiled to
_build/default/${name}
- check for the presence of a specific directory (src ebin priv include) inside the build
- if the directory is there, copy the contents of the directory into the convention defined path
After - check for the presence of (src ebin priv include) directly inside $src
- if the directory is there, copy it's content too the convention defined path
In this pr does this mean that the bare compile will compile directly into $src and not into _build ?
There is one step I'm missing here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, yes you've got this exactly right. AFAIK the only documentation for rebar3 bare compile
is the source code, there's a parameter called outdir
but it defaults to the working directory.
One more question I have is around the making of symlinks. |
Rebar3 looks in ERL_LIBS but only as a last resort, so if
That's what I'm hoping! |
bb52cce
to
6b494f0
Compare
Some test expressions: includes.nixThis tests compiling code that uses
nifs.nixThis is just a bunch of modules I could think of that use nifs
How I tested: $ NIX_PATH=nixpkgs=$NIXPKGS_CHECKOUT nix-shell nifs.nix --run erl For cowboy, I just tested |
BTW I had to update |
6b494f0
to
1f1b199
Compare
@dlesl Wow! I did not expect it to work :) I have a non-trivial private Do you know what causes |
It had some hooks in its |
As I understand it, this is good to merge. Leaving this open a little more in case somebody wants to comment. |
@happysalada I agree, I think it's ready to merge, but I would be interested to hear how things went with @gleber's private rebar3 project first. I did a bit more testing by just going through the top packages on hex.pm, and adding those that looked interesting (in an admittedly non-scientific way) to https://github.com/dlesl/build-rebar3-hex-test and was able to compile them all with this (and that didn't work with the |
@dlesl Sorry it took a while. I tried building the app with this and could not make it work. I am actually not sure what I am doing wrong here. I've distilled the problem into a standalone repo at https://github.com/gleber/buildRebar3-test-app which pins Nixpkgs to https://github.com/dlesl/nixpkgs/tree/rebar3-bare-compile2 using Niv. Please take a look what happens when you do:
|
@gleber This
default.nixlet
pkgs = import (builtins.fetchTarball
"https://github.com/dlesl/nixpkgs/archive/rebar3-bare-compile2.tar.gz") { };
depsFn = { builder, fetchHex, fetchFromGitHub }: rec {
ranch = builder {
name = "ranch";
version = "1.7.1";
src = fetchHex {
pkg = "ranch";
version = "1.7.1";
sha256 = "sha256-RR2FJ3h99xbZncNhYvygWTSRXbC2FBu9rC6o08evx9c=";
};
beamDeps = [ ];
};
cowlib = builder {
name = "cowlib";
version = "2.9.1";
src = fetchHex {
pkg = "cowlib";
version = "2.9.1";
sha256 = "sha256-5BddwkCnDZlhVhYIkeHGIjjt4XKeRXQL3TgGTa1HYXA=";
};
beamDeps = [ ];
};
cowboy = builder {
name = "cowboy";
version = "2.8.0";
src = fetchHex {
pkg = "cowboy";
version = "2.8.0";
sha256 = "sha256-RkPk+6dKyW1NFSx1gD3m+tCz+l3zVMca/dbL7rFfrIo=";
};
beamDeps = [ cowlib ranch ];
};
lager = builder {
name = "lager";
version = "3.9.1";
src = fetchHex {
pkg = "lager";
version = "3.9.1";
sha256 = "sha256-P1m6daBKmeXxi/kcifRtzlNvg8bLQV/ibm51pivvN9w=";
};
beamDeps = [ ];
};
};
deps = builtins.attrValues (depsFn {
inherit (pkgs) fetchHex fetchFromGitHub;
builder = pkgs.beamPackages.buildRebar3;
});
appsDirs = pkgs.lib.filterAttrs (_: type: type == "directory")
(builtins.readDir ./apps);
mkApp = name: src:
pkgs.beamPackages.buildRebar3 {
inherit name src;
beamDeps = deps;
version = "none";
};
apps = pkgs.lib.mapAttrsToList mkApp
(pkgs.lib.mapAttrs (name: _: ./apps + "/${name}") appsDirs);
in pkgs.stdenvNoCC.mkDerivation {
name = "test-app";
version = "0";
buildInputs = with pkgs; [ makeWrapper ] ++ apps;
unpackPhase = "true";
installPhase = ''
mkdir -p $out/bin
cat <<EOF > $out/bin/test-app
#!${pkgs.erlang}/bin/escript
main(Args) ->
myapp:main(Args).
EOF
chmod +x $out/bin/test-app
wrapProgram $out/bin/test-app --set ERL_LIBS "$ERL_LIBS"
'';
} |
Update: erlang/rebar3#2552 has been merged making it possible to use ERL_LIBS with |
Let's merge this and take the discussion around building projects in that other PR. |
Motivation for this change
Things done
sandbox
innix.conf
on non-NixOS linux)nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
./result/bin/
)nix path-info -S
before and after)