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

Cabal 2's 'foreign-library' doesn't work with HEAD #3364

Closed
bjornbm opened this issue Aug 18, 2017 · 9 comments
Closed

Cabal 2's 'foreign-library' doesn't work with HEAD #3364

bjornbm opened this issue Aug 18, 2017 · 9 comments
Milestone

Comments

@bjornbm
Copy link

bjornbm commented Aug 18, 2017

General summary/comments (optional)

Stack HEAD (aa5003a) does not produce a "foreign library" as specified by the foreign-librarystanza in the .cabal file. This stanza is a new feature of Cabal-2.0.0.*.I have tested this only on Windows.

Steps to reproduce

  1. Use HEAD of stack (or commit aa5003a).
  2. stack build this example repository: https://github.com/bjornbm/cabal-flib-invalid-cache-repro.git

This has been tested only on i386-windows.

Expected

I expected a DLL named myflib.dll to be produced.

For comparison this the result of building with cabal-install 2.0.0.0:

$  ~/AppData/Roaming/cabal/bin/cabal.exe --version
cabal-install version 2.0.0.0
compiled using version 2.0.0.2 of the Cabal library
$ PATH=~/AppData/Local/Programs/stack/i386-windows/ghc-8.2.1/bin:$PATH ~/AppData/Roaming/cabal/bin/cabal.exe build
Resolving dependencies...
Configuring testpkg-0.1.0.0...
Preprocessing library for testpkg-0.1.0.0..
Building library for testpkg-0.1.0.0..
[1 of 1] Compiling Lib              ( lib\Lib.hs, dist\build\Lib.o )
Preprocessing foreign library 'myflib' for testpkg-0.1.0.0..
Building foreign library 'myflib' for testpkg-0.1.0.0..
[1 of 1] Compiling FLib             ( flib\FLib.hs, dist\build\myflib\myflib-tmp\FLib.o )
[1 of 1] Compiling FLib             ( flib\FLib.hs, dist\build\myflib\myflib-tmp\FLib.o ) [flags changed]
Linking dist\build\myflib\myflib.dll ...

Actual

Stack complained:

$ stack build
testpkg-0.1.0.0: configure (lib)
Configuring testpkg-0.1.0.0...
testpkg-0.1.0.0: build (lib)
Preprocessing library for testpkg-0.1.0.0..
Building library for testpkg-0.1.0.0..
[1 of 1] Compiling Lib              ( lib\Lib.hs, .stack-work\dist\9cd999cb\build\Lib.o )
testpkg-0.1.0.0: copy/register
Installing library in C:\Users\bjorn\repos\cabal-flib-invalid-cache-repro\.stack-work\install\03648e34\lib\i386-windows-ghc-8.2.1\testpkg-0.1.0.0-8BkLVLBjses1NkNpiyJL1z
Installing foreign library myflib in C:\Users\bjorn\repos\cabal-flib-invalid-cache-repro\.stack-work\install\03648e34\lib
.stack-work\dist\9cd999cb\build\myflib\myflib.dll: copyFile: does not exist (No such file or directory)
'cabal copy' failed.  Error message:

--  While building package testpkg-0.1.0.0 using:
      C:\sr\setup-exe-cache\i386-windows\Cabal-simple_Z6RU0evB_2.0.0.2_ghc-8.2.1.exe --builddir=.stack-work\dist\9cd999cb copy
    Process exited with code: ExitFailure 1

One possible cause of this issue is:
* No module named "Main". The 'main-is' source file should usually have a header indicating that it's a 'Main' module.

No .stack-work\dist\9cd999cb\build\myflib directory was created, and of course no myflib.dll was created in that directory.

The log of stack build --verbose --cabal-verbose can be found in this Gist.

Stack version

$ stack --version
Version 1.5.1, Git revision aa5003a153504f54051e42a844a0c1c3d7f82163 (5099 commits) i386 hpack-0.17.1

Built from commit aa5003a.

Method of installation

Built from clean checkout of HEAD from github.

@mgsloan mgsloan added this to the P1: Must milestone Aug 18, 2017
@mgsloan
Copy link
Contributor

mgsloan commented Aug 18, 2017

Head version of stack only recently started using Cabal 2.0, there isn't yet support for these new features.

@decentral1se decentral1se changed the title Stack does not build foreign-library Cabal 2's 'foreign-library' doesn't work with HEAD Aug 19, 2017
@snoyberg
Copy link
Contributor

Can you provide any information on how Cabal's command line interface (the Setup.hs bit) exposes this functionality?

@bjornbm
Copy link
Author

bjornbm commented Aug 31, 2017

The functionality is exposed by a new stanza in the .cabal file. See http://cabal.readthedocs.io/en/latest/developing-packages.html#foreign-libraries. No custom Setup.hs is needed. To what extent it is exposed/hackable in Setup.hs I don't know.

Example stanza:

foreign-library myforeignlib
  type:                native-shared
  lib-version-info:    6:3:2

  if os(Windows)
    options: standalone
    mod-def-file: MyForeignLib.def

  other-modules:       MyForeignLib.SomeModule
                       MyForeignLib.SomeOtherModule
  build-depends:       base >=4.7 && <4.9
  hs-source-dirs:      src
  c-sources:           csrc/MyForeignLibWrapper.c
  default-language:    Haskell2010

Not sure to what extent this addresses your question. I don't have experience customizing Setup.hs.

@snoyberg
Copy link
Contributor

What I'm trying to understand is what changes Stack needs to make in order to make this functionality work. In order to build a package, Stack uses the Setup.hs file and essentially runs ./Setup build && ./Setup copy && ./Setup register. It seems like there's something new it has to do. If you can provide information on what that is (or, even better, try your hand at a PR implementing it), that will make things go faster here.

@mgsloan
Copy link
Contributor

mgsloan commented Aug 31, 2017

One way to figure it out is to run stack build -v and take a look at the Run process: invocations. Assuming the package is in the current dir, you should be able to do stack exec bash, and then within that shell run the commands. My guess is that it has something to do with the targets passed to the build invocation. Perhaps when specifying build targets, these foreign libraries need to be specified in some way.

@snoyberg
Copy link
Contributor

It looks like this is almost identical to the internal library issue: there's a new list of extra libraries that are simply not being accounted for by the current logic. It's going to require, in all places where we deal with library and executable components, piping through these extra library components too.

snoyberg added a commit that referenced this issue Sep 13, 2017
This should resolve both #3364 and #3361. There is a test case included
that should address both of them as well.

This is still relatively hacky. We will eventually be overhauling the
component system more dramatically to support Backpack with #2540 (CC
@ezyang).

This may still have some problems due to the upstream issue
haskell/cabal#4763, but at least in theory we're matching the behavior
of upstream. We can consider workarounds after that issue comes to a
conclusion.
@snoyberg
Copy link
Contributor

This should be resolved by #3430. It would be great if you could test that branch before this gets merged to master.

@bjornbm
Copy link
Author

bjornbm commented Sep 14, 2017

Both the simple repo referenced in the description as well as my more complicated project build successfully on both OS X and Windows, generating a .dylib and .dll respectively. I have tested the functions exported by the generated .dll on Windows and they are fine. In other words: all appears perfect! Many thanks! 👍 👍 👍

@snoyberg
Copy link
Contributor

Awesome, thanks for the quick response! I'm going to merge that PR and close out this issue. Thanks again for the report.

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

No branches or pull requests

3 participants