Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build on Nixpkgs/NixOS #4405

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
ab23462
Trying to enhance the experience on NixOS/Nixpkgs
jacereda Mar 30, 2018
0e0bd1a
Missing space
jacereda Mar 30, 2018
52d9600
Merge
jacereda Mar 30, 2018
44df85b
Merge branch 'build-on-nixpkgs' of https://github.com/jacereda/Idris-…
jacereda Mar 30, 2018
150e586
Enable tests
jacereda Mar 31, 2018
f723856
Merge
jacereda Apr 2, 2018
8009e2b
cabal test wasn't building the executables
jacereda Apr 2, 2018
55dc5db
Blind attempt at fixing Setup for Cabal-1
jacereda Apr 2, 2018
af91928
Apply stylish-haskell suggestion
jacereda Apr 3, 2018
5b018fe
Restore timeouts via ulimit
jacereda Apr 4, 2018
b6ed5d0
Avoid perl dependency
jacereda Apr 4, 2018
2b60976
Tests failed on windows due to ulimit -t, timeout script using node
jacereda Apr 4, 2018
6a2151b
Use another method to export IDRIS
jacereda Apr 4, 2018
f1ef4c6
Generate base nix expression with cabal2nix from Makefile
jacereda Apr 5, 2018
9db7c86
Use callCabal2nix
jacereda Apr 5, 2018
78d6af9
Warning
jacereda Apr 5, 2018
734e480
Patch node shebang
jacereda Apr 5, 2018
caccebd
Get rid of shell.nix and idris.nix
jacereda Apr 5, 2018
4c23999
Avoid duplicated CFLAGS
jacereda Apr 5, 2018
3e6e470
Don't force compiler
jacereda Apr 5, 2018
cf3d89f
Use installed idris when testing on appveyor
jacereda Apr 5, 2018
cc13c44
Merge master
jacereda Apr 5, 2018
405c415
Revert travis test
jacereda Apr 5, 2018
8d76d46
Leak warning
jacereda Apr 7, 2018
70e2514
Merge branch 'master' of https://github.com/idris-lang/Idris-dev into…
jacereda Apr 19, 2018
5e209f1
Merge master
jacereda May 3, 2018
42616f9
Merge master
jacereda May 3, 2018
93d5656
Merge
jacereda May 24, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,21 @@ encounter this then the fix is to augment the `PKG_CONFIG_PATH` for

```
PKG_CONFIG_PATH=/usr/local/opt/libffi/lib/pkgconfig stack build
```
```

## Experimental Support for Building on NixOS or systems with Nixpkgs

To run the full build process:

nix-build

The resulting build should be on the `result` directory.

If you wish to install it to your environment:

nix-env -f default.nix -i idris

For local development with Cabal:

nix-shell
cabal install # or build/test/whatever
64 changes: 43 additions & 21 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: build configure doc install linecount nodefault pinstall lib_clean relib fast test_js test_c stylize test test_clean lib_doc lib_doc_clean user_doc_html user_doc_pdf user_docs
.PHONY: build configure doc install linecount nodefault pinstall lib_clean relib fast test_js test_c stylize test test_clean lib_doc lib_doc_clean user_doc_html user_doc_pdf user_docs rts rts_clean

ARGS=
TEST-JOBS=
Expand All @@ -7,6 +7,10 @@ TEST-ARGS=
include config.mk
-include custom.mk

IDRIS ?= $(CURDIR)/dist/build/idris/idris
CB=env IDRIS=$(IDRIS) $(CABAL)
MK=+env IDRIS=$(IDRIS) $(MAKE)

ifdef CI
CABALFLAGS += -f CI
ifndef APPVEYOR
Expand All @@ -15,68 +19,86 @@ endif
endif

install:
$(CABAL) install $(CABALFLAGS)
$(CB) install $(CABALFLAGS)

pinstall: CABALFLAGS += --enable-executable-profiling
pinstall: dist/setup-config
$(CABAL) install $(CABALFLAGS)
$(CB) install $(CABALFLAGS)

build: dist/setup-config
$(CABAL) build $(CABALFLAGS)
$(CB) build

$(IDRIS): dist/setup-config
$(CB) build "exe:idris"

test: doc test_c stylize

stylize:
./stylize.sh

test_c:
$(CABAL) test $(ARGS) --test-options \
$(CB) test $(ARGS) --test-options \
"$(TEST-ARGS) --rerun-update +RTS -N$(TEST-JOBS) -RTS"

test_js:
$(CABAL) test $(ARGS) --test-options \
$(CB) test $(ARGS) --test-options \
"$(TEST-ARGS) --node --rerun-update +RTS -N$(TEST-JOBS) -RTS"

test_update:
$(CABAL) test $(ARGS) --test-options \
$(CB) test $(ARGS) --test-options \
"$(TEST-ARGS) --accept +RTS -N$(TEST-JOBS) -RTS"

test_clean:
rm -f test/*~
rm -f test/*/output

rts:
$(MK) -C rts

rts_install:
$(MK) -C rts install

rts_clean:
$(MK) -C rts clean

lib:
$(MK) -C libs

lib_install:
$(MK) -C libs install

lib_clean:
$(MAKE) -C libs IDRIS=../../dist/build/idris/idris RTS=../../dist/build/rts/libidris_rts clean
$(MK) -C libs clean

lib_doc:
+$(MK) -C libs doc

lib_doc_clean:
+$(MK) -C libs doc_clean

relib: lib_clean
$(CABAL) install $(CABALFLAGS)
$(CB) install $(CABALFLAGS)

linecount:
wc -l src/Idris/*.hs src/Idris/Elab/*.hs src/Idris/Core/*.hs src/IRTS/*.hs src/Pkg/*.hs src/Util/*.hs

#Note: this doesn't yet link to Hackage properly
doc: dist/setup-config
$(CABAL) haddock --hyperlink-source --html --hoogle --html-location="http://hackage.haskell.org/packages/archive/\$$pkg/latest/doc/html" --haddock-options="--title Idris"

lib_doc:
$(MAKE) -C libs IDRIS=../../dist/build/idris/idris doc

lib_doc_clean:
$(MAKE) -C libs IDRIS=../../dist/build/idris/idris doc_clean
$(CB) haddock --hyperlink-source --html --hoogle --html-location="http://hackage.haskell.org/packages/archive/\$$pkg/latest/doc/html" --haddock-options="--title Idris"

user_docs: user_doc_html user_doc_pdf

user_doc_clean:
$(MAKE) -C docs clean
$(MK) -C docs clean

user_doc_html:
$(MAKE) -C docs html
$(MK) -C docs html

user_doc_pdf:
$(MAKE) -C docs latexpdf
$(MK) -C docs latexpdf

fast:
$(CABAL) install $(CABALFLAGS) --ghc-option=-O0
$(CB) install $(CABALFLAGS) --ghc-option=-O0

dist/setup-config:
$(CABAL) configure $(CABALFLAGS)
$(CB) configure $(CABALFLAGS)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of renaming the CABAL and MAKE variables? These shorter versions are (slightly) more difficult for me to understand.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those try to ensure the correct idris is invoked via env IDRIS=$(IDRIS) ... and I simply used those. I'm not particularly attached to any of those names though, what would you suggest?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not leave them as they were?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean? Repeat explicitly like in env IDRIS=$(IDRIS) $(MAKE)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was commenting on renaming the CABAL variable to CB here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uses the original names now.

111 changes: 57 additions & 54 deletions Setup.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

import Control.Monad
import Data.IORef
import Data.Maybe (fromMaybe)
import Data.List (nub, isInfixOf)
import Control.Exception (SomeException, catch)

import Distribution.Simple
Expand Down Expand Up @@ -36,14 +38,11 @@ import Distribution.Types.UnqualComponentName

-- -----------------------------------------------------------------------------
-- Idris Command Path
idrisCmd local = Px.joinPath $ splitDirectories $ ".." </> ".." </> buildDir local </> "idris" </> "idris"


shinvoke verbosity cmd = P.runProgramInvocation verbosity . P.simpleProgramInvocation cmd

-- make on mingw32 exepects unix style separators
#ifdef mingw32_HOST_OS
(<//>) = (Px.</>)
idrisCmd local = Px.joinPath $ splitDirectories $ ".." <//> ".." <//> buildDir local <//> "idris" <//> "idris"
#else
idrisCmd local = ".." </> ".." </> buildDir local </> "idris" </> "idris"
#endif

-- -----------------------------------------------------------------------------
-- Make Commands
Expand All @@ -55,42 +54,32 @@ mymake = "gmake"
#else
mymake = "make"
#endif
make verbosity =
P.runProgramInvocation verbosity . P.simpleProgramInvocation mymake
make verbosity = shinvoke verbosity mymake

#ifdef mingw32_HOST_OS
windres verbosity = P.runProgramInvocation verbosity . P.simpleProgramInvocation "windres"
#endif
-- -----------------------------------------------------------------------------
-- Flags

usesGMP :: S.ConfigFlags -> Bool
usesGMP flags =
case lookupFlagAssignment (mkFlagName "gmp") (S.configConfigurationsFlags flags) of

flag nm flags = case lookupFlagAssignment (mkFlagName nm) (S.configConfigurationsFlags flags) of
Just True -> True
Just False -> False
Nothing -> False


usesGMP :: S.ConfigFlags -> Bool
usesGMP = flag "gmp"

execOnly :: S.ConfigFlags -> Bool
execOnly flags =
case lookupFlagAssignment (mkFlagName "execonly") (S.configConfigurationsFlags flags) of
Just True -> True
Just False -> False
Nothing -> False
execOnly = flag "execonly"

isRelease :: S.ConfigFlags -> Bool
isRelease flags =
case lookupFlagAssignment (mkFlagName "release") (S.configConfigurationsFlags flags) of
Just True -> True
Just False -> False
Nothing -> False
isRelease = flag "release"

isFreestanding :: S.ConfigFlags -> Bool
isFreestanding flags =
case lookupFlagAssignment (mkFlagName "freestanding") (S.configConfigurationsFlags flags) of
Just True -> True
Just False -> False
Nothing -> False
isFreestanding = flag "freestanding"

#if !(MIN_VERSION_Cabal(2,0,0))
mkFlagName :: String -> FlagName
Expand All @@ -105,13 +94,12 @@ lookupFlagAssignment = lookup
-- -----------------------------------------------------------------------------
-- Clean

idrisClean _ flags _ _ = cleanStdLib
idrisClean _ flags _ _ = cleanStdLib >> cleanRts
where
verbosity = S.fromFlag $ S.cleanVerbosity flags

cleanStdLib = makeClean "libs"

makeClean dir = make verbosity [ "-C", dir, "clean", "IDRIS=idris" ]
cleanStdLib = make verbosity ["lib_clean"]
cleanRts = make verbosity ["rts_clean"]

-- -----------------------------------------------------------------------------
-- Configure
Expand Down Expand Up @@ -183,12 +171,16 @@ generateToolchainModule verbosity srcDir toolDir = do
createDirectoryIfMissingVerbose verbosity True srcDir
rewriteFileEx verbosity toolPath (commonContent ++ toolContent)

idrisConfigure _ flags pkgdesc local = do
idrisPostConf _ flags pkgdesc local = do
nixLDFLAGS <- lookupEnv "NIX_LDFLAGS"
configureRTS
withLibLBI pkgdesc local $ \lib libcfg -> do
let libAutogenDir = autogenComponentModulesDir local libcfg
let libDirs = extraLibDirs $ libBuildInfo lib
generateBuildFlagsModule verbosity libAutogenDir libDirs
let nixLibDirs = map (drop 2)
$ filter ("-gmp-" `isInfixOf`)
$ words $ fromMaybe "" nixLDFLAGS
generateBuildFlagsModule verbosity libAutogenDir (nub $ libDirs ++ nixLibDirs)
generateVersionModule verbosity libAutogenDir (isRelease (configFlags local))
if isFreestanding $ configFlags local
then do
Expand All @@ -209,7 +201,7 @@ idrisConfigure _ flags pkgdesc local = do
-- installing but shouldn't be in the distribution. And it won't make the
-- distribution if it's not there, so instead I just delete
-- the file after configure.
configureRTS = make verbosity ["-C", "rts", "clean"]
configureRTS = make verbosity ["rts_clean"]

#if !(MIN_VERSION_Cabal(2,0,0))
autogenComponentModulesDir lbi _ = autogenModulesDir lbi
Expand Down Expand Up @@ -273,27 +265,34 @@ idrisPreBuild args flags = do
verbosity = S.fromFlag $ S.buildVerbosity flags
dir = S.fromFlagOrDefault "dist" $ S.buildDistPref flags
#else
return (Nothing, [])
preBuild simpleUserHooks args flags
#endif

idrisBuild _ flags _ local
idrisBuildHook pd lbi hooks flags = do
let exe = ("exe:" ++) . unUnqualComponentName . exeName
exes = map exe (executables pd)
nflags = case S.buildArgs flags of
orig@["regression-and-feature-tests"] ->
flags { S.buildArgs = exes ++ orig }
_ -> flags
buildHook simpleUserHooks pd lbi hooks nflags


idrisPostBuild _ flags _ local
= if (execOnly (configFlags local)) then buildRTS
else do buildStdLib
buildRTS
where
verbosity = S.fromFlag $ S.buildVerbosity flags

buildStdLib = do
putStrLn "Building libraries..."
makeBuild "libs"
where
makeBuild dir = make verbosity [ "-C", dir, "build" , "IDRIS=" ++ idrisCmd local]

buildRTS = make verbosity (["-C", "rts", "build"] ++
gmpflag (usesGMP (configFlags local)))

putStrLn "Building libraries..."
make verbosity [ "-j8", "lib", "IDRIS=" ++ idrisCmd local]
buildRTS = do
putStrLn "Building runtime..."
make verbosity $ ["rts"] ++ gmp
gmpflag False = []
gmpflag True = ["GMP=-DIDRIS_GMP"]
gmp = gmpflag (usesGMP (configFlags local))

-- -----------------------------------------------------------------------------
-- Copy/Install
Expand All @@ -307,22 +306,22 @@ idrisInstall verbosity copy pkg local
target = datadir $ L.absoluteInstallDirs pkg local copy

installStdLib = do
let target' = target -- </> "libs"
putStrLn $ "Installing libraries in " ++ target'
makeInstall "libs" target'
let target' = target -- </> "libs"
putStrLn $ "Installing libraries in " ++ target'
make' "lib_install" target'

installRTS = do
let target' = target </> "rts"
putStrLn $ "Installing run time system in " ++ target'
makeInstall "rts" target'
make' "rts_install" target'

installManPage = do
let mandest = mandir (L.absoluteInstallDirs pkg local copy) ++ "/man1"
notice verbosity $ unwords ["Copying man page to", mandest]
installOrdinaryFiles verbosity mandest [("man", "idris.1")]

makeInstall src target =
make verbosity [ "-C", src, "install" , "TARGET=" ++ target, "IDRIS=" ++ idrisCmd local]
make' x target =
make verbosity [ x, "TARGET=" ++ target, "IDRIS=" ++ idrisCmd local]

-- -----------------------------------------------------------------------------
-- Test
Expand All @@ -335,7 +334,10 @@ fixPkg pkg target = pkg { dataDir = target }

idrisTestHook args pkg local hooks flags = do
let target = datadir $ L.absoluteInstallDirs pkg local NoCopyDest
testHook simpleUserHooks args (fixPkg pkg target) local hooks flags
idris <- canonicalizePath (buildDir local </> "idris" </> "idris")
setEnv "IDRIS" idris
-- testHook simpleUserHooks args (fixPkg pkg target) local hooks flags
testHook simpleUserHooks args pkg local hooks flags

-- -----------------------------------------------------------------------------
-- Main
Expand All @@ -344,9 +346,10 @@ idrisTestHook args pkg local hooks flags = do
-- See https://github.com/haskell/cabal/issues/709
main = defaultMainWithHooks $ simpleUserHooks
{ postClean = idrisClean
, postConf = idrisConfigure
, postConf = idrisPostConf
, preBuild = idrisPreBuild
, postBuild = idrisBuild
, buildHook = idrisBuildHook
, postBuild = idrisPostBuild
, postCopy = \_ flags pkg local ->
idrisInstall (S.fromFlag $ S.copyVerbosity flags)
(S.fromFlag $ S.copyDest flags) pkg local
Expand Down
2 changes: 2 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc822" }:
nixpkgs.pkgs.haskell.packages.${compiler}.callPackage ./idris.nix { }
4 changes: 2 additions & 2 deletions idris.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,12 @@ custom-setup

Flag FFI
Description: Build support for libffi
Default: False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These flags should stay as they are, because libffi can be difficult for Mac users and some people don't like the license of GMP.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And I agree, I'm sort of asking how should this be handled in the second bullet point.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that their behavior should remain unchanged in the .cabal file at least. Nix users are a minority of Idris users, and I don't think that we should make it more difficult to build it the common way to make Nix packaging easier.

Default: True
manual: True

Flag GMP
Description: Use GMP for Integers
Default: False
Default: True
manual: True

-- This flag determines whether to show Git hashes in version strings
Expand Down
Loading