Cabal depend on local package with foreign dependencies

Hi there, I have two libraries that I'm working on, packageA and packageB. packageA was written some time ago and depends on a foreign C library, libfoo, which I also wrote and which is installed in a non-standard location. packageB depends on packageA and is new and under active development. I have the following things, then: - libfoo is installed in ~/.local/lib, with includes in ~/.local/include/foo - packageA is in ~/src/packageA - packageB is in ~/src/packageB packageA has a .cabal file which includes: library build-depends: base, ... exposed-modules: A include-dirs: /home/richard/.local/include extra-lib-dirs: /home/richard/.local/lib executable testA ... extra-lib-dirs: /home/richard/.local/lib extra-libraries: foo I've created a cabal sandbox in packageA and I can successfully build it. Now, packageB makes use of packageA. It has a .cabal file which looks like this: library build-depends: base, packageA, ... exposed-modules: B executable testB ... extra-lib-dirs: /home/richard/.local/lib extra-libraries: foo Again, I've created a cabal sandbox in packageB. In order to be able to use packageA (which is not installed anywhere) I believe I have to do: $ cabal add-source ~/src/packageA Next, when I try and configure, it says: cabal: At least the following dependencies are missing: packageA -any That's fine, I assume, because I can now just `cabal install --only-dependencies` to get packageA built into packageB's sandbox. But when I try and do this, I get: $ cabal install --only-dependencies Resolving dependencies... Configuring packageA-0.1... Building packageA-0.1... Preprocessing library packageA-0.1... In-place registering packageA-0.1... Preprocessing executable 'testA' for packageA-0.1... Foo.hsc:10:33: fatal error: foo/foo.h: No such file or directory compilation terminated. So a target of packageA which compiles fine when doing cabal build directly from packageA now fails to compile when I attempt to build it from packageB by installing packageB's dependencies. I'm not sure how to proceed. It feels like maybe I have to tell cabal--when running it from packageB--where the include files are for packageA, because packageA needs to get compiled (which involves linking against libfoo and using libfoo's includes). I know that packageA *does* compile (because I've done that already), but it won't compile inside packageB's sandbox. Any suggestions? Richard

Hi Richard after building packageA, try running "cabal copy" from packageA .cabal dir then run "cabal install packageA" from packageB .cabal dir works for me.

Hi Imants, On Tue, 27 Oct 2015 15:20:09 +0000, Imants Cekusins wrote:
Hi Richard
after building packageA,
try running "cabal copy" from packageA .cabal dir then run "cabal install packageA" from packageB .cabal dir
works for me.
Thanks for this suggestion. I'd not come across the cabal copy command. So I can see that pacakgeA is now installed in its own .cabal-sandbox. But when I try and configure packageB it still says that the dependency is missing. And if I try and build packageB, it still tries to build packageA (and fails just as before). I noticed that cabal copy has a --destdir option, so I tried passing packageB's .cabal-sandbox/ directory as that argument. This actually resulted in it stuffing the binaries etc. into a directory which was at the end of a copy of the absolute path to packageA made inside packageB's .cabal-sandbox/ directory (i.e. ~/src/packageB/.cabal-sandbox/home/richard/src/packageB/.cabal-sandbox/)! I did try manually moving all those files into ~/src/pacakgeB/.cabal-sandbox/ but that didn't fool cabal; it still claimed that packegeA was a missing dependency. Any further thoughts? Richard

Hello Richard, I am not sure why package A builds in its own sandbox, but your copypaste suggests that executable testA does not have an include-dirs section which would tell it where to find foo.h. Could that be the problem? Edward Excerpts from Richard Lewis's message of 2015-10-27 08:08:26 -0700:
Hi there,
I have two libraries that I'm working on, packageA and packageB.
packageA was written some time ago and depends on a foreign C library, libfoo, which I also wrote and which is installed in a non-standard location. packageB depends on packageA and is new and under active development.
I have the following things, then:
- libfoo is installed in ~/.local/lib, with includes in ~/.local/include/foo - packageA is in ~/src/packageA - packageB is in ~/src/packageB
packageA has a .cabal file which includes:
library build-depends: base, ... exposed-modules: A include-dirs: /home/richard/.local/include extra-lib-dirs: /home/richard/.local/lib
executable testA ... extra-lib-dirs: /home/richard/.local/lib extra-libraries: foo
I've created a cabal sandbox in packageA and I can successfully build it.
Now, packageB makes use of packageA. It has a .cabal file which looks like this:
library build-depends: base, packageA, ... exposed-modules: B
executable testB ... extra-lib-dirs: /home/richard/.local/lib extra-libraries: foo
Again, I've created a cabal sandbox in packageB. In order to be able to use packageA (which is not installed anywhere) I believe I have to do:
$ cabal add-source ~/src/packageA
Next, when I try and configure, it says:
cabal: At least the following dependencies are missing: packageA -any
That's fine, I assume, because I can now just `cabal install --only-dependencies` to get packageA built into packageB's sandbox. But when I try and do this, I get:
$ cabal install --only-dependencies Resolving dependencies... Configuring packageA-0.1... Building packageA-0.1... Preprocessing library packageA-0.1... In-place registering packageA-0.1... Preprocessing executable 'testA' for packageA-0.1... Foo.hsc:10:33: fatal error: foo/foo.h: No such file or directory compilation terminated.
So a target of packageA which compiles fine when doing cabal build directly from packageA now fails to compile when I attempt to build it from packageB by installing packageB's dependencies.
I'm not sure how to proceed. It feels like maybe I have to tell cabal--when running it from packageB--where the include files are for packageA, because packageA needs to get compiled (which involves linking against libfoo and using libfoo's includes). I know that packageA *does* compile (because I've done that already), but it won't compile inside packageB's sandbox.
Any suggestions?
Richard

Try to run this from packageB dir: "cabal sandbox add-source {path to C}" Then install packageA from B Also maybe try to run "cabal install packageC" from packageB - this may not be necessary. Btw separate sandboxes - one per each project - work just fine.

Hi Edward, Hmm, well packageA's testA definitely *does* build without needing include-dirs. But I've tried inserting it in case it makes a difference for packageB; it doesn't. But I'm now looking at the errors more carefully (and using verbose cabal output). As pacakgeA was written some time ago, I'd forgotten that it uses hsc. And it's actually the hsc source file which is breaking when pacakgeB attempts to build pacakgeA. Now, I think I've just worked out what's going on here. Typically, I'd abstracted away one very important detail: the "other-modules" options in my .cabal file. The module that's failing to compile is a non-exposed module of packageA. Because it was non-exposed, I was listing it as an "other-modules" requirement of the executable testA. I think, therefore, that when pacakgeB tried to build testA, it ended up trying to build it without the necessary includes. So I've tried making this other module also exposed. (It's not ideally what I'd like, but maybe I'll learn to live with it.) And now packageB is able to build packageA in its sandbox. Richard On Tue, 27 Oct 2015 18:38:29 +0000, Edward Z. Yang wrote:
Hello Richard,
I am not sure why package A builds in its own sandbox, but your copypaste suggests that executable testA does not have an include-dirs section which would tell it where to find foo.h. Could that be the problem?
Edward
Excerpts from Richard Lewis's message of 2015-10-27 08:08:26 -0700:
Hi there,
I have two libraries that I'm working on, packageA and packageB.
packageA was written some time ago and depends on a foreign C library, libfoo, which I also wrote and which is installed in a non-standard location. packageB depends on packageA and is new and under active development.
I have the following things, then:
- libfoo is installed in ~/.local/lib, with includes in ~/.local/include/foo - packageA is in ~/src/packageA - packageB is in ~/src/packageB
packageA has a .cabal file which includes:
library build-depends: base, ... exposed-modules: A include-dirs: /home/richard/.local/include extra-lib-dirs: /home/richard/.local/lib
executable testA ... extra-lib-dirs: /home/richard/.local/lib extra-libraries: foo
I've created a cabal sandbox in packageA and I can successfully build it.
Now, packageB makes use of packageA. It has a .cabal file which looks like this:
library build-depends: base, packageA, ... exposed-modules: B
executable testB ... extra-lib-dirs: /home/richard/.local/lib extra-libraries: foo
Again, I've created a cabal sandbox in packageB. In order to be able to use packageA (which is not installed anywhere) I believe I have to do:
$ cabal add-source ~/src/packageA
Next, when I try and configure, it says:
cabal: At least the following dependencies are missing: packageA -any
That's fine, I assume, because I can now just `cabal install --only-dependencies` to get packageA built into packageB's sandbox. But when I try and do this, I get:
$ cabal install --only-dependencies Resolving dependencies... Configuring packageA-0.1... Building packageA-0.1... Preprocessing library packageA-0.1... In-place registering packageA-0.1... Preprocessing executable 'testA' for packageA-0.1... Foo.hsc:10:33: fatal error: foo/foo.h: No such file or directory compilation terminated.
So a target of packageA which compiles fine when doing cabal build directly from packageA now fails to compile when I attempt to build it from packageB by installing packageB's dependencies.
I'm not sure how to proceed. It feels like maybe I have to tell cabal--when running it from packageB--where the include files are for packageA, because packageA needs to get compiled (which involves linking against libfoo and using libfoo's includes). I know that packageA *does* compile (because I've done that already), but it won't compile inside packageB's sandbox.
Any suggestions?
Richard
participants (3)
-
Edward Z. Yang
-
Imants Cekusins
-
Richard Lewis