Reputation: 1137
In app/Main.hs, I want to open a text file, "foo.txt". I know how to open a text file in a plain Haskell program. In my cabal project,
import System.IO
Main = do
contents <- readFile "foo.txt"
print $ Main.lex contents
return contents
type Keyword = String
lex :: String -> [Keyword]
lex "" = []
lex x = words x
gives the error
openFile: does not exist (No such file or directory)
What do I need to change in my cabal file, or the file path or location to be able to open the file? I've tried putting it next to the output binary, and that doesn't work either.
This is my cabal file:
-- This file has been generated from package.yaml by hpack version 0.28.2.
--
-- see: https://github.com/sol/hpack
--
-- hash: baf2fc7e230f4b4937dfd918a13fefb55b66c7a4468b24d0e3e90cad675b26d5
name: CCompiler
version: 0.1.0.0
description: Please see the README on GitHub at <https://github.com/githubuser/CCompiler#readme>
homepage: https://github.com/githubuser/CCompiler#readme
bug-reports: https://github.com/githubuser/CCompiler/issues
author: Author name here
maintainer: [email protected]
copyright: 2018 Author name here
license: BSD3
license-file: LICENSE
build-type: Simple
cabal-version: >= 1.10
extra-source-files:
ChangeLog.md
README.md
source-repository head
type: git
location: https://github.com/githubuser/CCompiler
library
exposed-modules:
Lib
other-modules:
Paths_CCompiler
hs-source-dirs:
src
build-depends:
base >=4.7 && <5
default-language: Haskell2010
executable CCompiler-exe
main-is: Main.hs
other-modules:
Paths_CCompiler
hs-source-dirs:
app
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends:
CCompiler
, base >=4.7 && <5
default-language: Haskell2010
test-suite CCompiler-test
type: exitcode-stdio-1.0
main-is: Spec.hs
other-modules:
Paths_CCompiler
hs-source-dirs:
test
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends:
CCompiler
, base >=4.7 && <5
default-language: Haskell2010
Upvotes: 5
Views: 1058
Reputation: 4867
I understand your question to be about finding files at runtime, which you want to process and aren't packaged with your package.
Where are severals ways, how you could find files at runtime, which aren't packaged.
Either add an command line flag and call your executable with the absolute path of the file you want to process.
Or implement a file chooser dialog, with e.g. gi-gtk
.
Or hard coding relative paths which isn't advisable, as they are interpreted relative to the current working directory of your process, which can be different, depending on how the program did get started.
If you want to determine, which current working directory your program runs in, if started with cabal run
, just do a litte test project with the following cabal file:
name: test2
build-type: Simple
cabal-version: >= 1.10
version: 0.0.0.1
executable test2
hs-source-dirs: .
main-is: test2.hs
build-depends:
base
, directory
and the following test2.hs
:
module Main where
import System.Directory
main :: IO ()
main = do
cwd <- getCurrentDirectory
putStrLn cwd
Upvotes: 0
Reputation: 1137
add
data-dir: data
in the top section of the cabal file.
create the directory 'data' next to src and app, and put all files in there.
Make sure your cabal file also has this line
other-modules:
Paths_CCompiler
with your project's name instead of CCompiler.
My main function is now this
module Main where
import Lib
import System.IO
import Paths_CCompiler
main = do
filepath <- getDataFileName "return_2.c"
contents <- readFile filepath
print $ Lib.lex contents
return contents
Thanks to this blog post.
Upvotes: 7