From a76301a911413a991a49a3254fe4c4385ad4954c Mon Sep 17 00:00:00 2001 From: zhujinxuan Date: Tue, 12 Nov 2019 16:25:58 -0500 Subject: [PATCH] Add mainModule in spec to allow -main-is compiling --- snack-lib/build.nix | 7 ++++--- snack-lib/default.nix | 3 ++- snack-lib/package-spec.nix | 12 +++++++++++- tests/main-is-different/Spec.hs | 12 ++++++++++++ tests/main-is-different/golden | 1 + tests/main-is-different/package.nix | 4 ++++ tests/main-is-different/test | 18 ++++++++++++++++++ 7 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 tests/main-is-different/Spec.hs create mode 100644 tests/main-is-different/golden create mode 100644 tests/main-is-different/package.nix create mode 100755 tests/main-is-different/test diff --git a/snack-lib/build.nix b/snack-lib/build.nix index df3ac7f..853452b 100644 --- a/snack-lib/build.nix +++ b/snack-lib/build.nix @@ -18,11 +18,11 @@ rec { # Returns an attribute set where the keys are all the built module names and # the values are the paths to the object files. # mainModSpec: a "main" module - buildMain = ghcWith: mainModSpec: + buildMain = ghcWith: mainModSpec: mainModName: buildModulesRec ghcWith # XXX: the main modules need special handling regarding the object name { "${mainModSpec.moduleName}" = - "${buildModule ghcWith mainModSpec}/Main.o";} + "${buildModule ghcWith mainModSpec}/${mainModName}.o";} mainModSpec.moduleImports; # returns a attrset where the keys are the module names and the values are @@ -34,9 +34,10 @@ rec { { ghcWith , moduleSpec # The module to build , name # The name to give the executable + , mainModName }: let - objAttrs = buildMain ghcWith moduleSpec; + objAttrs = buildMain ghcWith moduleSpec mainModName; objList = lib.attrsets.mapAttrsToList (x: y: y) objAttrs; deps = allTransitiveDeps [moduleSpec]; ghc = ghcWith deps; diff --git a/snack-lib/default.nix b/snack-lib/default.nix index c48c82b..3bc0f5a 100644 --- a/snack-lib/default.nix +++ b/snack-lib/default.nix @@ -46,7 +46,8 @@ with rec let moduleSpec = executableMainModSpec pkgSpec; name = pkgSpec.packageName; - drv = linkMainModule { inherit moduleSpec name ghcWith; }; + mainModName = pkgSpec.packageMainModule; + drv = linkMainModule { inherit moduleSpec name ghcWith mainModName; }; in { out = drv.out; exe_path = "${drv.out}/${drv.relExePath}"; diff --git a/snack-lib/package-spec.nix b/snack-lib/package-spec.nix index 594a147..5cbad39 100644 --- a/snack-lib/package-spec.nix +++ b/snack-lib/package-spec.nix @@ -11,6 +11,7 @@ rec { { src ? [] , name ? null , main ? null + , mainModule ? "Main" , ghcOpts ? [] , dependencies ? [] , extensions ? [] @@ -29,11 +30,20 @@ rec { { packageIsExe = ! builtins.isNull main; packageName = pName; packageMain = main; + packageMainModule = mainModule; packageSourceDirs = if builtins.isList src then src else [src]; - packageGhcOpts = ghcOpts; + packageGhcOpts = let + addition = + if mainModule == "Main" + then + [] + else + ["-main-is" mainModule]; + in + ghcOpts ++ addition; packageExtensions = extensions; packageDependencies = mkPerModuleAttr dependencies; diff --git a/tests/main-is-different/Spec.hs b/tests/main-is-different/Spec.hs new file mode 100644 index 0000000..10f6bc4 --- /dev/null +++ b/tests/main-is-different/Spec.hs @@ -0,0 +1,12 @@ +{-| +Copyright: + © 2018 Nicolas Mattia +-} +module Spec + ( main + ) where + +import Numeric.Natural (Natural) + +main :: IO () +main = putStrLn "hello, test!" diff --git a/tests/main-is-different/golden b/tests/main-is-different/golden new file mode 100644 index 0000000..30b2f7a --- /dev/null +++ b/tests/main-is-different/golden @@ -0,0 +1 @@ +hello, test! diff --git a/tests/main-is-different/package.nix b/tests/main-is-different/package.nix new file mode 100644 index 0000000..b8762b2 --- /dev/null +++ b/tests/main-is-different/package.nix @@ -0,0 +1,4 @@ +{ main = "Spec"; + mainModule = "Spec"; + src = ./.; +} diff --git a/tests/main-is-different/test b/tests/main-is-different/test new file mode 100755 index 0000000..7191172 --- /dev/null +++ b/tests/main-is-different/test @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# vim: ft=sh sw=2 et + +set -euo pipefail + +test() { + $SNACK build + $SNACK run | diff golden - + + TMP_FILE=$(mktemp) + + capture_io "$TMP_FILE" main | $SNACK ghci + + diff golden $TMP_FILE + rm $TMP_FILE +} + +SNACK="snack --package-file ./package.nix" test