Which package provides the "make" executable? - nixos

I've tried https://nixos.org/nixos/packages.html#make but it returns around 314 results spread across 20 pages so not very convenient.
I've also tried the stdenv package with no change in behavior.

I've found the following:
$ readlink $(which make)
/nix/store/qwl4psnv7qnbs69qhd5w2jfcp7a686vw-gnumake-4.2.90pre2491_48c8a11/bin/make
So the name of the package is gnumake. Package search reveals five packages of which four are GNU make.
nix repl on my NixOS 18.03 system shows:
$ nix repl
[...]
nix-repl> (import <nixpkgs> {}).gnumake
«derivation /nix/store/b1imiipjihl8k9n48smbvjpsjcjq0qfj-gnumake-4.2.1.drv»
With GitHub's search you can figure out where derivations named gnumake are defined, which is in pkgs/development/tools/build-managers/gnumake

Related

Why does GHCi understand imports that GHC doesn't?

I'm pretty new to Haskell, and I think I have a fundamental misunderstanding somewhere. When I'm in GHCi (using the ghci command), I can type import System.Random, and it works. I can then generate random numbers.
Next, I make a file called test.hs that contains nothing but one line: import System.Random. I then call the command ghc test.hs and get the following error message:
test.hs:1:1: error:
Could not find module ‘System.Random’
There are files missing in the ‘random-1.1’ package,
try running 'ghc-pkg check'.
Use -v to see a list of the files searched for.
|
1 | import System.Random
| ^^^^^^^^^^^^^^^^^^^^
However, if I go back to GHCi, I can type :load test.hs. This works, and allows me to generate random numbers.
When I run ghc-pkg check, I get only warnings about missing haddock interface files: https://pastebin.com/6a9f0nYZ. From what I understand, this isn't related to the current issue.
Also, when I run ghc-pkg list, random-1.1 is in the list, so random should be installed.
A couple of questions:
Why would GHC and GHCi have access to different imports? Why is the system set up that way? Maybe I just don't understand the relationship between GHC and GHCi.
According to the error message, there are "files missing." How can I figure out which files?
How can I make it so that I can compile Haskell files that use System.Random?
Edit: Both GHC and GHCi are the same version.
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.6.4
$ ghci --version
The Glorious Glasgow Haskell Compilation System, version 8.6.4
Edit: Both ghc and ghci are in /usr/bin/
$ which ghc
/usr/bin/ghc
$ which ghci
/usr/bin/ghci
Update: It looks like this is an Arch Linux peculiarity, not a corrupt package. I've updated my answer accordingly.
GHCi loads "dynamic" versions of modules. By default, GHC links with "static" versions of modules. In particular, when you run:
> import System.Random
under GHCi, it tries to access the file Random.dyn_hi to get interface information for the module. In contrast, when you compile a file with that import statement in it, GHC tries to access the file Random.hi.
You can verify this is the issue by running ghc-pkg field random import-dirs and peeking in the resulting directory. There should be a System subdirectory that usually has two files in it: System.hi and System.dyn_hi. If the former is missing, that's your problem.
Now, it looks like you're probably using Arch Linux. As documented on the Arch Haskell wiki page in the section "Problems with linking", the Arch Haskell community packages (including haskell-random) intentionally omit the static versions of interface files and libraries.
There are several of workarounds given there:
You can use dynamic linking when compiling with GHC. When using GHC directly, this just means passing the -dynamic flag. For Cabal-based projects, instructions are given on that page for modifying your ~/.cabal/config to use dynamic linking for all projects.
You can install the ghc-static and ghc-pristine packages and set up your path and/or Cabal to use the compiler in /usr/share/ghc-pristine/bin/ghc which will maintain its own separate package database that won't interfere with globally installed Haskell community packages, like haskell-random.
You can install ghc-static to get static versions of the base libraries and then run cabal install --force-reinstalls somepackage for all the non-base packages you need. Note that the Wiki notes that this can be tedious and complicated, since you have to manually determine all the package dependencies.
Now, it looks like you already had ghc-static installed, or when invoking GHC you would have also gotten an error about missing files in the base package. You ran cabal install --force-reinstalls random, though as #dfeuer notes, it might have been safer to run:
$ cabal install --force-reinstalls random-1.1
to ensure that the same version was reinstalled.
Anyway, this installed an additional copy of random in your user-specific package directory. If you run:
$ ghc-pkg list
you'll see that random-1.1 is listed both under the global database and user database:
/usr/lib/ghc-8.6.4/package.conf.d
...
random-1.1
...
/home/xxxx/.ghc/x86_64-linux-8.6.4/package.conf.d
random-1.1
and if you run:
$ ghc-pkg describe random
you'll see that it lists the two separate installed versions which is why you now get duplicate fields with ghc-pkg field random import-dirs.
There shouldn't be anything wrong with this. Your user database will take precedence over the global database, so your newly installed version of random will be used when you run GHCi or GHC.
Note that, if you change your mind and want to back out this reinstallation (and maybe try one of the other solutions suggested on the Wiki), you should be able to run:
$ ghc-pkg unregister --user random
Technically, this won't actually remove the package (as the compiled version will still be there under ~/.cabal/lib), but it should otherwise put things back the way they were.

nix-shell as #! interpreter for runghc

I'm trying to use nix-shell as a #! wrapper for runghc, as suggested in the manpage. But it cannot find the libraries. Given the following example, cut-down from the manpage
#! /usr/bin/env nix-shell
#! nix-shell -i runghc -p haskellPackages.HTTP
import Network.HTTP
main = return ()
I get the following result:
[~:0]$ ./nixshelltest
nixshelltest:4:1: error:
Failed to load interface for ‘Network.HTTP’
Use -v to see a list of the files searched for.
[~:1]$
to my mind, that's exactly what nix-shell -p is to avoid.
Am I doing something wrong, missing the point, or is there a bug? This is both on a nixOS 17.03 host, and also a host running nix 17.09 on top of Ubuntu.
Thanks,
The environment that you're using to run the script is missing a step. It's got a GHC and a HTTP package, but the compiler doesn't know about the package.
The way GHC and library packages work in nix might be a little "inside out" from what you're expecting. You actually need to install a compiler that "depends on" all of the libraries you want, rather than simply installing the compiler and the library separately. The reason is that GHC is designed to have library packages added by modifying the file tree where GHC is installed. On a mutable file system with only a single system GHC install you would just modify GHC whenever a library was installed, but nix can't. Nix has to be able to install a frozen GHC that never changes, and potentially many of them.
So what happens instead is that you install a tiny wrapper which depends on the both the underlying "raw" GHC install and all of the libraries that you want to use. The wrapper then acts like an install of GHC that had those libraries registered, without actually needing to duplicate an entire GHC install. When you just install a library package on its own it just sits there inert, without any GHC being able to find it just by it existing.
In fact, the script you've shown here doesn't actually specify that it should have a compiler installed at all; it just asks for the HTTP library. When I tried your script I got command not found: runghc. The runghc is only working on your system because it happened to already be in your path when you ran this (perhaps because you have GHC installed in your profile?), and that GHC wasn't installed with the HTTP package and so can't see it. The nix-shell adding just the library to the environment doesn't help.
What you need to do instead is use this line:
#! nix-shell -i runghc -p "ghc.withPackages (ps: [ ps.HTTP ])"
You're not installing either ghc or HTTP directly; instead the ghc.withPackages function computes a nix package that installs a GHC wrapper that knows about the HTTP Haskell package. Under the hood this depends on a "raw" GHC with no additional libraries, and also on the HTTP library and will cause those to be installed too.
If you use lots of different Haskell environments (possibly via nix-shell scripts like this that each need a different set of libraries), then you will end up with a unique withPackages wrapper installed on your system for each combination of libraries you ever use. But that's okay because the wrappers themselves are tiny, and nix is able to share and reuse the underlying GHCs and library packages between all of those environments.

How can configuration tools like sdl-config be used with a cabalized project?

I have a working SDL/Haskell application that I would like to build using Cabal instead of the current Makefile (because that is the "Haskell way"). The Makefile is itself very simple, and I was hoping that the default cabal build process could allow me to reconstruct a build command specified in my Makefile. The problem is that it makes use of "sdl-config", a utility that gives you all the necessary cc- compiler options:
wrapper.o: SDLWrapper_stub.h
ghc -no-hs-main `sdl-config --cflags` -Wall wrapper.c -c
Cabal does not seem to expand that into a shell call when calling GHC. How can I specify that sdl-config's options should be fed into GHC when compiling wrapper.o?
Using the configure style in Cabal, you can write a little configure script that substitutes a variable for the output of the sdl-config command. The values will then be replaced in a $foo.buildinfo.in file, yielding a $foo.buildinfo file, that Cabal will include in the build process.
General solution: the configure script
#!/bin/sh
SDLFLAGS=`sdl-config --cflags`
echo Found "$SDLFLAGS"
sed 's,#SDLFLAGS#,'"$SDLFLAGS"',' z.buildinfo.in > z.buildinfo
The $foo.builinfo.in file
cc-options: #SDLFLAGS#
The .cabal file
Build-type: Configure
When you run "cabal configure" the "cc-options" field in z.buildinfo will be created to hold:
cc-options: -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT
which cabal will include in the build.
Done.
Specific solution for pkg-config tools
For tools that support the pkg-config-style of configuration, such as sdl or cairo and others, Cabal has specific support already:
pkgconfig-depends: package list
A list of pkg-config packages, needed to build this package. They can be annotated with versions, e.g. gtk+-2.0 >= 2.10, cairo >= 1.0. If no version constraint is specified, any version is assumed to be acceptable. Cabal uses pkg-config to find if the packages are available on the system and to find the extra compilation and linker options needed to use the packages.
If you need to bind to a C library that supports pkg-config (use pkg-config --list-all to find out if it is supported) then it is much preferable to use this field rather than hard code options into the other fields.
So for sdl you just need:
pkgconfig-depends: sdl
Use the Configure build type in your $PROJ_NAME.cabal file and generate a $PROJ_NAME.buidinfo file from a $PROJ_NAME.buildinfo.in template with a configure script. Look at the source of the SDL library on Hackage for an example. This section of the Cabal user guide provides more details.
One tip: do not forget to mention $PROJ_NAME.buildinfo.in and configure in the extra-source-files field.

ghc can't find my cabal installed packages

I've installed ghc 6.12.3, and then the Haskell Platform. I'm trying to compile a test program:
$ ghc test.hs
test.hs:3:0:
Failed to load interface for `Bindings':
Use -v to see a list of the files searched for.
so, naturally, I do
cabal install Bindings
Which works fine, and places the package in ~/.cabal/lib/bindings-0.1.2 The problem is, that when I go to compile again with ghc, it still doesn't find the package I've installed with cabal.
compiling in verbose mode gives:
ghc -v test.hs
Using binary package database: /home/ludflu/ghc/lib/ghc-6.12.3/package.conf.d/package.cache
Using binary package database: /home/ludflu/.ghc/x86_64-linux 6.12.3/package.conf.d/package.cache
As suggested by another stackoverflow user, I tried:
ghc-pkg describe rts > rts.pkg
vi rts.pkg # add the /home/ludflu/.cabal/lib to `library-dirs` field
ghc-pkg update rts.pkg
But to no avail. How to I add the .cabal to the list of package directories to search?
Thank you!
You can check which packages are installed with ghc-pkg list. It may be that you need to either specify the packages to ghc with -package <pkgname> or I believe adding --make to will trigger a chasing down of dependencies, including packages.
Edit: the bindings package is obsolete indeed, see the hackage page. This isn't a package management problem, the only module available is Bindings.Deprecated, which you are perfectly able to load, even though it is an empty module. I believe the relevant parts have been broken out into bindings-<module>, so if you want the bindings functionality you should look to those packages.
http://www.haskell.org/haskellwiki/Cabal-install
One thing to be especially aware of, is that the packages are installed locally by default by cabal, whereas the commands
runhaskell Setup configure
runhaskell Setup build
runhaskell Setup install
install globally by default. If you install a package globally, the local packages are ignored. The default for cabal-install can be modified by editing the configuration file.
I was getting the same error with the runhaskell command. I used the cabal in the directory that had the .cabal file and was able to resolve the error.

Using GHC, cabal with GMP installed in user-space

I have been trying to install Haskell Platform and cabal-install installed on Linux in user-space on a system that doesn't have the GNU Multi-Precision package (GMP) installed.
I managed to get GHC-6.12.1 installed and GHCi working by setting up LB_LIBRARY_PATH to point at the lib directory where I installed GMP, but then ran into problems in the next step, getting cabal-install to work. It kept trying to (statically) link to GMP.
This fails because the GMP is not installed in the system and ld hasn't a clue where to find the libraries, and there is no environment variable (that I am aware of) that can tell ld where to find the user-installed GMP, and (apparently) no way of telling configuring Cabal to supply the relevant -L flag.
After much fruitless searching and hacking attempts I hit on the absurdly simple idea of installing my own ld shell script that invokes the system ld with the appropriate -L flag.
This is shell scripting 101, of course:
#!/bin/sh
/usr/bin/ld -L$HOME/gnu/lib "$#"
With this script installed in a directory on my PATH ahead of /usr/bin all the problems seem to have gone away.
Basically, your ghc is not working yet. Yes, it can compile things, but it cannot link programs because it needs to link them to gmp.
What we can do is to edit some core package, e.g. the rts package, so that ghc will always use the right -L flag:
ghc-pkg describe rts > rts.pkg
vi rts.pkg # add the gmp dir to the `library-dirs` field
sudo ghc-pkg update rts.pkg

Resources