-
Notifications
You must be signed in to change notification settings - Fork 521
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
Including in a release Erlang and Elixir modules #2733
Comments
You may want to use https://github.com/Supersonido/rebar_mix as a plugin, which also provides hooks to consolidate protocols to get them included in a release. |
Can you provide an example project to reproduce? Sounds like it should work fine so I'd need to play around with it. |
@ferd, as far as I understand |
I found something interesting that may lead to a clue. If I have application
and one is symlinked in However, if instead I use the
So, I think the issue is that in the phase of producing |
Maybe it is an issue with |
I put together this example to illustrate the issue. There are two branches there $ tree
├── one
│ ├── rebar.config
│ └── src
│ ├── one.app.src
│ ├── one.erl
│ └── three.ex
└── two
├── rebar.config
├── rebar.lock
└── src
├── two.app.src
└── two.erl
tree _build/default/rel/two/lib/one-1.0/
_build/default/rel/two/lib/one-1.0/
└── ebin
├── Elixir.DecodeError.beam
├── Elixir.EncodeError.beam
├── one.app
└── one.beam As you see the Elixir beams are generated. This
$ rebar3 release
===> Verifying dependencies...
===> App one is a checkout dependency and cannot be locked.
===> Analyzing applications...
===> Compiling one
===> Missing artifact ebin/Elixir.DecodeError.beam
$ tree _build
_build
└── default
├── checkouts
│ └── one
│ ├── ebin
│ │ ├── one.app
│ │ └── one.beam
│ ├── include -> ../../../../_checkouts/one/include
│ ├── priv -> ../../../../_checkouts/one/priv
│ └── src -> ../../../../_checkouts/one/src
└── lib
└── one
└── ebin
├── Elixir.DecodeError.beam
└── Elixir.EncodeError.beam So, looks like the files get generated in the wrong place? If we comment out the
and the Elixir modules are not listed in the
|
@tsloughter, possibly you are right, the issue is with my use of |
@saleyn that would still be the right way to do it, it would just mean there is a bug. I was just suggesting a way you might be able to check by seeing if that value is wrong (like print it out in the shell command that runs the elixir compile) or searching for the beam file to see where it ended up. |
Thanks for the example, I'll try it in the morning. |
Somewhat unrelated, but is there an option in rebar to specify that a dependency is compile-only? E.g. if project |
IIRC the issue is probably that we moved _checkout directories' build directory to rebar3/apps/rebar/src/rebar_app_utils.erl Lines 256 to 261 in 048412e
This was done as part of #2276 and moves checkout deps' artifacts to This isn't great for portability, maybe there's a need to add a value to |
Indeed, the current approach doesn't seem to be portable, as the project shouldn't care about the method a dependency is defined (i.e. _checkouts, path, git, etc). Sounds like an oversight. |
@saleyn does it only not work when used as a checkout? I noticed in your example the |
Oooh, dammit, I forgot about that checkouts change. Isn't there an env var for the path to the lib... instead of needing to append |
Looks like there isn't. I think the change would be to use |
I have one more test case in question that doesn't involve
As can be seen, the beam files
|
Is there a workaround for the test case above that I can use with the current version of the For the sake of completeness I added the build example using the mix tool for a project with a dependency where both have a mix of Erlang/Elixir files, and the
|
Well for your example with one/three, I don't quite know. The environment setting does specify using absolute paths: rebar3/apps/rebar/src/rebar_env.erl Line 43 in dc3eca5
rebar3/apps/rebar/src/rebar_dir.erl Lines 39 to 43 in dc3eca5
But mix is doing its build by switching the directory, and so the hooks are run without knowing of the appropriate project hook. This ends up being in a bad situation where for Elixir's build model, the hook would need to be This is handled properly in the bare erlang compiler (which is used as an interface for other apps by changing the output directories in
If you output the whole environment when running the hook under mix, you'll also see that it generates a few extra values and others exist:
The sort of issue then is that when This can be done: diff --git a/one/rebar.config b/one/rebar.config
index c5ea44a..6a49ed8 100644
--- a/one/rebar.config
+++ b/one/rebar.config
@@ -1,5 +1,5 @@
{pre_hooks,
- [{compile, "elixirc -o $REBAR_BUILD_DIR/lib/one/ebin src/*.ex"}]}.
+ [{compile, "elixirc -o ${REBAR_BARE_COMPILER_OUTPUT_DIR:-$REBAR_BUILD_DIR/lib/one/ebin} src/*.ex"}]}.
{deps, []}.
The project will now be able to compile itself fine when called from within rebar3, but also to have the hook locate the code properly when a third-party build tool calls the shots and has a different file structure. |
Thanks @ferd. Maybe it would be better for rebar to set I followed your suggestion, and that fixed the example project two in branch
So, the Elixir output files are not placed under |
Well that value is not set by rebar3 ever, it is set for rebar3. It could for example be set by default but not used with the rebar3 bare compiler and be wrong to use in a hook then. I'm just assuming it won't be set, but that may be wrong. If someone had the value set, then hooks would start dumping files in the wrong environment. It's a hack I'd be hard pressed to support, and just a mess because we're trying to make two tools with different project structures agree when calling each other somewhat recursively. I don't know of a good long term solution, just shitty hacks. Maybe that patch would be acceptable. I guess chances are low enough? |
I guess the alternative is to introduce another variable (e.g. "REBAR_PROJECT_OUTPUT_DIR"?) that would be set to the target location of the current project's output directory. It would check for the |
Even if we changed the hook mechanism to specifically know which commands are run so that the value is overriden in case of a bare compile call so it runs the compile hooks and adds a Rebar3 just has the basic directories and not necessarily app-specific directories as variables in hooks (it would just link to The reason for that is that the hook variables are uniform across all hooks, and some hooks are not app-specific, and therefore can't link to a specific app's path. However the |
Maybe we could set a value that we guarantee only exists when being called by the bare compiler (we clear it if not) which would indicate a way to do that workaround? It still forces the logic onto the caller but I don't think there is such a thing as a transparent way to make it work. |
My objective is to be able to bundle a mix of Erlang/Elixir modules in one app, and make sure that if used as a dependency the app can be properly compiled whether the top-level build is done by |
Yeah. That's because they have entirely different compiling models. We're sort of stuck with that. Rebar3 gave full standalone modes to Mix and had to write custom compiler extensions to build Elixir properly, but it isn't perfect. I'm pretty sure we do a lot of things that are really painful for people using Bazel too. Regarding hooks: rebar3/apps/rebar/src/rebar_hooks.erl Lines 90 to 101 in dc3eca5
REBAR_APP_OUTDIR variable that could point to ebin/, but it wouldn't always be there if the hook is run on a multi-app level (eg. umbrella project top-level's compile hook).
I'm gonna have to think a bit about what would be a good way to make it work. I'm not sure it can be done without being a huge mess. |
I have an Erlang project that includes one Elixir
*.ex
file in thesrc
directory alongside with*.erl
files. I added this line to compile it:I can verify that it gets compiled fine with
rebar3 compile
. However when this project is used by another project as a dependency by being referenced via a link under_checkouts
, while the compilation of that project compiles it, making a release doesn't result in the compiled_build/default/my_app/ebin/Elixir*.ex
being copied into the release tree. What might cause it to ignore this file and how can I configure rebar3 (or mix if the dependent project is Elixir one) to include this file?The text was updated successfully, but these errors were encountered: