I'm trying to create a cabal library package named foo.
The sourcefiles I'm trying to include are: A2_5.hs, A7_1.hs, A8_1.hs, profiling.hs
I have the following in my foo.cabal file:
Name: Foo
Version: 1.0
Cabal-Version: >= 1.2
Author: Chiel92
License: GPL
License-file: LICENSE
Category: Educational Assignment
Description: Description here
Build-Type: Simple
data-files: README.md
Library
Build-Depends: base, criterion
Exposed-modules: A2_5,
A7_1,
A8_1,
profiling
However, when running cabal configure I'm getting an error:
cabal: foo.cabal:14: Parse of field 'exposed-modules' failed.
What is going wrong?
EDIT: The weird thing is: when omit the profiling part, it goes fine
Omitting "profiling" makes it work because "profiling" is not a valid module name. Module names start with upper case letters.
I found the solution: when I write Profiling starting with an uppercase, it works! So apparently the modules that are exposed have to start with an uppercase, even though their filename is lowercase.
Related
I understand that cabal will recompile a module if the interface of any of its dependencies has changed. It seems that this simple rule does not hold if the module contains Template Haskell. In that case, even just adding a trailing newline character to a file in the module's (transitive) dependencies will cause the cabal to recompile the file.
Minimal example:
file: Foo.hs
module Foo where
foo = "foo"
file: FooTH.hs
{-# LANGUAGE TemplateHaskell #-}
module FooTH where
import Data.Bifunctor.TH
import Foo
data FooPair a b = FooPair a b
$(deriveBifunctor ''FooPair)
file: MCVE.cabal
name: MCVE
version: 0.1.0.0
synopsis: MCVE
license: MIT
license-file: LICENSE
author: tarleb
maintainer: tarleb#example.com
build-type: Simple
extra-source-files: CHANGELOG.md
cabal-version: >=1.10
library
exposed-modules: Foo
, FooTH
build-depends: base >=4.8 && <4.13
, bifunctors
default-language: Haskell2010
Adding a newline to Foo.hs, e.g. by running echo "\n" >> Foo.hs, will cause recompilation of module FooTH. This ceases to happen if the TH line in FooTH is commented out.
What is the reason for this, and is there a way to avoid this unnecessary recompilation?
There's a feature in Template Haskell called addDependentFile, which adds metadata to the .hi file indicating that the source file in question depends on another file as well. To my knowledge, Cabal will always ask GHC to try to build, though it may have more intelligent logic. Stack tries to bypass that process, and has logic to parse the addDependentFile information out.
In my haskell project, I have the following directory structure (some entries are missing but not relevant to this problem)
- quanthas
- quanthas.cabal
- src/
- QuantHas/
- Settings.hs
My Settings.hs file contains this module header
module QuantHas.Settings(module QuantHas.Settings) where
My cabal file looks like this
Name: QuantHas
Version: 0.0
Description:
QuantHas project is an attempt to port QuantLib to Haskell keeping the functional flavor of Haskell.
License: BSD3
License-file: LICENSE
Build-Type: Simple
Cabal-Version: >=1.10
Library
Build-Depends: base >= 3 && < 5, array >= 0.2
Exposed-modules: QuantHas.Time.Frequency
QuantHas.Time.TimeUnit
QuantHas.Time.Period
QuantHas.Time.Date
QuantHas.Time.DayCounter
QuantHas.Time.BusinessDayConvention
QuantHas.Time.Calendar
QuantHas.Time.Calendars.UnitedKingdom
QuantHas.Time.Schedule
QuantHas.Settings
QuantHas.Require
default-language: Haskell2010
hs-source-dirs: src
-- ghc-options: -Wall
test-suite QuantHas-tests
type: exitcode-stdio-1.0
hs-source-dirs: testsuite
main-is: Tests.hs
default-language: Haskell2010
When I execute
cabal install --enable-tests
I get this message
src/Quanthas/Settings.hs:17:8: error:
File name does not match module name:
Saw: ‘QuantHas.Settings’
Expected: ‘Quanthas.Settings’
This seems wrong. However, what if we do what cabal expects. So the Settings.hs module header now is
module Quanthas.Settings(module Quanthas.Settings) where
Cabal now says
src/QuantHas/Settings.hs:17:8: error:
File name does not match module name:
Saw: ‘Quanthas.Settings’
Expected: ‘QuantHas.Settings’
And it's at this ppint that I give up and turn to SO. Can anyone help me understand what is going on?
Versions info:
Platform: Macbook Pro running MacOS 10.12.3
Haskell: 8.0.1
Cabal: 1.24.0.0
Thanks!
The issue is that there is a typo in one of the import statements in a different module. Since you're on a case-insensitive filesystem (OS X), GHC is able to find the module contents, but upon checking the module header finds it mismatches with the import statement and errors out.
Today I installed windows 8.1 and haskell on my laptop. I'm trying to build my own haskell library, but I got an error when I try to use cabal sdist. This is the error:
D:\Development\School\AFP\Assignments\Practice\Exercise\Project>cabal sdist
Distribution quality errors:
'license: NONE' is not a recognised license. The known licenses are: GPL,
GPL-2, GPL-3, LGPL, LGPL-2.1, LGPL-3, AGPL, AGPL-3, BSD2, BSD3, MIT, ISC,
MPL-2.0, Apache, Apache-2.0, PublicDomain, AllRightsReserved, OtherLicense
Distribution quality warnings:
No 'category' field.
No 'maintainer' field.
No 'synopsis' field.
A 'license-file' is not specified.
When distributing packages it is encouraged to specify source control
information in the .cabal file using one or more 'source-repository' sections.
See the Cabal user guide for details.
Note: the public hackage server would reject this package.
Warning: Cannot run preprocessors. Run 'configure' command first.
Building source dist for Project-0.1.0.0...
cabal: does not exist
Before I used the "cabal sdist" I used the following commands:
cabal init
cabal sandbox init
cabal install -j
Every command succeed, except for the cabal sdist. The cabal install only gives the following warning:
D:\Development\School\AFP\Assignments\Practice\Exercise\Project>cabal install -j
Resolving dependencies...
In order, the following will be installed:
Project-0.1.0.0 (reinstall)
Warning: Note that reinstalls are always dangerous. Continuing anyway...
Notice: installing into a sandbox located at
D:\Development\School\AFP\Assignments\Practice\Exercise\Project\.cabal-sandbox
Configuring Project-0.1.0.0...
Building Project-0.1.0.0...
Installed Project-0.1.0.0
This is my Project.cabal file:
-- Initial Project.cabal generated by cabal init. For further
-- documentation, see http://haskell.org/cabal/users-guide/
-- Initial Project.cabal generated by cabal init. For further
-- documentation, see http://haskell.org/cabal/users-guide/
name: Project
version: 0.1.0.0
-- synopsis:
description: Education
license: NONE
-- license-file:
-- author:
-- maintainer:
-- copyright:
-- category:
build-type: Simple
extra-source-files: File6, File5, File4, File3, File2
cabal-version: >=1.10
library
exposed-modules: File1
-- other-modules:
-- other-extensions:
build-depends: base >=4.8 && <4.9, QuickCheck >=2.8 && <2.9
hs-source-dirs: src
default-language: Haskell2010
I tried google, but I can't find a good solution. I use the following versions:
Cabal version: 1.22.4.0
Haskell version: 7.10.2
If you need more information, please ask.
I don't know anything about sdist, but the problem is clear: you've specified 'NONE' as the license in your cabal file, but that is not allowed for the sdist option. configure, build, and init don't care about the specific license, but sdist apparently does.
For more info, I searched google for "cabal sdist" and found this.
This [cabal sdist] has the advantage that Cabal will do a bit more checking, and ensure that the tarball has the structure that HackageDB expects.
HackageDB probably expects a valid license, hence why "NONE" is not allowed.
The problem was that cabal could not find the files in extra-source-files. I thought I didn't had to add the extension of the haskell files, but this is required.
I also had another problem. The extra-source-files wasn't using the hs-source-dirs, so I had to explicitly write "src/" infront of a file.
I am using ghc 7.6.3. I installed wxHaskell from here: https://github.com/wxHaskell/wxHaskell
It worked, the sample programs compile and the run successfully.
The only problem now is that I want to distribute a wxHaskell application on mac OS X. I tried using macosx-app and cabal-macosx (https://github.com/michaelt/cabal-macosx) to make an "app" file. It runs fine on my machine, but it fails to run on another computer. I get the following error:
Dyld Error Message: Library not loaded: /Users/user/.cabal/lib/wxc-0.90.1.0/ghc-7.6.3/libwxc.dylib.
I am using OS X 10.8.4 (Mountain Lion), but I would be also interested in compiling apps on Windows and redistribute them too.
What would be the best way to redistribute wxHaskell apps?
Setup.hs
-- Example Setup.hs for the wxHello app.
import Distribution.MacOSX
import Distribution.Simple
main :: IO ()
main = defaultMainWithHooks $ simpleUserHooks {
postBuild = appBundleBuildHook guiApps -- no-op if not MacOS X
}
guiApps :: [MacApp]
guiApps = [MacApp "WxHello"
(Just "resources/WxHello.icns")
Nothing -- Build a default Info.plist for the icon.
[] -- No other resources.
[] -- No other binaries.
ChaseWithDefaults -- Try changing to ChaseWithDefaults
]
wxHello.cabal:
Name: wxHello
Version: 0.1.0
Stability: Alpha
Synopsis: wxWidgets `Hello World' example for cabal-macosx
Description:
Example showing how to use cabal-macosx to build an application
bundle for a simple `Hello World' program using the wxWidgets GUI
toolkit.
Category: Data
License: BSD3
License-file: LICENSE
Copyright: Andy Gimblett <haskell#gimbo.org.uk>
Author: Andy Gimblett <haskell#gimbo.org.uk>
Maintainer: Andy Gimblett <haskell#gimbo.org.uk>
Build-Type: Custom
Cabal-Version: >=1.6
Executable WxHello
hs-source-dirs: src
Main-is: Main.hs
Build-Depends: base >= 3 && < 5, cabal-macosx, wx
ghc-options: -fwarn-tabs -threaded -Wall
Here are the dylib files inside the generated package:
WxHello.app $ find . | grep dylib
./Contents/Frameworks/Users/user/.cabal/lib/wxc-0.90.1.0/ghc-7.6.3/libwxc.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_baseu-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_baseu_net-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_baseu_xml-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_adv-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_aui-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_core-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_gl-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_html-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_propgrid-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_qa-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_ribbon-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_richtext-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_stc-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_webview-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_xrc-2.9.5.0.0.dylib
./Contents/Frameworks/usr/lib/libc++abi.dylib
./Contents/Frameworks/usr/lib/libexpat.1.dylib
./Contents/Frameworks/usr/lib/libiconv.2.dylib
./Contents/Frameworks/usr/lib/libstdc++.6.dylib
./Contents/Frameworks/usr/lib/libz.1.dylib
The last redistributable I made in Windows with wxHaskell needed the files
mingwm10.dll and
wxmws28u_gcc.dll
to be in the same folder as the .exe (not just somewhere on my path).
This was using a previous version of wxHaskell, which compiled against a previous version of wxWidgits itself, so presumably you'd need the wx dll to have 29 in it rather than 28.
I compiled with static linking too:
ghc -static -optl-static -optl-mwindows Main -o Project.exe
the -optl-mwindows gets rid of the command prompt window which would otherwise appear alongside your app.
It might be helpful to include your .cabal and Setup.hs files.
From the documentation on cabal-macosx, it seems that you need to ensure that your MacApp data value in Setup.hs gets the appropriate mode for ChaseDeps (use ChaseWithDefaults instead of DoNotChase) in order to build redistributable app bundles.
If you have done that but still get the same error, I would check inside the resulting app bundle to see if the necessary libraries got copied in there at all. You may find enough information to file a bug with the cabal-macosx maintainer.
Edit
Based on what you've included, the setup looks correct, and it appears to have at least copied the library dependencies in. I think the problem is probably with the cabal-macosx package.
Looking at the source code to the dependency-fixup code, it looks like it should have printed a bunch of "Updating <library>'s dependence on <path> to <path>" lines as it was building the bundle. Did you see those? Were there any lines updating the binary itself?
I am not very experienced with the OS X linking process, but I would think that unless the binary is linked after copying the libraries, it would need to be updated as well. You should be able to use /usr/bin/otool -L <filename> and /usr/bin/install_name_tool to manually fix up the paths in binaries the install process may have missed.
Here are the man pages for those two tools:
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/install_name_tool.1.html
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/otool.1.html
Given a Haskell project, is there a way to automatically calculate the entire list of dependencies? All the libraries it depends on as well as libraries that have been included but are not required.
As I said in the comments, cabal-install already does this (I'm using cabal-install 0.14.0) by guessing the packages via module lookup (like GHCi). It doesn't have any real intelligence w.r.t. versions so it just sets the version to the match major version of what you have installed.
Below you can see me making a dummy package that imports Data.Vector and cabal-install infers I am using vector 0.9.*.
[tommd#mavlo blah]$ pwd
/tmp/blah
[tommd#mavlo blah]$ cat Data/Blah.hs
module Data.Blah where
import Data.Vector
[tommd#mavlo blah]$ cabal init
Package name? [default: blah]
...SNIP...
What does the package build:
1) Library
2) Executable
Your choice? 1
Include documentation on what each field means (y/n)? [default: n]
Guessing dependencies... <--- SEE, SEE! YAY!
Generating LICENSE...
Warning: unknown license type, you must put a copy in LICENSE yourself.
Generating Setup.hs...
Generating blah.cabal...
You may want to edit the .cabal file and add a Description field.
[tommd#mavlo blah]$ cat blah.cabal
-- Initial blah.cabal generated by cabal init. For further documentation,
-- see http://haskell.org/cabal/users-guide/
name: blah
version: 0.1.0.0
synopsis: Sisponys
-- description:
-- license:
license-file: LICENSE
author: Me
maintainer: No#No.No
-- copyright:
-- category:
build-type: Simple
cabal-version: >=1.8
library
exposed-modules: Data.Blah
-- other-modules:
build-depends: base ==4.5.*, vector ==0.9.* <-- SEE?? SEE! YIPPEE!!