I am trying to integrate rebar3 into my project, but for some reason, I can't make it find and resolve dependencies when running the app.
Dependencies are downloaded and put in the respective folders in the project and the app compiles without errors, but then functions from dependencies are undefined if I call them from inside the project app or from the Erlang REPL.
I think I am missing some small point, but can't figure out what exactly.
My rebar.config is as simple as this:
{erl_opts, [debug_info]}.
{
deps, [
{jsx}
]
}.
{cover_enabled, true}.
The project repo is here.
Can you please share a link to a simple example project where dependencies are present in the rebar.config and are successfully used in the app code?
but then functions from dependencies are undefined if I call them from inside the project app or from the Erlang REPL
In order to load all the dependencies in the REPL, you need to start the REPL using rebar3 shell. rebar3 shell invokes erl with the correct arguments so that the paths of all of the project's dependencies are added to Erlang's Code Path. The command also accepts many flags and arguments; you can see the full list and description by running rebar3 help shell.
Related
I'm trying to compile my app (app_1) with a dep from another project (proj2) which has some apps (e.g. app_a, app_b, app_c...).
proj2 is has an apps folder in which there are the said apps (app_a etc.).
I'm trying to get app_a, but it also depends on app_b.
Whatever I do, I cannot seem to get it to work.
Using this in rebar.config of app_1:
{deps, [{proj2, {git, "git://github.com/scm/pr/proj2", {branch, "master"}}}]}.
I get
Dependency failure: source for proj2 does not contain a recognizable project and can not be built
Similar attempts with app_a instead of proj2, adding the /apps/app_a path etc. do not help.
Running rebar3 3.12.0.
Any help would be appreciated in how is it possible. Thanks
With rebar3 3.12.0, I don't think this is possible. You might be able to get it to work by using a rebar3.config.script file that downloads the dependency manually before putting it somewhere rebar3 can find it.
rebar3 3.14.0 introduced a git_subdir dependency type, which would look something like this:
{deps, [{proj2, {git_subdir, "git://github.com/scm/pr", {branch, "master"}, "proj2"}}]}.
This is mentioned in an example in the documentation on dependencies, but there aren't many details about it.
So if you're able to upgrade to a newer rebar3 version, it might be worth trying.
I am trying to use eflame to profile CouchDB code to investigate some performance issues in my application. I tried adding the eflame dependency in rebar.config.script (https://github.com/apache/couchdb/blob/master/rebar.config.script)
However I get an error when I run configure to build CouchDB (2.0.0) from its source:
Dependency not available: eflame-.* ({git,
"git://github.com/proger/eflame.git",
{branch,"master"}})
ERROR: compile failed while processing /tmp/couchdb: rebar_abort
Makefile:67: recipe for target 'couch' failed
My change in the rebar.config.script in CouchDB source was adding a single line below (with a comma in the previous line of course)
{eflame, {url, "git://github.com/proger/eflame.git"}, {branch ,"master"}}
I tried various combinations of specifying the dependency as shown in rebar documentation but without any success.(I took into account the order of arguments in the MakeDep function in the rebar.config.script and accordingly tried to pass the arguments)
Any pointers to resolve will be greatly appreciated. Thanks! (Note : I am not familiar with Erlang or rebar , so please excuse any obvious mistakes)
It looks like what's missing in your case is the second argument of the tuple, that requires the version number. You can use an asterix there if you don't need a specific one:
{eflame, ".*", {git, "git://github.com/proger/eflame.git", {branch, "master"}}}
Alternatively, if you are using rebar3, you could use the hex package:
{eflame, "1.0.1"}
There were two issues here
1)The version of rebar I was using was not > 1.5
2)I had to add get-deps before doing a rebar compile as given in this rebar dependencies issue post
So assuming that i have an rebar app structure and in deps folder i have a number of dependencies, some are library applications and some are applications that need to be started. I usually do it like this:
start(_Type, _Args) ->
code:add_path("../deps/depapp/ebin"),
{ok, _} = application:ensure_all_started(depapp),
Is this the correct way to do it in an development environment ? How about in production ?
What you used is not necessarily a wrong way but could exposes some problems. For instance this way you have no choices for starting dependent applications which must be started before your application.
So there are other alternatives for loading or starting dependent OTP applications or libraries.
1) Using erl command line flags:
erl -pa ebin deps/*/ebing -s your_dep_app start -s your_app start
2) Using package manger for handling it:
As an example Rebar as a package manager can handle it for you. What you need is specifying your application dependencies in rebar.config and then issue rebar get-deps for Rebar2 or rebar3 compile for Rebar3. Following is a snippet of a sample config file for Rebar3:
{deps,[
%% Packages
rebar,
{rebar,"1.0.0"},
{rebar, {pkg, rebar_fork}}, % rebar app under a different pkg name
{rebar, "1.0.0", {pkg, rebar_fork}},
%% Source Dependencies
{rebar, {git, "git://github.com/erlang/rebar3.git"}},
{rebar, {git, "http://github.com/erlang/rebar3.git"}}]}.
For more information about Rebar dependency manager take a look at this link.
Also for starting or loading them using Rebar you can make a release and let Rebar start or load them. Following is a snippet of a sample Rebar config file for making a release:
{relx, [
{release,
{your_app, "0.1.0"},
[your_dep_app_1,
{your_dep_app_2, load}]}]}.
This config loads and starts your_dep_app_1 but just loads your_dep_app_2. For more information about Rebar release manager take a look at this link.
I wanted to integrate Elixir into our project, and the good old codes don't use rebar, so I think writing the rules for building .ex files into Emakefile may be a good idea, yet the man page here didn't mention anything relevant.
Edit:
Our team works mainly in Windows environment, but the deployment will be done on Linux servers, so I need a cross-platform solution. Since Erlang itself is cross-platform, I wanted to do it with erl -make command.
Of course I can write a Makefile, but then I'll need a build.bat or something alike to build the code in our developing environments, since we don't have make command on our dev' machines.
Anyone have a better idea?
Update:
In case anyone wants to know, I'm doing it this way:
Copy the lib/elixir directory in the Elixir source tree to our source dir, say some_project/src/tools/elixir.
Add some_project/src/tools/elixir/src/elixir_transform.erl and some_project/src/tools/elixir/src/* to the Emakefile, in that order. Set the output dir to some_project/ebin (All the other .beam files are located there).
Copy src/elixir.app.src in the Elixir source tree to some_project/ebin/elixir.app, and edit it to fix the version code.
Build the Erlang code by running erl -pa ebin -make, in some_project dir.
Build the Elixir compiler by running erl -pa ebin -s elixir_compiler core -s erlang halt
Now we have a working Elixir environment in our code, and I use the following escript to build our custom .ex files:
%%! -pa ./ebin
main(_) ->
ExList = [
<<"source_1.ex">>,
<<"source_2.ex">>,
<<"source_3.ex">>],
application:start(elixir),
gen_server:call(elixir_code_server, {compiler_options, [{docs, true}, {debug_info, true}]}),
[elixir_compiler:file_to_path(F, <<"./ebin">>) || F <- ExList],
erlang:halt(0).
If you want to explicitly compile Elixir, I would go with the Makefile approach since it will always be supported by Elixir. However, I would recommend the precompiled binaries or even assume Elixir is installed in each developer machine. You can even add a task to your Emakefile to guarantee everyone is using the proper Elixir version.
Finally, about compiling your own Elixir code, I would recommend simply using mix. mix is a binary that ships with Elixir and you can simply do ./src/tools/elixir/bin/mix compile from your Emakefile.
In case using mix is not possible, you should use the parallel compiler, since it will compile files using all cores available in your machine and it will automatically detect and solve dependency in between files. Here is an example of calling the parallel compiler from erlang:
https://github.com/basho/rebar/pull/347/files#L1R62
The API is very simple. It expects a list of file names to compile as binary and the directory to output files to as another binary.
I'm very new to Erlang and using Rebar but we are doing a project that needs to connect to a Riak server, for this I'm trying to use the Riak Erlang client (riakc_pb_socket etc).
The problem is that the shell that is started from my start up script (generated by Rebar and reltool) does not include the dependencies I've specefied in my rebar.config (they download just fine when I do rebar get-deps however). I know that I can include them to my path when I start the shell myself (erl -pa PATH) but since this needs to be done automatically I wonder how I achive that, can I specify such behavior with Rebar or do I need to do code loading from inside the application?
Thanks to the link provided by Roberto Aloi I was able to figure out how the reltool works and after some working I found that all I had to do was add this line
{app, riakc, [{mod_cond, app}, {incl_cond, include}]},
To my reltool.config and now it works, so thanks a lot :)