is it possible to stack cabal sandboxes? - haskell

Is it possible to "stack" cabal sandboxes or specify a "package.d" search path?
I'd like to install frequently used packages into a common sandbox that projects can use but don't update.
There is a world-file parameter in the cabal.sandbox.config file, but I couldn't find any reference to it in the Cabal source.

I believe world-file refers to an optional function by which cabal-install will maintain a plaintext list of packages requested for install, perhaps modeled on Gentoo's /var/lib/portage/world and similar systems. Cabal doesn't use that file for anything.
Your proposed "nested sandboxes" might cause the same problems as global or per-user installations: various packages would have to have a consistent set of dependencies.
It's possible to share a single sandbox between projects with the --sandbox=DIR parameter to cabal sandbox.

Related

It is possible for cabal.project to have two seperate build units?

I want to avoid cabal dependency hell problem.
I have three packges.
cabal.project
packages: schema/
client/
server/
Where client would depend on schema, and server depend on schema.
Building schema&client or schema&server would be fine.
But client and server have transitive dependency on two versions of same package.
Is it possible to group build units in cabal.
So I can build schema&client and schema&server separately to avoid the dependency hell in cabal, under a single cabal.project.
I believe it is impossible to use two conflicting packages in one cabal project.
As an alternative, you could consider making two project files, e.g. client.project and server.project, and switching between them using the --project-file cabal option.

Is there a way to install an Haskell executable as a dependency?

I found myself writing Haskell commands based upon other commands provided by other Haskell packages, but i could not find a way to install an executable as a dependency.
As far as i could see, Cabal and Stack provide ways for a package to depend on a library, but not on an executable.
If i want to build upon the functionality already provided by another executable, the only way i know is to ask the users to install that other package as well. That also means that i cannot assume the executable is there or its version is the right one.
So is there a way for an Haskell package to depend on an executable provided by another package?

How to gather the full config of a NixOS system?

I read a bit about NixOS and tried it these days, because I got the impression that it would let me configure a Linux with just one file.
When I used it, I installed a bunch of packages with nix-env, so they didn't end up in the configuration.nix, but I could simply uninstall them later and add them to the configuration.nix by hand. I there something like npm i -g <package> that would install this globally so it would end up in the configuration.nix and could simply be copied to another machine.
Also, I installed stuff like zsh and atom and they have an entirely different approach to configuration and customization (bashscript, javascript, less, etc).
Is there a way for Nix/NixOS to track the package-specific config too?
Does it already happen and I don't see it? Like the nix expression of the package knows where the package will store its config etc.
I mean, it's nice that I can add these packages to the main config and when using it at another PC I get the same software installed, but I still see myself writing rather much configs for the installed packages too.
If you want packages installed through configuration.nix, then the easiest way to accomplish that is to add them to the environment.systemPackages attribute. Packages listed in there will be available automatically to all users on the machine. As far as I know, there is no shell command available to automate the maintenance of that attribute, though. The only way to manage that list is by editing configuration.nix and manually adding the packages you'd like to have installed.
Nix does not manage package-specific configuration files. As you probably know, NixOS provides such a mechanism for files in /etc, but a similar mechanism to manage config files in $HOME etc. does not exist. The PR https://github.com/NixOS/nixpkgs/pull/9250 on Github contains a concrete proposal to add this capability to Nix, but it hasn't been merged yet because it requires some changes that are controversial.
Nix does not currently offer ways of managing user specific configuration or language specific package managers. AFAICT that's because it is a very complex and opinionated territory compared to generating configs for sshd etc.
There are however Nix-based projects providing solution to at least some parts of your question. For managing user configuration (zsh etc.), have a look at home manager.

Is it possible to compile a portable executible on Linux based on yum or rpm?

Usually one rpm depends on many other packages or libs. This is not easy for massive deployment without internet access.
Since yum can automatically resolve dependencies. Is it possible to build a portable executable? So that we can copy it to other machines with the same OS.
If you want a known collection of RPMs to install, yum offers a downloadonly plugin. With that, you should be able to collect all the associated RPMs in one shot to install what you wanted on a disconnected machine.
The general way to build a binary without runtime library dependencies is to build it to be static, ie. using the -static argument to gcc, which links in static versions of the libraries required such that they're included in the resulting executable. This doesn't bundle in any data file dependencies or external executables (ie. libexec-style helpers), but simpler applications often don't need them.
For more complex needs (where data files are involved, or elements of the dependency chain can't be linked in for one reason or another), consider using AppImageKit -- which bundles an application and its dependency chain into a runnable ISO. See docs/links at PortableLinuxApps.org.
In neither of these cases does rpm or yum have anything to do with it. It's certainly possible to build an RPM that packages static executables, but that's a matter of changing the %build section of the spec file such that it passes -static to gcc, not of doing anything RPM-specific.
To be clear, by the way -- there are compelling reasons why we don't use static libraries all the time!
Using shared libraries means that applying a security update to a library only means replacing the library itself, not recompiling all applications using it.
Using shared libraries is more memory-efficient, since the single shared copy of the library in memory can be used by multiple applications.
Using shared libraries means your executables don't need to include full copies of all the libraries they use, making them much smaller.

cabal sandbox v. global package db

When installing inside a cabal sandbox, cabal will still use packages from the global package db (in particular, packages which came from the Haskell Platform). This can lead to install conflicts. Is it possible to configure cabal to ignore the global package db?
I see the corresponding feature has been implemented in ghc itself, via a -no-global-package-db option (see https://ghc.haskell.org/trac/ghc/ticket/5977), and ghc-pkg will ignore the global package db if you do not pass it the --global flag. Is there a way to configure cabal similarly?
Also, there's a closed issue against cabal implying the opposite behavior (rebuilding everything instead of using packages from the installed Haskell Platform), so I'm not sure if this behavior has changed over time; see https://github.com/haskell/cabal/issues/1695
You should be able to pass cabal configure the --package-db flag, documented like so:
--package-db=DB Append the given package database to the
list of package databases used (to satisfy
dependencies and register into). May be a
specific file, 'global' or 'user'. The
initial list is ['global'], ['global',
'user'], or ['global', $sandbox],
depending on context. Use 'clear' to reset
the list to empty. See the user guide for
details.
So in particular, you can pass it clear and then pass it just the sandbox db.
This is all discussed in wonderful detail in the Storage and Interpretation of Cabalized Packages article.

Resources