I'm trying to set up a Haskell project with Stack. I have created a project: stack new project1 and added the suggested dependency (acme-missile) just to see how it works.
extra-deps:
- acme-missiles-0.3
But when I try to invoke launchMissile in the Main it won't work. I get
Error:(3, 1) Could not find module ‘Acme.Missiles’
Use -v to see a list of the files searched for.
|
3 | import Acme.Missiles
| ^^^^^^^^^^^^^^^^^^^^
What is the problem? What am I missing?
EDIT
When I run stack solver I get this:
Using configuration file: stack.yaml
Using cabal packages:
- ./
The following changes will be made to stack.yaml:
* Dependencies to be deleted
extra-deps:
- acme-missiles-0.3
To automatically update stack.yaml, rerun with '--update-config'
Isn't that strange? Like it thinks my dependency is not needed?
You'll need to add the dependency to project1.cabal as well:
build-depends:
base >=4.7 && <5
, project1
, acme-missiles
Alternatively, on newer versions of Stack, it looks like you should use package.yaml instead:
dependencies:
- base >= 4.7 && < 5
- acme-missiles
I can't say that I have deep knowledge of how this works, but if I understand it correctly, the main file where you're supposed to add dependencies is in the .cabal or package.yaml file. The extra-deps field in stack.yaml is where you can indicate if you have dependencies that deviate from the LTS that you currently use.
Related
I'm trying to include quickcheck-instances package for testing. Here is how my dependencies field in package.yaml looks like:
dependencies:
- blackjack
- quickcheck-instances >= 0.3.25 && < 0.4
- QuickCheck >= 2.14.2 && < 2.15
Here is how my extra-deps field in stack.yaml looks like:
extra-deps:
- quickcheck-instances-0.3.25.2#sha256:083b84b91fccb3bbf22cd906f5bc731c8e6ee96c7554e892985452f2d61d4ad3,4484
- hashable-1.3.3.0#sha256:7f3b67151162a1dfe8472dc30430af98ed5470801d3f4b6c9b8d7a7443c920d4,4068
- unordered-containers-0.2.14.0#sha256:2fe789f78246b7c7ec10d7b85c72d898a9f72fdda5b60d581e839d21016bc628,4992
- QuickCheck-2.14.2#sha256:4ce29211223d5e6620ebceba34a3ca9ccf1c10c0cf387d48aea45599222ee5aa,7736
- case-insensitive-1.2.1.0#sha256:9dfd3171fc7698cf8d931727d3af3a7b389135b583e46b5adac1f9d2026fff61,2244
- data-fix-0.3.2#sha256:ca5ee8d5e15d08e65e9af74004cd663391706c0a62b7d1c6d0023e4c34cd0038,1659
- integer-logarithms-1.0.3.1#sha256:888fb6c4fbd79ed2e8f8b94b61bccac25f7fab2b13b32b496e86828bc60b17cf,3184
- old-time-1.1.0.3#sha256:c91fbb3ee73d20ccd015842b30f1f29a304893ebe0ae3128b7bbc13d5bb0d4c8,1328
- scientific-0.3.7.0#sha256:0f188a7b92780d81a2e3cf1195a3a24cfe3e7c43d0e9e0f2101a465803d68076,4773
- splitmix-0.1.0.3#sha256:fc3aae74c467f4b608050bef53aec17904a618731df9407e655d8f3bf8c32d5c,6049
- strict-0.4.0.1#sha256:50187e750751a258efea12ef2979e16a014a953c15bf4c2fca2f1168a44a5a12,4156
- tagged-0.8.6.1#sha256:29c67d98a4404607f024750ab9c7210dadcbbef4e1944c48c52902f2071b2662,2874
- these-1.1.1.1#sha256:bdc0a3015b2e5cdf016e402937d71856ae5fe4e9e9a0d4823cc94a214c55a39b,2732
- time-compat-1.9.6.1#sha256:cddf1a7654ccc3564d2197e6bf0064254abf792c591a9fa0eaa16e6039036152,4997
- uuid-types-1.0.5#sha256:5031383749d57cb95877d7e56f0300be66652b6e57f5ba6681dcc6e4f78d046d,2541
- vector-0.12.3.0#sha256:0ae2c1ba86f0077910be242ec6802cc3d7725fe7b2bea6987201aa3737b239b5,7953
- assoc-1.0.2#sha256:a824e4f615469a27ad949dbf4907ba258bd6b459deebec00524c7bcb3f65cc9f,1205
- base-orphans-0.8.5#sha256:b01baac1b88cc80e70214c064ec8c174718c19400232588bff591f5a9c49a750,3177
- old-locale-1.0.0.7#sha256:fa998be2c7e00cd26a6e9075bea790caaf3932caa3e9497ad69bc20380dd6911,1071
- primitive-0.7.2.0#sha256:d7c3635e83ae160129cdfe2be4092ab6389199d73a2c29adf904124dbcfe6100,2660
- random-1.2.0#sha256:195506fedaa7c31c1fa2a747e9b49b4a5d1f0b09dd8f1291f23a771656faeec3,6097
- bifunctors-5.5.11#sha256:cc425ee85aae56dba1123baf6fb3fa7abcd90782f26bb904eef14c7332ee85f6,3919
- comonad-5.0.8#sha256:1f1aabd73ec7f80f20cf078a748a60cd48d8e57277802fdf6a9ab3601a9b8f7e,3631
- th-abstraction-0.4.3.0#sha256:db4b3b69398acd8a7c5c8cc8a962da55d65d05d44d5039b51bd3cb5fb3d8400f,2148
- distributive-0.6.2.1#sha256:0f99f5541cca04acf89b64432b03422b6408e830a8dff30e6c4334ef1a48680c,2996
- indexed-traversable-0.1.1#sha256:e4602357513aa3b146546227732e6e5698392f4324ab690e109cc05676ba3b4f,2491
- transformers-compat-0.6.6#sha256:510709db2b12d1510d70de824ee544ca0a9e6f27aa7e299218cbacc0750b4a5e,5560
- transformers-0.5.6.2#sha256:6c959d14430f4deffb99579ba019de07c3d852a2122b6f449344386c7d75ff1d,3172
This is the error I got:
Error: While constructing the build plan, the following exceptions were encountered:
In the dependencies for transformers-compat-0.6.6:
transformers-0.5.6.2 from stack configuration does not match >=0.3 && ==0.2.*
needed due to blackjack-0.1.0.0 -> transformers-compat-0.6.6
Some different approaches to resolving this:
* Set 'allow-newer: true' in /home/xwtek/.stack/config.yaml to ignore all version constraints and build anyway.
Plan construction failed.
Of course after setting the allow-newer into true, it works, but I don't want to mess with that setting, because I fear that something like that would make things break later. Any better solution?
Clearly, you are missing how stack works. You should read the stack user guide, but let me explain briefly. stack uses two files to work:
stack.yaml: It defines from where stack should download packages. By default Stackage. Optionally, git repos, hackage or local libraries.
package.yaml: It defines which libraries you'll be using along with how to build your executable. Dependencies, compiler flags, test, etc...
In general the only thing you need to touch from stack.yaml is the resolver, and then use package.yaml to list your dependencies. So, How does stack.yaml is used?
You should have a line like this
resolver:
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/6.yaml
This specifies the set of packages you gonna use, called: resolver or snapshot. All libraries version within an snapshot are guaranteed to build togheter with no dependency hell. In the example above the resolver is set to lts-18.6. So, If you visit stackage page for that snapshot you'll see all suported libraries and the compiler version: ghc-8.10.4
So let say I want to add QuickCheck to my dependencies. In my package.yaml I would list it down the library dependencies label
library:
dependencies:
- QuickCheck
The version of QuickCheck is determine by the selected resolver (18.6) which in this case is QuickCheck-2.14.2 as you can check in the stackage web. Of course, it is a good practise to specify the actual version in package.yaml
library:
dependencies:
- QuickCheck-2.14.2
But it is not necessary, since the resolver already sets the version from you. If you need another version of the package, then you have to add it to extra-deps, indicating stack that you want packages from lts-18.6 and a different package listed in extra-deps
The stack documentation is fairly good, so you should read it more carefully.
I am trying to use EuterpeaLite (https://github.com/Euterpea/EuterpeaLite), but it is not on Hackage.
I imported it like such import EuterpeaLite as EL and I added it to my cabal file like this:
build-depends:
base >=4.7 && <5
, postgresql-simple
, EuterpeaLite
But when I run stack build or stack ghci, I get this error:
Error: While constructing the build plan, the following exceptions were encountered:
In the dependencies for engine-0.1.0.0:
EuterpeaLite needed, but the stack configuration has no specified version (no package with that name found, perhaps there
is a typo in a package's build-depends or an omission from the stack.yaml packages list?)
needed since engine is a build target.
Some different approaches to resolving this:
Plan construction failed.
Is there a special process for non-Hackage packages?
I used the following procedure.
Create a new stack project stack new myproject --resolver=14.27. I needed to specify an older resolver, since EuterpeaLite wouldn't build with lts-15.3
In the myproject directory, add the following lines to stack.yaml:
extra-deps:
- git: https://github.com/Euterpea/EuterpeaLite.git
commit: 5fe2d129bd3087dd78c0feaf4d35fc03ffd36215
Also in the myproject directory, I added the following dependency to package.yaml:
dependencies:
- base >= 4.7 && < 5
- EuterpeaLite # <- added this line
Ran stack build in the myproject directory.
As you noted, instead of using package.yaml, you could change your .cabal file.
Say I have two projects (project-a and project-b) and I wanted to include project-a into project-b without uploading project-a to stackage. How could I publish the package locally and include it into project-b like so?
# package.yaml for project-b
dependencies:
- base >= 4.7 && < 5
- project-a == 2.0.0.0
Special thanks to #arrowd for pointing me in the right direction. This is an answer to my question but if someone else has a better one I will accept it.
In project a run the command
> stack sdist
that will package your project up into a tarball and show you what directory it is in.
Then go to project b and add the following to the stack.yaml file under the extra-deps section
extra-deps:
- archive: /path/to/project-a/tar/file
and in your package.yaml file under dependencies
dependencies:
# other dependencies
- project-a == 2.0.0.0
then run
> stack build
and project-a will be included in project-b.
I am trying to add dependency of gtk2hs-buildtool to my Haskell project but following error while building stack.
In the dependencies for TicTacToe-0.1.0.0:
gtk2hs-buildtools needed, but the stack configuration has no specified version (latest matching
version is 0.13.5.4)
needed since TicTacToe is a build target.
TicTacToe.cabal file:
library
exposed-modules:
TicTacToeEngine
other-modules:
Paths_TicTacToe
hs-source-dirs:
src
build-depends:
base >=4.7 && <5,
gtk2hs-buildtools
default-language: Haskell2010
If you are using stack tool you shouldn't touch the <packagename>.cabal file. stack is in charge to generate it from package.yaml. Despite of the fact that is a common practise to modify the <packagename>.cabal, development workflow will be easier if you don't.
The files you are interested in (and the ones that stack tool uses) are the stack.yaml and package.yaml.
In stack.yaml you should see an entry called resolver: lts-XX.XX. That means that your dependencies version are managed such that they match those in the given lts (a.k.a. snapshot). You can go to https://www.stackage.org/, click on your lts version and search for the gtk2hs-buildtools package to get the right version for your project (example: lts-12.26 uses gtk2hs-buildtools-0.13.4.0). In your package.yaml, in the dependencies section write the entry entry - gtk2hs-buildtools
From lts-13.11 and above gtk2hs-buildtools is not available in stackage, so you need to add it as an extra-dep. in the stack.yaml, in the section extra-dep add the following entry gtk2hs-buildtools-0.13.4.0 (or the version number you'd like to use). Then add in the package.yaml and entry gtk2hs-buildtools. It is necessary to add the entry in both files. Refer to stack docs o understand why.
Just to ensure you can build your project, your files should something look like the following:
if using resolver above or equal to 13.11
stack.yaml
resolver: lts-13.11
extra-deps:
- gtk2hs-buildtools-0.13.4.0
package.yaml
dependencies:
- base
- gtk2hs-buildtools
if using resolver below 13.11
stack.yaml
resolver: lts-12.26
extra-deps:
package.yaml
dependencies:
- base
- gtk2hs-buildtools
I want to use reactive-banana in my new Haskell project. I never used cabal-install or stack before. I created a directory and initialized project files in it using stack new. I see now 2 files in the directory: new-template.cabal and stack.yaml.
How do I set dependencies and make sure they are downloaded and compiled?
At first I tried to add - reactive-banana-0.8.0.2 in stack.yaml under extra-deps:, but both stack build and stack solver didn't download it. Then I augmented a part called library in new-template.cabal to this:
library
hs-source-dirs: src
exposed-modules: Lib
build-depends: base >= 4.7 && < 5
, reactive-banana >= 0.8
default-language: Haskell2010
Every time I tried to run stack build, it crashed with an error and suggestion to add some package to stack.yaml under extra-deps:, and this happened three times until finally all packages installed, and I could import them in stack ghci REPL.
So my question is, what is the idiomatic way to use stack? Which of these 2 files should I use to specify dependencies and other project metadata? What is the sample workflow of an average Haskell developer with stack?
When using stack I generally don't put any versions bounds in my .cabal file. I let the resolver and extra-deps setting in the stack.yaml file determine which versions of packages to select.
Here is a stack.yaml file which brings in reactive-banana-0.8.1.2:
flags: {}
packages:
- '.'
extra-deps:
- reactive-banana-0.8.1.2
- psqueues-0.2.0.2
resolver: lts-2.17
In my .cabal file I just have:
build-depends: base >= 4.7 && < 5, reactive-banana
The reactive-banana version is pinned by the stack.yaml file.
If you want to use GHC 7.10 change the resolver to something like nightly-2015-06-17.
I determine the extra-deps iteratively, by just running stack build and adding whatever dependencies are missing to the stack.yaml file until all dependencies are satisfied.
You will only need to do this with packages which are not in Stackage - like reactive-banana. A great many of commonly used packages are in Stackage and their versions will be determined by the resolver setting.
In the default configuration, stack works with two package databases: a centralised per-user one and a project-specific one. The centralised database only pulls packages from Stackage, a subset of Hackage with known-to-be-compatible packages, while you can put whatever you want on the project-specific database. All packages you use must be in the cabal file, but those not on Stackage (that is, the ones that will go to the project-specific database) must also be listed in the extra-deps section of stack.yaml. reactive-banana is not on Stackage, so you need to add it to stack.yaml, like this:
# etc.
extra-deps:
- reactive-banana-0.8.1.2
# etc.
stack solver can fill in the extra dependencies in stack.yaml for you.