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

running cabal-doctest on code that does FFI #37

Open
cdepillabout opened this issue Mar 9, 2018 · 7 comments
Open

running cabal-doctest on code that does FFI #37

cdepillabout opened this issue Mar 9, 2018 · 7 comments

Comments

@cdepillabout
Copy link

I'm trying to run cabal-doctest on a package that contains code that does FFI, but I am getting an error about an Illegal foreign declaration:

$ stack test mypackage:mypackage-doctests

mypackage-0.1.0.0: test (suite: mypackage-doctests)

-i
-i/home/user/git/mypackage/.stack-work/dist/x86_64-linux-nopie/Cabal-2.0.1.0/build/autogen
-i/home/user/git/mypackage/.stack-work/dist/x86_64-linux-nopie/Cabal-2.0.1.0/build
-i/home/user/git/mypackage/src
-I/home/user/git/mypackage/include
-hide-all-packages
-no-user-package-db
-package-db=/home/user/.stack/snapshots/x86_64-linux-nopie/lts-10.1/8.2.2/pkgdb
-package-db=/home/user/git/mypackage/.stack-work/install/x86_64-linux-nopie/lts-10.1/8.2.2/pkgdb
-package-db=.stack-work/dist/x86_64-linux-nopie/Cabal-2.0.1.0/package.conf.inplace
-optP-include
-optP.stack-work/dist/x86_64-linux-nopie/Cabal-2.0.1.0/build/autogen/cabal_macros.h
-optP-std=c++11
-optP-g
-XCPP
-XDeriveDataTypeable
-XEmptyDataDecls
-XFlexibleContexts
-XFlexibleInstances
-XGADTs
-XGeneralizedNewtypeDeriving
-XMultiParamTypeClasses
-XNoImplicitPrelude
-XNoMonomorphismRestriction
-XOverloadedStrings
-XQuasiQuotes
-XRecordWildCards
-XStrict
-XStrictData
-XTemplateHaskell
-XTupleSections
-XTypeFamilies
-XViewPatterns
-package-id=base-4.10.1.0
-package-id=bytestring-0.10.8.2
-package-id=text-1.2.2.2-9VTsh6V7U7hpagw2HDvpZ
-package-id=yaml-0.8.25-4pReAuIriLM49ZzXYo2cQB
-package-id=directory-1.3.0.2
-package-id=aeson-1.2.3.0-ugexjDh4BlCBSU1ypSCIP
-package-id=monad-logger-0.3.26-HML9yY1QV17FFM52i6WgV1
-package-id=transformers-0.5.2.0
-package-id=unordered-containers-0.2.8.0-6Q8cKU0tfULGVDjEZYkMDG
-package-id=containers-0.5.10.2
-package-id=vector-0.12.0.1-IUGn3M9mkBh8CyXcBnfTR4
-package-id=multimap-1.2.1-3GJfs4zkCkW9B3Fr8In11Z
-package-id=time-1.8.0.2
-package-id=stm-2.4.4.1-6AExGOUG8NB2Rzejnay0ww
-package-id=mtl-2.2.1-DscMMmDQUE6GBfOSl4qMUH
-package-id=async-2.1.1.1-H3j65XcXMHtBvmNwGCQ80G
-package-id=machinecell-3.3.2-FExSUJRpVnSzomdqOFNnQ
-package-id=repa-3.4.1.3-GEnIKEZpCV61MI3ixuOgDr
-package-id=base64-bytestring-1.0.0.1-8MlzMz2YH3lCqJ4GOwL1Be
-package-id=JuicyPixels-3.2.9.1-BVWqbGS41WB1algPpFp0MX
-package-id=JuicyPixels-repa-0.7.1.0-HdCUFuhlE2KLkfygLx9oIP
-package-id=protocol-buffers-2.4.6-47f03hB2WvJAHf1FpvcHy
-package-id=split-0.2.3.2-7cayvoeRj5XIrIBUB58mMy
-package-id=binary-0.8.5.1
-package-id=binary-orphans-0.1.8.0-8PLkSxRGG1kBUzNCD3xKty
-package-id=random-1.1-LLUGZ7T9DqQ5vN0Jbcd0We
-package-id=random-shuffle-0.0.4-KDdg8pdjcYGELQehGYXr0X
-package-id=network-2.6.3.2-Elf6Dxkfz0iKjb1zv5eBTP
-package-id=network-ip-0.3.0.2-B85Xtbe1mSN1xAVqRKIk2F
-package-id=MissingH-1.4.0.1-ImyRV7T8Qr2ErDeNfuBTMk
-package-id=fft-0.1.8.6-HQVRSUFjKmx2zA2dGyOfvA
-package-id=carray-0.1.6.8-HwQa2zABqEdJhijAqYXaoj
-package-id=csv-conduit-0.6.7-1fdundjwG291W8v1e6PJ81
-package-id=classy-prelude-1.3.1-ANeqbljMhXs5dVxxtSFDQi
-package-id=doctest-0.13.0-FhL1bQZiTYWBiul8DyT6Aa
-package=mypackage-0.1.0.0
-package-id=QuickCheck-2.10.1-Ewacc04OJICEFWthkI3IgS
-package-id=template-haskell-2.12.0.0
....
MyModule
....


/home/user/git/mypackage/src/MyModule.hs:44:1: error:
    • Illegal foreign declaration: requires unregisterised, llvm (-fllvm) or native code generation (-fasm)
    • When checking declaration:
        foreign export ccall "my_func" my_func
          :: IO Bool
   |
44 | foreign export ccall my_func :: IO Bool
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Examples: 0  Tried: 0  Errors: 0  Failures: 0

mypackage-0.1.0.0: Test suite mypackage-doctests passed

Here's the mypackage-doctests stanza out of the cabal file:

test-suite mypackage-doctests
    type:                exitcode-stdio-1.0
    main-is:             doctests.hs
    hs-source-dirs:      test
    build-depends:       base
                       , doctest >= 0.11.3 && <0.14
                       , mypackage
                       -- QuickCheck and template-haskell are used when
                       -- actually running the the doctest exectuable.  They
                       -- must not be removed.
                       , QuickCheck ==2.10.*
                       , template-haskell

    ghc-options:         -Wall -threaded
    default-language:    Haskell2010

The DocTest.hs file is identical to the one defined here. The Setup.hs file in the repository is identical to the one defined here.


Is it possible to run doctests on code that does FFI?

If not, is there an easy way to tell cabal-doctest that I don't actually need that file tested, but please test the other ones?

@phadej
Copy link
Collaborator

phadej commented Mar 9, 2018

Could you try adding x-doctest-option: -fobject-code, that's IIRC required to load FFI code into GHCi anyway.

@cdepillabout
Copy link
Author

cdepillabout commented Mar 9, 2018

That seems to work, thanks!

However, it leaves .o and .hi files next to the .hs files.

For instance, in my example above, if I have src/Foo.hs, after running the mypackage-doctest stanza, I am left with a Foo.hi and Foo.o file in src/. Since I am using stack, I would have expected that they would be created in .stack-work/ instead of being left in the src/ directory.

Do you know of an easy way to make it so that doctest doesn't leave around these .hi and .o files when using -fobject-code?

Also, do you want me to send a PR to cabal-doctest updating the README.md to suggest -fobject-code?

@phadej
Copy link
Collaborator

phadej commented Mar 9, 2018

@cdepillabout you could try -outputdir
But setting it to .stack-work will be build-tool dependent. We can teach cabal-doctest to set it to some path Cabal gives us hint abou (e.g. somewhere in dist-newstyle if cabal new-build is used)

@cdepillabout
Copy link
Author

cdepillabout commented Mar 9, 2018

Thanks for the suggestion about -outputdir. I specified -outputdir in x-doctest-options along with -fobject-code and all the .hi and .o files were put in that directory.

However, when I re-run the mypackage-doctest test suite, it appears that something weird is happening. The first module that it tries to compile (and run doctest on) can't find Prelude:

/home/user/git/mypackage/src/Foo.hs:5:1: error:
    Could not find module ‘Prelude’
    Use -v to see a list of the files searched for.
  |
5 | import           Prelude
  | ^^^^^^^^^^^^^^^^^^^^^^^^

If I delete the directory passed to -outputdir and re-run the mypackage-doctest test suite, the above problem disappears.

I'm not sure the best way to fix this.

I'll probably go ahead and edit my doctest.hs file to delete the above directory before the tests are run, but if you have a better idea I'd definitely be interested in hearing it!

But setting it to .stack-work will be build-tool dependent. We can teach cabal-doctest to set it to some path Cabal gives us hint about.

That makes sense 👍

@cdepillabout
Copy link
Author

Hmm, one more unfortunate thing about needing to use -fobject-code is that it doesn't seem to play nice with doctest in some cases:

sol/doctest#160

@phadej
Copy link
Collaborator

phadej commented Jan 28, 2019

@cdepillabout can you make a small package to reproduce the problems.

I think sol/doctest#217 can help in some situations (i.e. when you don't use non-exposed internals)

@cdepillabout
Copy link
Author

@phadej I'm sorry, I don't remember too much about what was causing this, and I don't have access to the code anymore that was causing this. (It was at a previous job.)

Please feel free to close this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants