Cabal, lib and exe in one

I'm trying to create a single cabal file containing specs for both a library and an executable using that library. I'm not having much luck though :( This is what I have so far: name: foo version: 0.1 exposed-modules: Foo.Bar other-modules: Foo.Qux Foo.C2HS hs-source-dirs: src include-dirs: csrc c-sources: csrc/qux.c extensions: ForeignFunctionInterface build-depends: base, haskell98 executable: foo hs-source-dirs: test-src main-is: foo.hs other-modules: Foo.Bar When built this is the message I get: test-src/foo.hs:5:7: Could not find module `Foo.Bar': Use -v to see a list of the files searched for. How do I specify that Foo.Bar is found where cabal puts it (./dist/build/)? /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus@therning.org Jabber: magnus.therning@gmail.com http://therning.org/magnus Software is not manufactured, it is something you write and publish. Keep Europe free from software patents, we do not want censorship by patent law on written works. Finagle's Fifth Law: Always draw your curves, then plot your readings.

On Tue, 2007-05-01 at 09:34 +0100, Magnus Therning wrote:
I'm trying to create a single cabal file containing specs for both a library and an executable using that library. I'm not having much luck though :(
This is what I have so far:
name: foo version: 0.1 exposed-modules: Foo.Bar other-modules: Foo.Qux Foo.C2HS hs-source-dirs: src include-dirs: csrc c-sources: csrc/qux.c extensions: ForeignFunctionInterface build-depends: base, haskell98
executable: foo hs-source-dirs: test-src main-is: foo.hs other-modules: Foo.Bar
When built this is the message I get: test-src/foo.hs:5:7: Could not find module `Foo.Bar': Use -v to see a list of the files searched for.
How do I specify that Foo.Bar is found where cabal puts it (./dist/build/)?
But surely Foo.Bar is in src, it is afterall exactly the same module as the one you're using in the library, no? So if foo.hs is in test-src and Foo/Bar.hs is in src then I think you just need: hs-source-dirs: test-src, src You cannot specify that things are found in dist/build since that dir can placed anywhere by the user. But I don't see that you'd want to, I can't see how it makes any sense. Duncan

On Tue, May 01, 2007 at 12:02:18 +0100, Duncan Coutts wrote:
On Tue, 2007-05-01 at 09:34 +0100, Magnus Therning wrote:
I'm trying to create a single cabal file containing specs for both a library and an executable using that library. I'm not having much luck though :(
This is what I have so far:
name: foo version: 0.1 exposed-modules: Foo.Bar other-modules: Foo.Qux Foo.C2HS hs-source-dirs: src include-dirs: csrc c-sources: csrc/qux.c extensions: ForeignFunctionInterface build-depends: base, haskell98
executable: foo hs-source-dirs: test-src main-is: foo.hs other-modules: Foo.Bar
When built this is the message I get: test-src/foo.hs:5:7: Could not find module `Foo.Bar': Use -v to see a list of the files searched for.
How do I specify that Foo.Bar is found where cabal puts it (./dist/build/)?
But surely Foo.Bar is in src, it is afterall exactly the same module as the one you're using in the library, no?
Yes.
So if foo.hs is in test-src and Foo/Bar.hs is in src then I think you just need:
hs-source-dirs: test-src, src
No, that's not enough, I also have to add the following lines to make the executable compile and link: extensions: ForeignFunctionInterface c-sources: csrc/ptrace.c That is, I end up compiling the library a second time! Can't I get the executable to link against the library that was just created?
You cannot specify that things are found in dist/build since that dir can placed anywhere by the user. But I don't see that you'd want to, I can't see how it makes any sense.
I was just expecting to not have to repeat myself in the cabal file. Not such a strange thing to expect from a build system, I think :-) Also, I don't really see what you mean by "that dir can be placed anywhere by the user". That dir is created as part of the build process and it's location is, AFAICS, always going to be ./dist/build. Finding the library after installation is another matter, but that problem should be taken care of during the `./Setup.hs configure` stage. /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus@therning.org Jabber: magnus.therning@gmail.com http://therning.org/magnus

On Tue, 2007-05-01 at 22:29 +0100, Magnus Therning wrote:
So if foo.hs is in test-src and Foo/Bar.hs is in src then I think you just need:
hs-source-dirs: test-src, src
No, that's not enough, I also have to add the following lines to make the executable compile and link:
extensions: ForeignFunctionInterface c-sources: csrc/ptrace.c
That is, I end up compiling the library a second time! Can't I get the executable to link against the library that was just created?
I was just expecting to not have to repeat myself in the cabal file. Not such a strange thing to expect from a build system, I think :-)
Yes this is an interesting question about what it means to have programs in the same cabal package as an executable. Currently having a executable and a library inside a cabal package is not the same thing as having a library package and separate package that contains only that executable. The difference is that when the executable is in the same cabal package it merely has access to the same modules, it doesn't 'depend' on that library package exactly. So for example it can access modules which are not exposed by the library and indeed it can compile those same modules with completely different build flags. So currently those modules will be built twice. It's not clear to me that this is the right meaning, or indeed that we should allow multiple entries in a single .cabal file. I think it might be better to just have multiple .cabal files (possibly in the same directory). Then we could be explicit and state that an executable depends on the library or if we want to use different build flags, or use modules that are not exposed by the lib then we can do that and only in that case do we build those modules twice.
Also, I don't really see what you mean by "that dir can be placed anywhere by the user". That dir is created as part of the build process and it's location is, AFAICS, always going to be ./dist/build.
Actually it's location can be set at configure time with --scratchdir= so that for example you could put it in a temp dir or something. Duncan

Duncan Coutts wrote:
On Tue, 2007-05-01 at 22:29 +0100, Magnus Therning wrote:
So if foo.hs is in test-src and Foo/Bar.hs is in src then I think you just need:
hs-source-dirs: test-src, src No, that's not enough, I also have to add the following lines to make the executable compile and link:
extensions: ForeignFunctionInterface c-sources: csrc/ptrace.c
That is, I end up compiling the library a second time! Can't I get the executable to link against the library that was just created?
I was just expecting to not have to repeat myself in the cabal file. Not such a strange thing to expect from a build system, I think :-)
Yes this is an interesting question about what it means to have programs in the same cabal package as an executable.
Currently having a executable and a library inside a cabal package is not the same thing as having a library package and separate package that contains only that executable. The difference is that when the executable is in the same cabal package it merely has access to the same modules, it doesn't 'depend' on that library package exactly. So for example it can access modules which are not exposed by the library and indeed it can compile those same modules with completely different build flags. So currently those modules will be built twice.
It's not clear to me that this is the right meaning, or indeed that we should allow multiple entries in a single .cabal file. I think it might be better to just have multiple .cabal files (possibly in the same directory). Then we could be explicit and state that an executable depends on the library or if we want to use different build flags, or use modules that are not exposed by the lib then we can do that and only in that case do we build those modules twice.
Right at the front of the Cabal docs it says: "However having both a library and executables in a package does not work very well; if the executables depend on the library, they must explicitly list all the modules they directly or indirectly import from that library." IMO we shouldn't allow both a library and an exe in the same package. I think I argued against this originally, and my understanding is that doing this is deprecated, although perhaps not visibly enough. Whenever the question of what to do about lib+exe packages arises, the discussion tends to spiral out of control into what we should do about collections of packages in general. For now, the simple story is that each package should have either a single library or a single executable (even multiple executables in a package is questionable; if they share some code it shoud be in a package). Cheers, Simon

On Wed, May 02, 2007 at 10:08:41 +0100, Simon Marlow wrote: [..]
IMO we shouldn't allow both a library and an exe in the same package. I think I argued against this originally, and my understanding is that doing this is deprecated, although perhaps not visibly enough. Whenever the question of what to do about lib+exe packages arises, the discussion tends to spiral out of control into what we should do about collections of packages in general.
For now, the simple story is that each package should have either a single library or a single executable (even multiple executables in a package is questionable; if they share some code it shoud be in a package).
So, you are saying that I should split my library and its test app(s) into separate packages? That would also mean that I have to install the library before compiling and running the tests, right? Hmmm, if that's the case then I have to say that cabal won't suit me very well. Are there any options to cabal? /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus@therning.org Jabber: magnus.therning@gmail.com http://therning.org/magnus

On Wed, 2007-05-02 at 13:58 +0100, Magnus Therning wrote:
So, you are saying that I should split my library and its test app(s) into separate packages? That would also mean that I have to install the library before compiling and running the tests, right?
No, I don't think that's very practical at the moment. At the moment I'd just keep it in one .cabal file and just add all the src dirs and .c files etc that you need into each program section. It's not very pretty but it's not completely unwieldy. What we should probably do is make it easier to deal with a collection of packages including registering packages in-place and then it'd become quite practical to have multiple .cabal files, one for each lib and binary in your system. And you'd be able to express the proper dependencies between them. This is the kind of thing that people have been thinking about for a while, but there are some tricky issues and it's also quite a lot of work.
Hmmm, if that's the case then I have to say that cabal won't suit me very well. Are there any options to cabal?
Nothing easy. Duncan

I think Simon is right, and not just from a Haskell point of view. Allowing a package to contain a both a library and an executable makes the behavior of the package system less obvious. That's not to say that it can't behave "correctly", but that it can't behave both "correctly" and in a way that is easy to understand. Yes, it makes installation of an executable package more complicated if you have to install its library package as well. But making this simple should be handled by a layer above the cabal package files (Hackage?). In my experience, the best packaging systems distinguish between dependency assurance and dependency satisfaction. For example, the Debian packaging system has two layers. dpkg deals with package files, installing a single package, and assuring that dependencies are met prior to installation. apt-get retrieves packages from repositories with their pre-reqs (based on the dependency) and invokes dpkg on the retrieved packages. I know the problem is not identical to the one cabal is trying to solve, but I think there is a great deal to be learned by looking at the Debian packaging system and its conventions. In any event, solid naming conventions could go a long way to making this obvious. If foo has a useful exposed library, but primarily consists of an executable, dividing it into foo-bin and foo-lib could serve to clarify. I would propose that, since the bulk of existing packages seem to be libraries, we use a naming convention to distinguish packages that build executables and leave the names of library packages unannotated. -r On May 2, 2007, at 2:08 AM, Simon Marlow wrote:
Duncan Coutts wrote:
So if foo.hs is in test-src and Foo/Bar.hs is in src then I think you just need:
hs-source-dirs: test-src, src No, that's not enough, I also have to add the following lines to make the executable compile and link:
extensions: ForeignFunctionInterface c-sources: csrc/ptrace.c
That is, I end up compiling the library a second time! Can't I get the executable to link against the library that was just created? I was just expecting to not have to repeat myself in the cabal file. Not such a strange thing to expect from a build system, I think :-) Yes this is an interesting question about what it means to have
On Tue, 2007-05-01 at 22:29 +0100, Magnus Therning wrote: programs in the same cabal package as an executable. Currently having a executable and a library inside a cabal package is not the same thing as having a library package and separate package that contains only that executable. The difference is that when the executable is in the same cabal package it merely has access to the same modules, it doesn't 'depend' on that library package exactly. So for example it can access modules which are not exposed by the library and indeed it can compile those same modules with completely different build flags. So currently those modules will be built twice. It's not clear to me that this is the right meaning, or indeed that we should allow multiple entries in a single .cabal file. I think it might be better to just have multiple .cabal files (possibly in the same directory). Then we could be explicit and state that an executable depends on the library or if we want to use different build flags, or use modules that are not exposed by the lib then we can do that and only in that case do we build those modules twice.
Right at the front of the Cabal docs it says:
"However having both a library and executables in a package does not work very well; if the executables depend on the library, they must explicitly list all the modules they directly or indirectly import from that library."
IMO we shouldn't allow both a library and an exe in the same package. I think I argued against this originally, and my understanding is that doing this is deprecated, although perhaps not visibly enough. Whenever the question of what to do about lib +exe packages arises, the discussion tends to spiral out of control into what we should do about collections of packages in general.
For now, the simple story is that each package should have either a single library or a single executable (even multiple executables in a package is questionable; if they share some code it shoud be in a package).
Cheers, Simon _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (4)
-
Duncan Coutts
-
Magnus Therning
-
R Hayes
-
Simon Marlow