Cabal: installing a Bash script alongside a library - haskell

I have a non-Haskell executable (bash script) that I would like cabal to install in ~/.cabal/bin along with my Haskell library. How can I achieve this simply with cabal?
Edit: as I mentioned in a comment below: installing specifically to ~/.cabal/bin isn't crucial, I just need the script to be available in my library.

You can use cabal's data-files field to have some extra files installed, and then use the getDataFileName function created by cabal to retrieve the file. Details are available in the documentation and this blog post.

Related

How do I install Bash completions for my Haskell package's executable?

The Haskell package optparse-applicative provides instructions for creating a bash completion script for an executable, and then suggests that this
should be shipped with the program and copied to the appropriate directory usually (/etc/bash_completion.d/) during installation.
I wold like to ship and install this script with my package, along wit the executable. How do I instruct Cabal (in my .cabal) to
include the bash completion script along with my package, and
copy the script to /etc/bash_completion.d/?

Cabal: executable data-files

I want to include an executable file in the cabal data-files section to execute it as a subprocess in my Haskell program.
The file's there, getDataFileName works for it, but it lacks the executable bit and so trying to run it with System.Process.createProcess fails with permission denied.
Is there a way for cabal to preserve the execution permission of the file? Is there another clean way to solve this?
As summarized in some discussion on cabal patches, the current (underdocumented) state of play is that one should use both a copy and an install hook, since one or the other will get executed.
Edit: After some digging, there's an old ticket on libexec support in cabal, which would be a very nice solution if it were implemented.

How to create a Cabal Sandbox

I want to build an environment for tutorial programs for Haskell, as I want to try and learn the language. So I read about Cabal and already have it on my machine, because I updated pandoc sometimes. I followed some tutorials, which state that you should run:
$ cabal sandbox init
$ cabal install --only-dependencies
$ cabal build
To have the environment set up. However, if I try so, I receive the following message:
$ cabal sandbox init
Writing a default package environment file to
/home/xiaolong/development/Haskell/cabal.sandbox.config
Using an existing sandbox located at
/home/xiaolong/development/Haskell/.cabal-sandbox
(Output of ls command)
$ ls
cabal.sandbox.config
And then:
$ cabal install --only-dependencies
cabal: Error reading local package.
Couldn't find .cabal file in: .
Huh? Suddenly there needs to be a .cabal file? This is puzzling to me. What steps do I need to take to get an environment, in which I can simply install packages and then use that environment to run code of any tutorials I choose?
This is another tutorial suggesting the described workflow. Something is there I am missing.
(I am under the impression, that cabal sandboxes are comparable to python virtualenvs, being useful in the way, that one doesn't need to install packages system-wide, but can instead install them in a directory and then use that environment to run programs.)
You need to have a cabal file inside it which describes your project's name, package dependencies, license etc. A cabal file can be generated using cabal init which is followed by a series of question you have to answer.
Once the initial cabal configuration file is created, you can go inside the package directory and create sandbox inside it using the commands you have described above.
You may be also interested in Stack which is another alternate (better, if you would ask me :)) tool for developing Haskell projects.

Yocto do_package() syntax to add recipe with scons.py

I am trying to include the libjsoncpp package into my Yocto build, which is not currently included in Yocto's package list. I downloaded the source files from http://sourceforge.net/projects/jsoncpp/files/jsoncpp/. The package does not come with an INSTALL script but instead uses scons.py. How can I write the install script for this as a recipe?
Thanks
I downloaded the jsoncpp-src-0.6.0-rc2.tar from that link and didnt see any scons.py, even though the README says it should be there. I did however look through the SConstruct included therein, which is the main SCons build script.
To be able to use it, you will need to (obviously :) ) install Python and SCons, as indicated in the README:
(I would recommend the latest version of SCons, which is 2.3.0, hopefully its compatible)
Building/Testing: =================
JsonCpp uses Scons (http://www.scons.org) as a build system. Scons
requires python to be installed (http://www.python.org).
You download scons-local distribution from the following url:
http://sourceforge.net/projects/scons/files/scons-local/1.2.0/
Unzip it in the directory where you found this README file. scons.py
Should be at the same level as README.
python scons.py platform=PLTFRM [TARGET]
You should then be able to invoke scons from your scripts as follows:
$ scons -f <path to json>/SConstruct platform=linux-gcc
Substitute linux-gcc with your platform. Read through the SConstruct and search for platform to see all the possibilities.

How to override anaconda/kickstart package ordering?

I am building a bootable ISO to be used to install a Linux image (Oracle Linux, 5.8). This is using anaconda with a kickstart file to select the packages to be loaded. Some of these packages are failing with dependency problems in their %post section.
Eg, this is seen in /root/install.log after the installation is complete:
Installing thirdparty-tools-1.00-09.noarch
/var/tmp/rpm-tmp.97891: line 1: ln: command not found
/var/tmp/rpm-tmp.97891: line 2: ln: command not found
/var/tmp/rpm-tmp.97891: line 3: ln: command not found
/var/tmp/rpm-tmp.97891: line 4: ln: command not found
error: %post(thirdparty-tools-1.00-09.noarch) scriptlet failed, exit status 127
I'm trying to find out if it is possible to control/override the package ordering, without editing any RPMs to add dependencies. I've been looking through the anaconda / kickstart documentation (https://fedoraproject.org/wiki/Anaconda/Kickstart#Chapter_3._Package_Selection), and searching extensively elsewhere, so I think that the answer is actually 'no, you can't do this'. Which would be a shame.
The problem is that I am trying to include various third-party RPMs, which are not under my control and which have been digitally signed. These include some processing in a %post section. This processing requires some standard Linux commands, eg 'ln', 'touch', etc, which are supplied within the coreutils package. The third-party package does not currently include a dependency on the coreutils package, though obviously it should really. Anaconda uses its own partial ordering algorithm to choose what order to install these packages, and the third-party packages are being installed before the coreutils package. Obviously, the proper solution is to get these RPMs fixed by the third-party; however, this is likely to take too long.
I was hoping that their might be some hidden / un-documented option for the kickstart file, which could add in extra dependencies. Ideally, I'd like to be able to add something like this to the %packages section:
%packages
#admin-tools
#base
#core
#system-tools
thirdparty-tools
# We would like to add some magic command to indicate a missing dependency
thirdparty-tools dependson coreutils
So, my question is: Is it possible to control or override the package ordering without editing any RPMs to add dependencies?
Very many thanks for any help.
If you can't get the source RPM, you can use rpmrebuild to re-create the RPM:
rpmrebuild -e -n -d . -p thirdparty-tools-1.00-09.noarch
This will bring up a re-created spec file in your default editor, where you can make changes to the requires lines. Also, you may want to change the package name too, so that your re-built version is differentiated from the upstream vendor's version (I usually append "-local" to the package name).
Your package "thirdparty-tools" needs to specify all of its requirements. If you can get a SRPM of this package, you can modify the spec to indicate that you need coreutils, bash, etc in your package.
If you can't modify this package at all, your best option is to create a wrapper package that has the necessary requirements. Just use your favorite editor to create a file "thirdparty-tools-installer.spec" and ensure you include coreutils as a requirement as well as "thirdparty-tools". You can refer to rpm.or for more information http://www.rpm.org/max-rpm/s1-rpm-build-creating-spec-file.html
Lastly, you can just do yum -y install thirdparty-tools in the %post section of Kickstart. It's uglier for sure, but it will probably work.

Resources