Re: [Haskell-cafe] "Cabal ignores ld-options?" - 2011 remix

On Sun, 2011-01-30 at 05:20 -0500, Ryan Newton wrote:
I am trying to link a ".a" file built by a separate makefile into my library. GHC has no problem with it, but I need to convince cabal to do it for the package to be hackage-friendly. There's a thread about this back in 2007:
http://www.haskell.org/pipermail/cabal-devel/2007-April/000507.html
Is there a method for this now, or is the state of affairs the same as before?
Having a Haskell package link against an external C library is straightforward, you just list it in the extra-libraries field. The external library must already be installed on the system however. Bundling a copy of the external library with a cabal package is not quite so easy. You will have to write code in the Setup.hs to call the separate makefile during the build (and perhaps extra steps at configure time too). Your best bet is probably to use the "simple" build system's hooks API. You can list the library in the extra-libraries field in the .cabal file but you will also need to modify the check for external libraries that are done in the postConf hook (since the separate .a library will not be available at configure time): modify the package description that gets passed to the postConf hook to exclude the library. Duncan

Thanks Duncan, Alas, I don't think it's something I want to install globally on the users machine. It's actually not much code, but I can't get cabal to build it directly because it chokes on the .s assembly files (which are intel syntax not AT&T). Right now I'm depending on "yasm". The makefile I run just executes the commands listed at the end of this email. After much random monkeying thusfar, I'd be happy with anything that works ;-). Is extra-lib-dirs for an executable supposed to change the search path at runtime? Via extra-libraries I can successfully introduce the dependency on libFOO.so (as reported by ldd). But the search path appears to not be modified (without manually tweaking LD_LIBRARY_PATH -- I'm on ubuntu). This approach is what I was trying to do in commit 0abc7d0a456ee0d818b2https://github.com/rrnewton/intel-aes/commit/0abc7d0a456ee0d818b2313184f0d25...here: git clone git://github.com/rrnewton/intel-aes.git git checkout 0abc7d0a456ee0d818b2313184f0d253aae10e47 (Note that the makefile in cbits still needs to be run manually in that version.) "extra-libraries" is only for dynamic libs of the form "libXX.so|dylib|dll" right? Even if they were globally installed it doesn't help with .a libs, does it? The users guide says "A list of extra libraries to link with." -- at the cost of verbosity a bit of elaboration would be much appreciated ;-). In any case, I want to try playing with the hooks that you mentioned. But I have at least one newbish question first. I'm running "cabal install" inside my package's directory and that doesn't seem to run Setup.hs. Is that not the way to simulate the eventual effect of a user "cabal install"ing from hackage? Cheers, -Ryan P.S. Build commands: gcc -fPIC -O3 -g -Iinclude/ -c src/intel_aes.c -o obj/x64/intel_aes.o yasm -D__linux__ -g dwarf2 -f elf64 asm/x64/iaesx64.s -o obj/x64/iaesx64.o yasm -D__linux__ -g dwarf2 -f elf64 asm/x64/do_rdtsc.s -o obj/x64/do_rdtsc.o ar -r lib/x64/libintel_aes.a obj/x64/intel_aes.o obj/x64/iaesx64.o obj/x64/do_rdtsc.o gcc -shared -dynamic -o lib/x64/libintel_aes.so obj/x64/intel_aes.o obj/x64/iaesx64.o obj/x64/do_rdtsc.o On Sun, Jan 30, 2011 at 12:22 PM, Duncan Coutts < duncan.coutts@googlemail.com> wrote:
On Sun, 2011-01-30 at 05:20 -0500, Ryan Newton wrote:
I am trying to link a ".a" file built by a separate makefile into my library. GHC has no problem with it, but I need to convince cabal to do it for the package to be hackage-friendly. There's a thread about this back in 2007:
http://www.haskell.org/pipermail/cabal-devel/2007-April/000507.html
Is there a method for this now, or is the state of affairs the same as before?
Having a Haskell package link against an external C library is straightforward, you just list it in the extra-libraries field. The external library must already be installed on the system however.
Bundling a copy of the external library with a cabal package is not quite so easy. You will have to write code in the Setup.hs to call the separate makefile during the build (and perhaps extra steps at configure time too).
Your best bet is probably to use the "simple" build system's hooks API. You can list the library in the extra-libraries field in the .cabal file but you will also need to modify the check for external libraries that are done in the postConf hook (since the separate .a library will not be available at configure time): modify the package description that gets passed to the postConf hook to exclude the library.
Duncan

Ok, I've made some progress in the direction Duncan suggested.
I can filter out the extra library before the postConf hook gets it. And
calling "make" from the hooks is pretty easy.
I've got a hack working that does allow full build/link/install given a
hardcoded path (e.g. hack). It works by passing -Wl,-rpath=/opt/...
directly through the .cabal file (ld-options). I need to un-hardcode that
directory but I can't figure out how to achieve the same effect as that
ld-options from my Setup.hs (I tried adding buildProgramArgs in the
buildHook but no luck yet).
There's also the question of how to find the install dir so that rpath can
be set to it. Unfortunately, I haven't been able to dig that out yet. When
I try to use absoluteInstallDirs via something like below, I get this error:
"setup: internal error InstallDirs.libsubdir"
putStrLn$ "Install dirs: " ++ show (absoluteInstallDirs desc linfo
NoCopyDest)
Best,
-Ryan
On Sun, Jan 30, 2011 at 10:20 PM, Ryan Newton
Thanks Duncan,
Alas, I don't think it's something I want to install globally on the users machine. It's actually not much code, but I can't get cabal to build it directly because it chokes on the .s assembly files (which are intel syntax not AT&T). Right now I'm depending on "yasm". The makefile I run just executes the commands listed at the end of this email.
After much random monkeying thusfar, I'd be happy with anything that works ;-). Is extra-lib-dirs for an executable supposed to change the search path at runtime? Via extra-libraries I can successfully introduce the dependency on libFOO.so (as reported by ldd). But the search path appears to not be modified (without manually tweaking LD_LIBRARY_PATH -- I'm on ubuntu). This approach is what I was trying to do in commit 0abc7d0a456ee0d818b2https://github.com/rrnewton/intel-aes/commit/0abc7d0a456ee0d818b2313184f0d25...here:
git clone git://github.com/rrnewton/intel-aes.git git checkout 0abc7d0a456ee0d818b2313184f0d253aae10e47
(Note that the makefile in cbits still needs to be run manually in that version.)
"extra-libraries" is only for dynamic libs of the form "libXX.so|dylib|dll" right? Even if they were globally installed it doesn't help with .a libs, does it? The users guide says "A list of extra libraries to link with." -- at the cost of verbosity a bit of elaboration would be much appreciated ;-).
In any case, I want to try playing with the hooks that you mentioned. But I have at least one newbish question first. I'm running "cabal install" inside my package's directory and that doesn't seem to run Setup.hs. Is that not the way to simulate the eventual effect of a user "cabal install"ing from hackage?
Cheers, -Ryan
P.S. Build commands:
gcc -fPIC -O3 -g -Iinclude/ -c src/intel_aes.c -o obj/x64/intel_aes.o yasm -D__linux__ -g dwarf2 -f elf64 asm/x64/iaesx64.s -o obj/x64/iaesx64.o yasm -D__linux__ -g dwarf2 -f elf64 asm/x64/do_rdtsc.s -o obj/x64/do_rdtsc.o ar -r lib/x64/libintel_aes.a obj/x64/intel_aes.o obj/x64/iaesx64.o obj/x64/do_rdtsc.o gcc -shared -dynamic -o lib/x64/libintel_aes.so obj/x64/intel_aes.o obj/x64/iaesx64.o obj/x64/do_rdtsc.o
On Sun, Jan 30, 2011 at 12:22 PM, Duncan Coutts < duncan.coutts@googlemail.com> wrote:
On Sun, 2011-01-30 at 05:20 -0500, Ryan Newton wrote:
I am trying to link a ".a" file built by a separate makefile into my library. GHC has no problem with it, but I need to convince cabal to do it for the package to be hackage-friendly. There's a thread about this back in 2007:
http://www.haskell.org/pipermail/cabal-devel/2007-April/000507.html
Is there a method for this now, or is the state of affairs the same as before?
Having a Haskell package link against an external C library is straightforward, you just list it in the extra-libraries field. The external library must already be installed on the system however.
Bundling a copy of the external library with a cabal package is not quite so easy. You will have to write code in the Setup.hs to call the separate makefile during the build (and perhaps extra steps at configure time too).
Your best bet is probably to use the "simple" build system's hooks API. You can list the library in the extra-libraries field in the .cabal file but you will also need to modify the check for external libraries that are done in the postConf hook (since the separate .a library will not be available at configure time): modify the package description that gets passed to the postConf hook to exclude the library.
Duncan

On Mon, 2011-01-31 at 01:13 -0500, Ryan Newton wrote:
Ok, I've made some progress in the direction Duncan suggested.
I can filter out the extra library before the postConf hook gets it. And calling "make" from the hooks is pretty easy.
I've got a hack working that does allow full build/link/install given a hardcoded path (e.g. hack). It works by passing -Wl,-rpath=/opt/... directly through the .cabal file (ld-options). I need to un-hardcode that directory but I can't figure out how to achieve the same effect as that ld-options from my Setup.hs (I tried adding buildProgramArgs in the buildHook but no luck yet).
Just modify the package description instead, e.g. in the configure step. The build prog args is intended for users, not for package authors. (It's so that cabal build --$PROG-options= works, and that's not something you're supposed to interfere with. Afterall, users are in control and can always add whatever options they want by adding wrapper scripts etc, this just makes it more convenient.)
There's also the question of how to find the install dir so that rpath can be set to it. Unfortunately, I haven't been able to dig that out yet. When I try to use absoluteInstallDirs via something like below, I get this error: "setup: internal error InstallDirs.libsubdir"
putStrLn$ "Install dirs: " ++ show (absoluteInstallDirs desc linfo NoCopyDest)
You're doing the right thing, just don't look at the libsubdir or datasubdir after calling absoluteInstallDirs, because those do not make sense after making the paths absolute (they're inherently relative). The reason it's labelled as an internal error is because if cabal were ever to call those, then it would be an internal error. When you call it however, it's your fault ;-) Duncan

Victory! Thanks!
Well.. mostly victory ;-). I've got it in a state where the .cabal
file rewriting works if "cabal configure" is called separately from
"cabal build/install" so that the latter reads the modified
configuration file. Right now I'm patching the .cabal file from the
postConf flag... maybe I could fix this problem by doing the patch
from preConf instead (presumably confHook reads the file?). But
there's a bit of a chicken-and-egg problem because I use
LocalBuildInfo to find libdir and that is computed by the configure
action!
I'd be really curious if anyone else can compile this ;-). It's not
on hackage yet but you can get it with"git clone
git://github.com/rrnewton/intel-aes.git".
As for portability... I'm afraid I don't personally do any
development on Windows. Presumably the goal is for hackage packages
to work without requiring Cygwin/make/etc?
Does anyone have a GHC7 setup in windows who would be interested in
helping a bit? The C/asm code that I'm wrapping does have a .bat file
that is supposed to build it. It might be easier if yasm.exe is
included in the package (it was in the original
Intel_AESNI_Sample_Library_v1.0.zip).
Thanks,
-Ryan
On Mon, Jan 31, 2011 at 6:43 AM, Duncan Coutts
On Mon, 2011-01-31 at 01:13 -0500, Ryan Newton wrote:
Ok, I've made some progress in the direction Duncan suggested.
I can filter out the extra library before the postConf hook gets it. And calling "make" from the hooks is pretty easy.
I've got a hack working that does allow full build/link/install given a hardcoded path (e.g. hack). It works by passing -Wl,-rpath=/opt/... directly through the .cabal file (ld-options). I need to un-hardcode that directory but I can't figure out how to achieve the same effect as that ld-options from my Setup.hs (I tried adding buildProgramArgs in the buildHook but no luck yet).
Just modify the package description instead, e.g. in the configure step. The build prog args is intended for users, not for package authors.
(It's so that cabal build --$PROG-options= works, and that's not something you're supposed to interfere with. Afterall, users are in control and can always add whatever options they want by adding wrapper scripts etc, this just makes it more convenient.)
There's also the question of how to find the install dir so that rpath can be set to it. Unfortunately, I haven't been able to dig that out yet. When I try to use absoluteInstallDirs via something like below, I get this error: "setup: internal error InstallDirs.libsubdir"
putStrLn$ "Install dirs: " ++ show (absoluteInstallDirs desc linfo NoCopyDest)
You're doing the right thing, just don't look at the libsubdir or datasubdir after calling absoluteInstallDirs, because those do not make sense after making the paths absolute (they're inherently relative).
The reason it's labelled as an internal error is because if cabal were ever to call those, then it would be an internal error. When you call it however, it's your fault ;-)
Duncan

On Mon, 2011-01-31 at 09:52 -0500, Ryan Newton wrote:
Victory! Thanks!
Well.. mostly victory ;-). I've got it in a state where the .cabal file rewriting works if "cabal configure" is called separately from "cabal build/install" so that the latter reads the modified configuration file.
Yikes! Don't actually modify the .cabal file on disk. I meant just modify the data structure that gets passed around.
As for portability... I'm afraid I don't personally do any development on Windows. Presumably the goal is for hackage packages to work without requiring Cygwin/make/etc?
Right. Duncan

Oops, I guess I misinterpreted "package description". It did sound a little dangerous ;-). What you suggested also worked. I'm in good shape now. Thanks again, -Ryan On Mon, Jan 31, 2011 at 11:24 AM, Duncan Coutts < duncan.coutts@googlemail.com> wrote:
On Mon, 2011-01-31 at 09:52 -0500, Ryan Newton wrote:
Victory! Thanks!
Well.. mostly victory ;-). I've got it in a state where the .cabal file rewriting works if "cabal configure" is called separately from "cabal build/install" so that the latter reads the modified configuration file.
Yikes! Don't actually modify the .cabal file on disk. I meant just modify the data structure that gets passed around.
As for portability... I'm afraid I don't personally do any development on Windows. Presumably the goal is for hackage packages to work without requiring Cygwin/make/etc?
Right.
Duncan
participants (2)
-
Duncan Coutts
-
Ryan Newton