"requested module differs from name found in the interface file" - haskell

What I want is: cabal to build my modules; make to build this one script.
The script links to Objective-C (see https://github.com/mchakravarty/language-c-inline/tree/master/tests/objc/marshal-array). when I build the script, it fails on the import:
$ make
Main.hs:1:1:
Bad interface file: dist/build/Commands/OSX/Events.hi
Something is amiss; requested module main:Commands.OSX.Events differs from name found in the interface file commands-0.0.0:Commands.OSX.Events
here are some file contents:
$ cat Makefile
PACKAGES = -package template-haskell -package language-c-quote -package language-c-inline -package commands
FRAMEWORKS = -framework Carbon -framework Cocoa -framework Foundation
LDFLAGS = $(PACKAGES) $(FRAMEWORKS)
Main: Main.o
cabal exec -- ghc -o Main Main.o $(LDFLAGS)
Main.o:
cabal build
cabal exec -- ghc -c Main.hs -idist/build/ -v
...
$ cat commands.cabal
exposed-modules: Commands.OSX.Events
hs-source-dirs: sources
...
$ ghc --show-iface dist/build/Commands/OSX/Events.hi
interface commands-0.0.0:Commands.OSX.Events 7083
...
$ cat sources/Commands/OSX/Events.hs
module Commands.OSX.Events where
...
$ cat Main.hs
import Commands.OSX.Events
...
the cabal build is successful, and executable compiles and runs successfully, if I just put everything in the same directory, and ignore cabal.
can I tell GHC that some module is part of some package?
can I make a cabal executable, with these external dependencies?
any other solutions?

explicitly naming the modules package worked:
ghc -package-name commands-0.0.0
http://www.haskell.org/ghc/docs/7.2.1/html/users_guide/packages.html

Related

Cabal / Stack ignores ghc-options for custom Setup scripts

I'm trying to get Stack working on an Arch system. I've done the usual:
pacman -S ghc stack cabal-install
And then placed the following in ~/.stack/config.yaml, so that the system GHC is used and dynamic libraries are used (the packages above do not include static libraries):
system-ghc: true
ghc-options:
"$everything": -dynamic
configure-options:
"$everything":
- -dynamic
But when I try to install something, (i.e. stack install wai) I see that it attempts to build a custom Setup script:
/usr/bin/ghc-8.6.5 -rtsopts -threaded -clear-package-db -global-package-db -hide-all-packages -package base -main-is StackSetupShim.mainOverride -package Cabal-2.4.0.1 /home/alba/.stack/setup-exe-src/setup-mPHDZzAJ.hs /home/alba/.stack/setup-exe-src/setup-shim-mPHDZzAJ.hs -o /home/alba/.stack/setup-exe-cache/x86_64-linux/tmp-Cabal-simple_mPHDZzAJ_2.4.0.1_ghc-8.6.5
And my options are not honored, so the build tries to use static libraries (and fails). Is there any way to get Stack/Cabal to use certain options when building Setup.hs?
EDIT: I found the relevant issues; it doesn't seem to be possible:
stack: Can't use system GHC without static libraries at all (#3409)
cabal: executable-dynamic: True should apply to build-type: Custom setup #1720
Related: It seems cabal will always attempt to build static + dynamic in some cases, even if you tell it otherwise.
For now, a partial solution I ended up using is to force the option with a wrapper.
At ~/.local/bin/ghc-8.6.5 put:
#!/bin/sh
exec /usr/bin/ghc-8.6.5 -dynamic "$#"
Then:
cd ~/.local/bin
chmod +x ghc-8.6.5
ln -s ghc{-8.6.5,}
ln -s {/usr/bin,.}/ghc-pkg-8.6.5
ln -s {/usr/bin,.}/runghc-8.6.5
ln -s {/usr/bin,.}/haddock-ghc-8.6.5
Make sure it's in your PATH and you're good to go.

Cabal build with c2hs not finding .chs module

I am trying out c2hs, and wanted to compile a small example of a shared library with Cabal to get started.
I have the following relevant section of the cabal file test.cabal:
executable libtest.so
hs-source-dirs: src
main-is: Dummy.hs
other-extensions: ForeignFunctionInterface
build-depends: base
default-language: Haskell2010
ghc-options: -no-hs-main -threaded
build-tools: c2hs
Then the source. src/Dummy.hs:
import Test
main :: IO ()
main = return
In the file src/Test.chs
{-# LANGUAGE ForeignFunctionInterface #-}
import Foreign
import Foreign.C
module Android where
And then when I try to compile (cabal configure && cabal build -v) I get the following error message:
Component build order: executable 'libtest.so'
creating dist/build
creating dist/build/autogen
Building test-0.1.0.0...
Preprocessing executable 'libtest.so' for test-0.1.0.0...
Building executable libtest.so...
creating dist/build/libtest.so
creating dist/build/libtest.so/libtest.so-tmp
/opt/ghc/bin/ghc --make -no-link -fbuilding-cabal-package -O -j8 -static
-outputdir dist/build/libtest.so/libtest.so-tmp -odir dist/build
/libtest.so/libtest.so-tmp -hidir dist/build/libtest.so/libtest.so-tmp-stubdir
dist/build/libtest.so/libtest.so-tmp -i -idist/build/libtest.so/libtest.so-tmp
-isrc -idist/build/autogen -Idist/build/autogen
-Idist/build/libtest.so/libtest.so-tmp
-optP-include -optPdist/build/autogen/cabal_macros.h -hide-all-packages
-package-db dist/package.conf.inplace -package-id
base-4.7.0.1-1a55ebc8256b39ccbff004d48b3eb834 -XHaskell2010
src/Dummy.hs -no-hs-main -threaded
src/Dummy.hs:1:8:
Could not find module ‘Test’
Use -v to see a list of the files searched for.
Please, can you tell me what the cause of the error is? What am I missing?
You need to add Test to the other-modules field.

How to link custom object file with Haskell library?

I've created a Haskell package that makes FFI calls to functions defined in CUDA code. I'd like to compile .cu file to an object (.o) file during package build and force linker to link it in.
So far, I tried to use a technique found this question. I've customized buildHook to:
run nvcc
run default buildHook
create ar library file with nvcc compiled code.
Setup.hs is available here.
This solution has a major disadvantage in restricting this package to static linking. Although cabal produces a shared library, it won't work because it has no way of resolving symbols located in the object file.
Is there a simpler way to link custom code during building?
I do a similar thing. I have a Haskell file which calls CUDA code.
Here's how I compile CUDA libraries and link with Haskell:
$(NVCC) -c -E $(NVCC_OPTS) -o build/file.i file.cu
$(NVCC) -c $(NVCC_OPTS) -o build/file.o file.cu
I then link everything into a C++ Shared Library called LibSO with Haskell options
$(CXX) -shared -Wl,-rpath=\$$$$ORIGIN $(CXX_LINK_LIBS) $(PACKAGE_RPATH) -Lbuild -rdynamic -L/usr/local/lib/ghc-7.6.3 -lHSrts-ghc7.6.3 -o build/LibSO.so build/file.o
where
CXX_LINK_LIBS = -Lbuild -lcudart -lcuda -lpthread -lcupti -lcurand -lnvidia-ml
NVCC_OPTS = --compiler-options -fPIC -maxrregcount=0 --machine 64 --DCUDA
I then take my Haskell files and compile them into o and hi files. (I compile twice because of TemplateHaskell)
ghc -v0 -Wall -rtsopts -threaded -stubdir build -ibuild/ -no-hs-main -o build/iop.o -ohi build/iop.hi -c haskell/iop.lhs
ghc -v0 -Wall -rtsopts -threaded -stubdir build -ibuild/ -no-hs-main -fPIC -dynamic -osuf dyn_o -hisuf dyn_hi -o build/iop.dyn_o -ohi build/iop.dyn_hi -c haskell/iop.lhs
So now we have haskell dynamic objects and a C++ shared library.
In the end, I link a main haskell file with everything:
ghc -optl "-Wl,-rpath=\$$ORIGIN" $(CXX_LINK_LIBS) -Lbuild -rtsopts -threaded -lstdc++ -lLibSO -o build/Main build/iop.dyn_o
Does this sort of help?

Profiling library via executable in cabal

Silly question. I have a cabal file with a library and an executable that I would like to use to profile the library, but I can't manage to see cost centers from my library (although I see some from other modules like GHC.IO.Encoding).
Here's a simplified version of my cabal file
flag dev
default: False
manual: True
library
exposed-modules: Foo
ghc-options: -Wall
ghc-prof-options: -fprof-auto
build-depends: base
executable dev-example
if !flag(dev)
buildable: False
ghc-options: -ddump-to-file -ddump-simpl -dsuppress-module-prefixes -dsuppress-uniques -ddump-core-stats -ddump-inlinings
ghc-options: -O2 -rtsopts
ghc-prof-options: -fprof-auto
hs-source-dirs: dev-example, ./
main-is: Main.hs
build-depends: base
Where I've been doing
$ cabal configure -fdev -w /usr/local/bin/ghc-7.6.3 --enable-library-profiling --enable-executable-profiling
$ cabal run dev-example -- +RTS -h -p
Ugh, the issue was simply that my library code was being inlined (or at least marked INLINABLE).

Problem Specifying Source Directory to GHC

This is an embarrassingly simple problem, but its solution yet eludes me. As the title indicates, I simply want to specify to GHC the location of all my source files. This should be simple; the GHC user guide:
-idirs
This flag appends a colon-separated
list of dirs to the search path.
So, I tried the following invocations:
ghc -isrc/ -v -outputdir build/ --make -Wall Main.hs
ghc -isrc/: -v -outputdir build/ --make -Wall Main.hs
ghc -i:src/: -v -outputdir build/ --make -Wall Main.hs
ghc -i"src/" -v -outputdir build/ --make -Wall Main.hs
ghc -i"src/": -v -outputdir build/ --make -Wall Main.hs
ghc -i:"src/": -v -outputdir build/ --make -Wall Main.hs
On every invocation GHC gave the error: "<no location info>: can't find file: Main.hs"
As you probably could have guessed, Main.hs is located in a subdirectory from the working directory called "src". Just in case it matters, I'm on Windows XP, and I'm using GHC 6.12.2. I'm assuming there is some small problem that I'm just missing.
-i specifies where GHC will search for other source files, other than the ones you specify on the command line. So your Main.hs there will also need a src/ prefix. E.g.
$ ghc -isrc src/Main.hs --make
[1 of 1] Compiling Main ( src/Main.hs, src/Main.o )
Linking src/Main ...
Alternatively, you could use cabal, and have cabal init generate all the build metadata for you.

Resources