Description
Describe the bug
After GHC 9.8.2/Cabal-3.10.2.0, and by GHC 9.10.1/Cabal-3.12.0.0, Cabal (the library) ignores hs-source-dirs
if main-is
is a C source file. Previously, Cabal respected hs-source-dirs
.
To Reproduce
Imagine a small package. In directory app
it has Main.hs
with contents:
module Main ( main ) where
import Lib ( myMax )
main :: IO ()
main = print $ myMax 10 100
In directory src
it has Lib.hs
with contents:
module Lib ( myMax ) where
myMax :: Int -> Int -> Int
myMax x1 x2 = if x1 > x2 then x1 else x2
foreign export ccall myMax :: Int -> Int -> Int
In directory c-app
it has main.c
with contents:
#include <stdio.h>
#include <HsFFI.h>
#ifdef __GLASGOW_HASKELL__
#include "Lib_stub.h"
#endif
int main(int argc, char *argv[]) {
hs_init(&argc, &argv);
printf("%lld\n", myMax(10,100));
hs_exit();
return 0;
}
It has the usual Setup.hs
:
import Distribution.Simple
main = defaultMain
and it has a Cabal file:
cabal-version: 1.12
name: haskell-c-tests
version: 0.1.0.0
build-type: Simple
library
exposed-modules: Lib
hs-source-dirs: src
ghc-options: -stubdir autogen-stubs
build-depends: base
default-language: Haskell2010
executable c-exe
main-is: main.c
hs-source-dirs: c-app
ghc-options: -no-hs-main
include-dirs: autogen-stubs
build-depends: base, haskell-c-tests
default-language: Haskell2010
executable haskell-exe
main-is: Main.hs
hs-source-dirs: app
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base, haskell-c-tests
default-language: Haskell2010
With GHC 9.8.2/Cabal-3.10.2.0 all is fine (extracts only):
❯ stack --stack-yaml stack-ghc-9.8.2.yaml runghc --no-ghc-package-path -- Setup.hs configure
Configuring haskell-c-tests-0.1.0.0...
❯ stack --stack-yaml stack-ghc-9.8.2.yaml runghc --no-ghc-package-path -- Setup.hs build -v
...
Preprocessing executable 'c-exe' for haskell-c-tests-0.1.0.0..
Building executable 'c-exe' for haskell-c-tests-0.1.0.0..
creating dist\build\c-exe
creating dist\build\c-exe\c-exe-tmp
Building C Sources...
creating dist\build\c-exe\c-exe-tmp
Running: "C:\Users\mike\AppData\Local\Programs\stack\x86_64-windows\ghc-9.8.2\bin\ghc.exe" "-c" "-odir" "dist\build\c-exe\c-exe-tmp" "-Idist\build\c-exe\autogen" "-Idist\build\global-autogen" "-Idist\build\c-exe\c-exe-tmp" "-Iautogen-stubs" "-Idist\build\autogen-stubs" "-optc-O2" "-pgmc" "C:\Users\mike\AppData\Local\Programs\stack\x86_64-windows\ghc-9.8.2\lib\../mingw/bin\clang.exe" "-hide-all-packages" "-no-user-package-db" "-package-db" "dist\package.conf.inplace" "-package-id" "base-4.19.1.0-6554" "-package-id" "haskell-c-tests-0.1.0.0-2Qfk7puHfWxBnTSX2kZfQz" "c-app\main.c" "-no-hs-main"
Linking...
Note that Cabal has passed "c-app\main.c"
to GHC 9.8.2 (the second from last argument).
However, with GHC 9.10.1/Cabal-3.12.0.0, Cabal passes only "main.c"
to GHC 9.10.1 and, consequently, fails to find main.c
:
❯ stack --stack-yaml stack-ghc-9.10.1.yaml runghc --no-ghc-package-path -- Setup.hs configure
Configuring haskell-c-tests-0.1.0.0...
❯ stack --stack-yaml stack-ghc-9.10.1.yaml runghc --no-ghc-package-path -- Setup.hs build -v
...
Preprocessing executable 'c-exe' for haskell-c-tests-0.1.0.0...
Building executable 'c-exe' for haskell-c-tests-0.1.0.0...
creating dist\build\c-exe
creating dist\build\c-exe\c-exe-tmp
Wanted build ways: [StaticWay]
Building C Sources...
creating dist\build\c-exe\c-exe-tmp
Running: "C:\Users\mike\AppData\Local\Programs\stack\x86_64-windows\ghc-9.10.1\bin\ghc.exe" "-c" "-odir" "dist\build\c-exe\c-exe-tmp" "-Idist\build\c-exe\autogen" "-Idist\build\global-autogen" "-Idist\build\c-exe\c-exe-tmp" "-Iautogen-stubs" "-Idist\build\autogen-stubs" "-optc-O2" "-pgmc" "C:\Users\mike\AppData\Local\Programs\stack\x86_64-windows\ghc-9.10.1\lib/../mingw//bin\clang.exe" "-hide-all-packages" "-no-user-package-db" "-package-db" "dist\package.conf.inplace" "-package-id" "base-4.20.0.0-30dc" "-package-id" "haskell-c-tests-0.1.0.0-BiMnNkNFjFZ2oxYL44TYmr" "main.c" "-no-hs-main"
<command line>: does not exist: main.c
(stack --stack-yaml stack-ghc-9.10.1.yaml runghc --no-ghc-package-path --
etc runs runghc
in the correct environment - that is, one that provides the relevant version of GHC and its Cabal boot package. The --no-ghc-package-path
is because GHC_PACKAGE_PATH
and Cabal are incompatible.)