Recently I have implemented dependency resolution for babel as well as the support for 'app' binary packages, in other words packages which require building. (For more information take a look at the readme)
fowl raised an issue on IRC in regards to 'app' packages depending on external files which also have to be installed, a good example of this is Aporia which requires a share directory be installed together with the 'aporia' executable.
As of right now all packages are installed to ~/.babel/libs/ into directories which take the form of pkgname-ver. Executable files are installed separately into ~/.babel/bin. This means that the applications would need to take special steps to ensure that they can find their extra file dependencies by searching for them in ../libs/pkgname-ver/. This is not ideal.
After discussing this issue with fowl yesterday on IRC and discussing it with Araq today, I have decided that the directory structure should be changed so that all packages are installed to ~/.babel/pkgs/pkgname-ver. On linux, binaries will then be symlinked to ~/.babel/bin/ which will mean that users will be able to add ~/.babel/bin/ to their $PATH and use the apps easily. On Windows, the packages will not be symlinked and instead the $PATH env variable will be edited automatically by babel (unless specified otherwise by the user).
This approach should be fairly intuitive, and should hopefully please everyone.
Let me know what you think!
I don't like the idea of changing the PATH var automatically. So another cross platform approach would be to have a runner app which would load the executable from the the installed package and version:
babel package app param1 param2 ...
this is how the haxelib package manager from Haxe does it (more or less).
and if you don't like the extra "babel package" you could automatically create a stub exe (or shell script / batch) in the bin directory which loads the corresponding exe from the package path.
It doesn't change PATH automatically. There is $babelDir/bin which is supposed to be in your PATH. On Linux, new symlinks will be added to $babelDir/bin, no such mechanism is possible on Windows afaik so your PATH can be updated by Babel if you ask for it.
I don't really like the idea of a runner app and I fear it will lead to the impression that Nimrod doesn't generate native code but needs a VM.
Adrianv's solution seems to me to be the simplest. In fact I quite like it. However it would result in some redundant calls: babel aporia aporia
The PATH environment variable on Windows would certainly get long quite quickly... so perhaps this isn't the best idea. The alternative is to use symlinks on Windows too, but i'm not sure how well those are supported.
ok, so on Windows babel will prompt the user whether they want the binary added to their %PATH%. Does that sound alright?
On linux, symlinks will be used.
@Araq: The problem with changing the PATH var is: 1.) It get's long - but this is just an aesthetic reason. 2.) You can change only the PATH var of your environment, or for new processes. Any running processes need to be restarted to see the change of the PATH var. This can be confusing.
symlinks only work from Vista up afaik. But it is also possible to create a .lnk file which points to the binary. But in order to start the binary from the command line you need to add .LNK to the PATHEXT environment var. So there is no benefit over a batch file - it makes things even more complicated.
@dom96: adding the binary to the PATH can make problems since it changes the context of the binary. If the binary depends on a .dll which is in the package directory it won't work. To make the calls look better I would do:
babel aporia run
or to make aporia permanent:
babel aporia link
(or any other better verb) - this will make the batch file in the bin directory - and then
aporia
@dom96: adding the binary to the PATH can make problems since it changes the context of the binary. If the binary depends on a .dll which is in the package directory it won't work.
This is precisely the problem we are trying to solve here. However, won't this solution work? The binary will be in $babelDir/pkgs/package-ver together with any other files that it needs. I'm not sure if dynlib would find dlls in this case, but I think those should be installed separately anyway. Other files can be easily loaded by using getAppDir().
the longer I think of, the less I like the idea playing around with the PATH var.
Some month ago I had a customer who called because our software crashed for some unknown reasons. First my service technician spent some time checking everything without success. Then he called me for help and together we found it was an old microsoft .dll which was loaded into our program. We checked the .dlls in the system32 directory but they had all the right version numbers. Than we looked at the PATH var and checked every directory which was in it - and found that there was another software package which had this old .dll in its directory. Now we asked the customer and he told us, that the technicians of the other company had worked on his server the day before.... So what happened - they had changed the PATH var to point to their directory out of some reason and so made the server unusable.
When I look at the scenario with babel, we will have a %babel%\bin dir with babel and all its helper files in in. The we want to install aporia version 1.0. This will create %babel%\aporia-1.0 with aporia in it and the needed .dll like libcurl.dll
In order to be able to start aporia we have two (at least) options. Put %babel%\aporia-1.0 to the PATH or create a starter prog for aporia in %babel%\bin. Now what is better ?
a) If you add %babel%\aporia-1.0 to the PATH you have 2 options - 1) add it to the end or 2) add it to the front. adding to end is less dangerous because if there is another directory on the PATH which contains libcurl.dll you won't temper with the configuration of the other application. Ok - we decide to add %babel%\aporia-1.0 to the end of the PATH because this looks safer. After some months we install update to version 1.1. %babel%\aporia-1.0 is somewhere in the middle of the PATH var because we have installed already 100 babel packages. Besides the problem to find the right entry inside the PATH var for the last aporia installation (because the entry could be %BABEL%\aporia-1.0, or %BABEL%\aporia-%APORIAVERSION% or c:\babel\aporia-%APORIAVERSION% or ...) we now have 3 options - 1) replace the entry in its original position 2) add to the end 3) add to the front. Replace seems to be the logic option, to the front is evil, to the end seems to be Ok too - really ? none of the 3 is Ok and can bring the system down.
to bring it to the point: I hate any software which plays around with my PATH var !
the API for changing a PATH var is even worse ;-)
I think a solution which does not depend on changing the PATH var is simpler for the user than a solution which changes the PATH var and does not do the expected ?!?
and because babel is not a general installer it won't update lnk files you have created on the desktop or file associations for .nim files to aporia for example. What will happen after you have upgraded aporia from version 1.0 to 1.1 ? - you will still open 1.0 when you double click on a .nim file or a desktop lnk
a stub exe is the poor man's version of a symlink
The API is just messing around with the registry iirc which means a nice helper module may come out of this as a side effect. ;-)
You still haven't convinced me really (it's not our job to fix Unix's/DOS's design mistakes), but I give up and let dom96 decide.
which means a nice helper module may come out of this
maybe I can help here - I have a young student doing his internship next month in our company and if he is good at coding I plan to let him do some work for nimrod and a registry module inspired by the pascal TRegistry or TRegIniFile class would be handy.
Hi. Are you aware of App Path registry key ? HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/App Paths
It can be used to adjust PATH per application on windows XP and later.
http://msdn.microsoft.com/en-us/library/ee872121%28VS.85%29.aspx#appPaths
ok, so I will still think about how to go forward with this, but I won't make a decision until next week as I will be busy until next thursday.
If anyone has any other ideas please let me know.
I have gone ahead and implemented adrianv's solution on Windows: a .bat file is generated which executes the correct executable. It looks like that approach works well, thanks for the great idea! I also fixed the remaining Windows bugs with some help from @onionhammer who fixed the openssl module.
So now it's up to you guys to start creating packages!
As always, feedback is greatly appreciated and please report any bugs you find on github.
In the future I will document babel in even more details and I am planning on adding the ability to specify a list of files/folders to install in the .babel file as currently everything will be installed with the exception of the files, directories and file extensions you specify using SkipFiles, SkipDirs and SkipExt respectively.