Package versioning clashes in Cabal - haskell

Forgive me if this is a FAQ but I'm a bit puzzled about how to get around this problem properly.
I recently downloaded the package TagSoup which installed fine with the latest version 0.12.2
Then I installed the package download-curl which installed fine with the latest version. What I failed to realise was, download-curl depends on TagSoup with a version =< 0.11, so as part of the installation process Cabal downloaded an older version of TagSoup too.
This is a problem because I want to use both libraries (the latest version of TagSoup AND download-curl) - and when you do for some reason GHCI gets in a bit of a mess.
My question is, is there a way of specifying versions in your import statements, i.e.
import Text.Html.TagSoup-0.12.2
or is this a no go? I'm thinking not.
The only way I got around this was to download the download-curl source, modify the .cabal file to use TagSoup-0.12.2 and reinstalled the package with my little "hack" in place which works as I would expect it to - but I don't think this is the solution
Any help would be appreciated

Normally one specifies the required version in the .cabal file. There is an extension syntax for specific package imports (-XPackageImports) but it's usually better to let Cabal deal.
That said, yes, if you need to use both then you enter the dark realm of diamond dependencies. Yours is pretty much the only solution available currently. -XPackageImports is not a good idea here, as trying to use two versions of the same library in the same program probably won't link and almost certainly will dump core at runtime if it does manage to link without duplicate symbols.

Related

How to Version Imports for Cabal Hook

I am writing a very simple "hook" for Cabal which works fine with the last version but it stops to work when I "downgrade" Cabal to older versions 1.22, 1.20, etc.
The cause looks due to the path of some modules that keep on change, like for example: import Distribution.Simple.LocalBuildInfo
Is there any way to manage those changes across different versions? Do I need a "CPP" macro (in case which one) or there are better ways to manage it?
Usually yes, code that is dependent on a version of a library manages it via CPP macros, using macros defined by Cabal itself. See http://www.edsko.net/2014/09/13/haskell-cpp-macros/ for some examples. In your case:
#if MIN_VERSION_Cabal(1,22,0)
-- something working in Cabal 1.22 or above
#else
-- something working in Cabal versions prior to 1.22
#endif
It's not ideal, I'll give you that.

cabal repl is too slow

Currently, cabal repl is unusable for me. Typing at the prompt is erratic: a few letters appear, then it seems to hang for 5-10 seconds, only to proceed again afterwards. I suspect it's related to the fact that it loads Alex/Happy generated files (81K and 134K respectively) into the REPL. I don't really need those files for REPL support most of the time. I'm not sure if that's actually the problem, but I don't know what else to try.
I'd like to be able to exclude them from the REPL while still including them in the build process. Even better: can I only use one function from each of those files (lex/parse) somehow?
Edit: I'm seeing this behavior with GHC 7.8.3/Cabal 1.20.0.3 running on OS X 10.9 and a mid-2012 rMBP (Sandy Bridge) with 16GB of RAM. GHC/Cabal was installed via Homebrew.
Edit 2: Cabal file in question
Can you post your .cabal file?
If I understand your situation correctly, here's how I might proceed:
Verify that the alex and happy generated files are causing the slowdown.
If that is the case, consider moving them into a different package so that ghci will load the compiled versions of them.
For #1, I might try replacing the alex and happy generated files with just stubs - skeletal files which contain definitions (= undefined) for only the symbols which are imported by other modules.
I tried reorganizing the code per user5402's answer, but I wasn't able to get much of a speedup, even with code in different base packages.
Instead, I created a .ghci file in the project directory with the following contents:
:set -fobject-code
This loaded compiled versions of modules, with only the exported functions callable. For my uses, this is fine.

Haskell-mode source navigation for dependencies

I am using haskell-mode for Emacs. I succeeded at creating etags for my haskell project on every save by hasktags, however, the cabal dependencies can not be navigated to this way. So I wonder: Is there a way to make this source code navigation work for cabal dependencies, too? (as it is easily possible for java-maven projects for example..)
You can try haskdogs, which provides a thin wrapper around hasktags and executes it for your imported modules as well as your own code. It maintains a repository of module sources in ~/.haskdogs and indexes into that.
I'm using it with vi and have been quite happy with it so far.

Linking to tcl85.lib with SWIG via MSVS (autogenerated by CMake)

http://community.activestate.com/node/7011
It's kinda like that poor chap shang (can I use chap gender-neutrally?) over there in the link, except it's another year and I have MSVS 2012.
Details
CMake has placed C:...\Tcl\lib\tcl85.lib on the dependencies list for my binary (I checked in the generated .vcproj file - it's there). Nevertheless, the linker errors are numerous and of the form:
nativeTCL_wrap.obj : error LNK2019: unresolved external symbol __imp__Tcl_[some-command-name] referenced in function _SWIG_Tcl_[some-other-command-name].
So I check the header file as listed in the dependencies list for my project in MSVS: version is #define as 8.5. This matches the library that I'm trying to link to. I tried exploring tcl85.lib with dependency walker. Apparently it can't explore that kind of file. I ran dumpbin.exe on it... And the .lib file has ALL OF THE MISSING FUNCTIONS, but of the following form:
__imp_Tcl_[some-command-name]
It has all of the symbols... But there's an underscore missing in each of them!
I then explored the libtcl85.dll.a file given by ActiveState's Tcl distro used in Cygwin, and the symbols look like this:
__imp__Tcl_[some-command-name]
So it has the extra underscore, and the binary links properly on Cygwin.
...
This is seriously one of those moments where I'm throwing my hands up in the air and thinking, "What do?" in all of its simplistic grammatically screwed up glory. The same swig interface file with the same CMake generates a module successfully in Cygwin. But developing Cygwin is a pain in the ass because of how slow it is (builds are almost 5-8 times as long as in more native-Windows-ish systems).
What Happens Next?
Do I try to convince Swig to generate with dependencies with one less underscore? If so how? Do I give up and file a bug report? If so, where? Is this a bug in ActiveState Tcl? Is this a bug in Swig? Is this not a bug at all and I'm just screwed?
For the lack of an underscore the kingdom was lost?
So, as I was writing my question, I started thinking about all of the different alternatives to how this could have gone wrong. Then I remembered that CMake by default chooses the 32-bit version of MSVS. I am now feeling quite sheepish, but as someone else apparently had a similar problem on the ActiveState fora, I'm leaving my answer here for anyone else needing this little, tiny, itsy bitsy reminder...
As it turned out, selecting the 64-bit version of MSVS with cmake -G "Visual Studio 2012 Win64" fixed everything. Linking worked fine. The binary got loaded successfully into Tclsh.
I would've expected a more comprehensive error message from my build tool about trying to link 32-bit and 64-bit binaries together, though...

Compiling Libpng in Windows 7 or getting a hold of Libpng12.dll (and understanding how to link .DLL in VS)

I've been using Libpng15 in Windows 7, but I've been getting errors in relation to the
Unresolved External _png_set_longjmp_fn error when I compile my code. I followed the directions in the aforementioned link, and while it DID compile without any errors, I wound up with a message saying that I needed libpng12.dll to continue.
So, I did some Googling for libpng12.dll...nothing came up but generic "find x.dll" websites which appeared to be scams.
I've tried reading the INSTALL docs for the libpng source code on their website, and all that I see is instructions on how to do it via Unix based systems. I tried to do this in Cygwin with no luck, so I'm kind of stuck on how to compile this library.
All in all, I'm willing to do either the compilation or just using the .dll, though the problem is that I can't find a working .dll for version 12.
Another thing I tried was downloading binaries from here, which claimed to be "libpng12 for windows". I then copied the files into my VC compiler directory, which overrode libpng15, I think. Still, when I link against it statically and run my program in VC, it says that I require the .DLL file. The libpng12.dll file was in fact a .dll.a file instead. I honestly am not sure to link these (I tried linking it statically by typing "libpng12.dll.a" in the Linker Input setting through VS).
If I can go the .dll route for libpng12, how do I do this? Where is the file? How do I link it in VS?
Any help would be appreciated, as it seems there really isn't a whole lot of information on this. Either that, or I'm just not looking properly.
Look in the "projects" directory of the libpng distribution, and use one of the visual projects.
As mentioned above Look in the "projects" directory of the libpng distribution
Then make the adjustments outlined here
https://stackoverflow.com/a/38547948/293792
Which I note here for simplicities sake
(as stated there) adding two lib values to
Config -> Linker -> Input -> Additional Dependencies
these values are ucrt.lib;vcruntime.lib
Ensuring the build type is /MD
Allowed me to build these older versions, and fix that error on Windows 10 VS2015.
This link seems to have an installer for 1.2 for you:
http://gnuwin32.sourceforge.net/packages/libpng.htm
it's 32 bit. Not sure if that makes a difference for you.

Resources