How to reload all OTP code when developing an OTP application? - erlang

While I'm learning OTP I've been making a lot of changes to the .app and .erl files and re-running my application to see the effect of the changes.
I've tried the following sequence of commands to pick up all my new changes, but it doesn't seem to work:
Compile src files ...
erlc -o ebin src/*.erl
... followed by this is the erlang shell:
application:stop(my_app).
application:unload(my_app).
application:load(my_app).
application:start(my_app).
However, this doesn't seem to work. The only way I have found to work is to exit the erlang shell, recompile the app and then run application:start(my_app)..
Is there an easier way of picking up my changes?

Calling application:load(App) (after stopping and unloading) will reload the .app file but not the modules. As the documentation says: "Note that the function does not load the actual Erlang object code."
If you were to do an upgrade using releases, you would ship an .appup file that specified which modules to reload on upgrade to the new version (no need to reload all of them if only one or two have changed), but if you're just developing and don't want to stop and restart everything, you'll have to set up your own help functions for reloading code.
Edit: Since OTP 20 (2017), the interactive Erlang shell now has the lm() function for loading all modules whose .beam files have changed, so there is no need to roll your own utility function for this anymore. See https://erlang.org/doc/man/c.html#lm-0

Related

:erlang.load_nif/2 finds shared library file inside original project but can't find it if the project gets imported

I've build a small elixir application that uses NIF functions to execute some c++ code.
The nifs are loaded via:
def load_nifs do
:erlang.load_nif('<relative_path_to_lib>/<lib_name>', 0)
:ok
end
and this works fine.
Now I want to integrate this app into another project. The problem now is that load_nif throws:
Failed to load NIF library: '<relative_path_to_lib>/<lib_name>.so: cannot open shared object file: No such file or directory''
although nothing has changed. I checked the deps folder and the shared library files are exactly where they are supposed to be, so the dependency seems to be loaded correctly. I also tried putting the .so files into the same folder as the module that calls load_nif (and omit <relative_path_to_lib>/) as well as providing an absolute path, all to no avail.
Any help is appreciated, Cheers.
Relevant info regarding my system:
OS: Ubuntu 22.04
Elixir version: Elixir 1.13.0 (compiled with Erlang/OTP 24)
Update:
The issue does not seem to be that files are located at the wrong place, as it finds the files during the first test run after compilation.
However, the error occurs when I repeat the run. It seems that the error message is wrong, since no files are deleted during the test.
If I repeat the function within one test multiple times there's no problem, so the issue is not created because the NIF function is executed multiple times, but because the test that contains the function is repeated multiple times.
Solution:
I still have no idea what causes this behavior but after putting the .so files into a priv directory and accessing them via
:erlang.load_nif(:code.priv_dir(:<app_name>), 0)
the tests pass.

ng-boilerplate LESS files are not compiling to the CSS file in build directory

The CSS (from LESS) is not rendering or compiling in my ng-boilerplate app.
I'm creating an app using ng-boilerplate and rails using these tutorials here, and we've integrated a working rails server with the angular. The angular is working on any page... as in, we can use:
$scope.animal = "dogs"
and
<div> I like {{animal}}! </div>
to get
I like dogs!
However, the Less and CSS (which was copied and pasted from a functional ng-boilerplate app without rails where it worked and compiled from all the different directories just fine) is not compiling to the build directory nor rendering. In fact, in this new app (the one with the rails), not even the original css/less from the ng-boilerplate template will compile or render.
We tried using the following commands, as the tutorial suggested, which created weird nested build directories (a build inside the build inside the build) and didn't fix the problem.
cd public
ln -s ../build UI
Meanwhile, the UI folder is linked to the build folder using a symlink but...
The LESS (from different files in different directories) is all supposed to compile to one CSS file called ng-boilerplate.css (which it did in the original app without rails), and instead there's a file called ng-boilerplate-0.3.1.css, which is empty. I tried renaming that, but it re-renames itself back to the 0.3.1 one every time grunt builds it.
I'm using rails version 4.2.1 and ruby says it's 2.1.0p0.
I hope that you have already found a solution, as I realise that this post is quite old. However, since this question appears reasonably highly when I was google searching, I felt it should have an answer.
When using ng-boilerplate, you need to be aware that, although it's compile process finds all of your JS files and makes nice compiled JS code, the same is not done for the LESS files in their build process. If you look in the directory 'src/app/less/' and view the 'main.less' file, you can see a small note mentioning that he would like to automate this process. Instead, it is at this point that you unfortunately need to manually import all of your LESS files.
The LESS way to import files is this for anybody who is unsure:
#import '../app/less/fileToImport.less'
The path can be relative or absolute.

Why does my program not run outside the source folder?

I'm writing a program using Lazarus + Ubuntu 12.04.
I compile the program and run the binary. It works, There are also reports created using LazReports and they all work fine.
But the moment I copy the binary to another folder like /usr/local/bin, it works without the reports. When I try to view a report, I see a warning like this:
[WARNING] SetAlphaBlend called without handle for
frProgressForm(TfrProgressForm)
But the program continues... I think this is to do with LazReport needing some sort of file in the current location but I cannot make out what it is.
Any idea on how I can get this working?
Thanks!
Voila!
The solution was to copy the .lrf (report) file to the folder that held the binary of my program.

Dynamically loading erlang header files

I know that you can dynamically load erlang beam files in an erlang node using "l(module_name).". My question is is it possible to load ".hrl" files the same way or some such similar without having to restart an erlang node
I am not sure this is possible, but just based on understanding, when you try to define an macro in url and you want to modify it, the compiler replaces the macro during the compilation of the erlang file by replacing the the macros that are defined in header.
Logically you should rebuilding you code and deploy it again. I don't understand a reason why you need hrl files to be loaded dynamically if you have an option for replacing the entire code dynamically. IMHO all you need to do is rebuild and upgrade and this also can be done without restarting erlang node.
".hrl" files - used only by compiler on compile sources. It is not is runtime files.
You can use popular auto-reloader by Mochi team
https://github.com/mochi/mochiweb/blob/master/src/reloader.erl
put them in your src/ folder and add to your exec erl -s reloader option

QMake and a .pro file

I've downloaded a package and am trying to build/install it. The project's wiki page has a command that looks like
qmake VAR=/path/to/something/ project.pro
It says that this command should tell qmake to generate a make file. Instead, I'm getting
qmake: Nothing to be done for `project.pro'.
Why is qmake not generating the make file like it's supposed to?
Without knowing the project in questions or the contents of the project (.pro) file, it is difficult to diagnose. One possibility is that qmake was already run, or that the files it is to generate are included with your download. In these circumstances, there really is nothing to be done for said project.
As a side note, may I recommend downloading "Qt Creator" and opening the project file in there? Qt Creator tends to make Qt development and project building a lot easier.
I just answered my own question... apparently there is more than one qmake. On my system, we're using a qmake: distributed parallel make, scheduling by Grid Engine. I found /etc/alternatives/qmake which is the QT qmake...

Resources