cabal icon indicating copy to clipboard operation
cabal copied to clipboard

Update cabal-package.rst w.r.t standalone foreign libs

Open andreabedini opened this issue 1 year ago • 8 comments

When describing the options: field for foreign libraries, the user guide currenlty says:

Options for building the foreign library, typically specific to the specified type of foreign library. Currently we only support standalone here. A standalone dynamic library is one that does not have any dependencies on other (Haskell) shared libraries; without the standalone option the generated library would have dependencies on the Haskell runtime library (libHSrts), the base library (libHSbase), etc. Currently, standalone must be used on Windows and must not be used on any other platform.

The phrase "standalone must be used on Windows and must not be used on any other platform" lacks enough details to let the user (or FWIW future contributors :P) understand what the issue is and what happens otherwise.

E.g.

  • When I tried to produce a standalone library on linux, the only issue I ran into was the old RPATH hack we have since removed (in #9164). If boot packages are built with -fPIC, producing a standalone foreign library seems to work without issues.

  • I do not have any knowledge of what can happen not using standalone on Windows (there's even a runtime assertion so one cannot check without modifying cabal). If it is something intrinsic to linking on window, I am wondering: would it make sense to make this automatic? is it worth having the user explictly write options: standalone?

The origin of the phrase seems to be Edsko's commit introducing foreign-libraries: 382143aa7322605d1a9f0480e383490e186c7ea0. The commit message does not provide any further explanation other than "it is not supported":

Add support for foreign libraries.

A stanza for a platform library looks something like

    platform-library test-package
      type:                native-shared

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

      other-modules:       MyPlatformLib.Hello
                           MyPlatformLib.SomeBindings
      build-depends:       base >=4.7 && <4.9
      hs-source-dirs:      src
      c-sources:           csrc/MyPlatformLibWrapper.c
      default-language:    Haskell2010

where native-shared means that we want to build a native shared library
(.so on Linux, .dylib on OSX, .dll on Windows). The parser also
recognizes native-static but this is not currently supported anywhere.
The standalone option means that the we merge all library dependencies
into the dynamic library (i.e., ghc options -shared -static), rather
than make the created dynamic library just record its dependencies (ghc
options -shared -dynamic); it is currently compulsory on Windows and
unsupported anywhere else. The mod-def-file can be used to specify a
module definition file, and is also Windows specific.

There is a bit of refactoring in Build: gbuild is the old buildOrReplExe
and now deals with both executables and platform libraries.

EDIT: what about macOS? We cannot just ignore it.

EDIT 2: AFAIU this just relies on passing the right flags to GHC, so it's GHC doing the linking. In that case, whether it is supported or not is GHC responsibility more than cabal's.

andreabedini avatar Oct 09 '23 03:10 andreabedini

Tagging @bgamari and @angerman as linking experts.

andreabedini avatar Oct 09 '23 04:10 andreabedini

Ah, the good old

Error:     Ambiguous module name ‘System.Directory’:
      it was found in multiple packages:
      directory-1.3.8.1 directory-1.3.8.1
  |
3 | import System.Directory
  | ^^^^^^^^^^^^^^^^^^^^^^^

<interactive>:338:31: error:
    Not in scope: ‘Main.main’
    No module named ‘Main’ is imported.

andreabedini avatar Oct 09 '23 06:10 andreabedini

@BinderDavid @malteneus Would you mind looking at this from a documentation point-of-view? @Mikolaj @ulysses4ever @Kleidukos What should we do here? I think standalone foreign-libs work on Linux but I haven't managed to track down the origin of the original statement.

andreabedini avatar Nov 21 '23 02:11 andreabedini

These are some notes from the investigation I did some months ago https://gist.github.com/andreabedini/a3b012345124854c2fe58380dfe3d4ae

andreabedini avatar Nov 21 '23 03:11 andreabedini

We should probably note that option: standalone might change in the future on windows if and once we support dynamic libraries? (Again assuming my understanding is correct).

This does highlight an issue I experienced with linking static windows libraries when going from 8.10 to 9.6 (and thus also newer cabal) I think.

angerman avatar Nov 23 '23 03:11 angerman

@andreabedini do you see a path forward here? @angerman were all of your comments addressed?

ulysses4ever avatar Jan 07 '24 19:01 ulysses4ever

@ulysses4ever What should we do here? I think standalone foreign-libs work on Linux but I haven't managed to track down the origin of the original statement.

I have not a slightest idea about foreign libs, I'm sorry to say!

ulysses4ever avatar Jan 07 '24 20:01 ulysses4ever

I found this GHC ticket which seems relevant.

andreabedini avatar Aug 02 '24 08:08 andreabedini