I am new to rebar and erlang in general and read that we can use other modules by specifying them as deps in rebar.config file. I am able to compile them properly but not sure how to use them in my module. If I try to use them, I get an error that the function is not available.
How can I use the functions from the modules that are in deps in my modules.
Thanks!
You have to tell code server where to find compiled code. I usually have in MakeFile something like:
run:
erl -pa ebin -pa deps/*/ebin
You usually need to specify application:start(appname) or similar in your application file before using them (to get some application to start up) and try to define them in the app.src file also, after that you should be able to use them
Related
I am creating an erlang application named (app_main) that will be initializing two other erlang applications ( app_1 and app_2 ):
Following is the structure of the code. Notice that app_1 and app_2 are under the deps directory and each have their own deps directory, which expand into further other nested references to other code directory structures, etc...
/app_main
/ebin
/main.erl
/deps
/app_1
/ebin
/deps
/...
/app_2
/ebin
/deps
/...
To start my app_main application, I am issuing the following command:
erl -pa ./ebin ./deps/*/ebin ./deps/*/deps/*/ebin -s app_main
The problem is that I need to know how many levels of nested deps references I may have... This sounds a bit illogical to me and I am wondering if there are better ways to achieve this.
For instance, would rebar be useful identifying nested rebar configs and add all dependencies to the app_main's deps directory automatically ?
Rebar is very useful for managing dependencies. You can define app 1 and 2 as dependencies for your main app and, assuming app 1 and 2 have their dependencies defined in Rebar, it will install them and their dependencies in your deps folder
See Rebar's documentation here: https://github.com/basho/rebar/wiki/Dependency-management
How are you specifying these dependencies, where do they come from, and how are you compiling them? When you're using 3rd party applications they will, in general, manage their own dependencies. Therefore, you should only ever to have start the shell like this:
erl -pa ebin deps/*/ebin
Both Rebar and erlang.mk are great tools for managing your applications and their dependencies.
I have a common test suite and I need to perform it with rebar. Usually it is done with command
rebar ct suites=mysuite
But there is an obstacle. My suite is required configuration file and I need to specify it when I am performing tests. ct_run allows to do it with
ct_run -config <configfile>
Does anybody know how can I specify config file with rebar?
I'm looking at the source code, and it doesn't look like you can specify one by name.
It's hard coded to look in your test directory for the following files:
test.config for the -ct_config option
app.config for the -config option
If that doesn't work for you, you could probably patch it to take a rebar.config parameter instead.
Update: use rebar3 instead of rebar
Add following to rebar.config:
{ct_opts, [
{config, "./config/test.config"}
]}.
More details here.
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 :)
In my project, i want to use mysql so i checkout this https://github.com/dizzyd/erlang-mysql-driver. I want to know how install the application so that my project can interact with it
Have a look at "rebar" - https://bitbucket.org/basho/rebar/wiki/Home
It can be used for installing dependencies, and for creating independent releases.
And a quick look at erlang-mysql-driver, that you want to use, shows that it is also using rebar for its dependency management.
rebar may complicate things if you have already started laying out your app (done some coding already) or if you are a newbie , however, if your project is an erlang/OTP app, then i suggest that you first organize you code according to the recommended file system like this:
MyProject--/src
/ebin
/lib
/include
/priv
/doc
/examples
/test
/Emakefile
The Emakefile is an important file. It maynot have a file extension. It enables the BIF: make:all() to compile all the erlang source modules you point it to and transfers all the .beam files to the destination you want.
For example: is i want all the modules in src to be compiled and transfer the beam files into ebin, i enter this into the Emakefile
{"src/*", [debug_info, netload,strict_record_tests,warn_obsolete_guard,{outdir, "ebin"}]}.
In that case i would start the erlang shell with its pwd() pointing in the folder MyProject, to enable the function call make:all() to find the file Emakfile so as to compile all my src files.
Now, suppose you have another OTP app which you want to have as an extra package in your build. If it OTP-like arranged as i have showed you, and not yet built i.e. not yet made, i mean with only its src and its folder ebin are empty or it ebin may be containing a .APP file already. Then you copy this OTP application into your lib folder, so that your application looks like this:
MyProject--/src
/ebin
/lib/some_otp_app-1.0
/include
/priv
/doc
/examples
/test
/Emakefile
then we would change our Emakefile to look like this:
{"src/*", [debug_info, netload,strict_record_tests,warn_obsolete_guard,{outdir, "ebin"}]}.
{"lib/some_otp_app-1.0/src/*", [debug_info, netload,strict_record_tests,warn_obsolete_guard,{outdir, "lib/some_otp_app-1.0/ebin"}]}.
In the folder MyProject, you can put a shell script that will start your project and add all relevant ebin paths to your nodes code path.the sh script may look like this:
#!/bin/bash
erl \
-name my_node#my_domain \
-pa ./ebin ./lib/*/ebin ./include \
-mnesia dump_log_write_threshold 10000 \
-eval "make:all()"
You can save this file as start_project.sh. Hence as you make changes to your source code, even at the time of starting your project, when you run the sh script with your terminal path pointing into the folder: MyProject, you do this:
$pwd
/export/home/your_user_name/MyProject
$sh start_project.sh
This would start your project at the node you entered in the script and would compile all src files which were changed when it was off. Not only this, you can as well call: make:all() in your shell whenever you make cahnges to your src code. then you would call: l(some_module) after making so that the erlang vm reloads the new object code of the compiled module.
So, your entire project will now appear like this:
MyProject--/src
/ebin
/lib/some_otp_app-1.0
/include
/priv
/doc
/examples
/test
/Emakefile
/start_project.sh
So if you substitute the erlang driver for mysql application with this "some_otp_app-1.0", everything will be fine. success!