flycheck / flycheck-haskell

Improved Haskell support for Flycheck
GNU General Public License v3.0
67 stars 25 forks source link

cabal_macros.h: No such file or directory #73

Closed mrkkrp closed 7 years ago

mrkkrp commented 7 years ago

Sometimes I see:

Suspicious state from syntax checker haskell-stack-ghc: Flycheck checker haskell-stack-ghc returned non-zero exit code 1, but its output contained no errors: cc1: fatal error: cabal_macros.h: No such file or directory
compilation terminated.
`gcc' failed in phase `C pre-processor'. (Exit code: 1)

Try installing a more recent version of haskell-stack-ghc, and please open a bug report if the issue persists in the latest release.  Thanks!

It looks like cabal_macros.h is not generated where Flycheck expects it to be. Any idea how to fix this?

sergv commented 7 years ago

@mrkkrp Can please you post output of stack --version and provide a reproducible example?

mrkkrp commented 7 years ago

Stack version:

Version 1.4.0, Git revision e714f1dd3fade19496d91bd6a017e435a96a6bcd (4640 commits) x86_64 hpack-0.17.0

I'll add an example a bit later (today or tomorrow).

mrkkrp commented 7 years ago

To reproduce:

  1. Clone for example https://github.com/stackbuilders/cassava-megaparsec.git.
  2. Go to the directory you have just created by clonning and run stack test so dependencies get installed, etc.
  3. emacs -Q
  4. Evaluate (package-initialize).
  5. Evaluate (require 'flycheck).
  6. Evaluate (require 'flycheck-haskell).
  7. Evaluate (add-hook 'flycheck-mode-hook #'flycheck-haskell-setup).
  8. Go to the directory where you've cloned the package.
  9. Open Data.Csv.Parser.Megaparsec.hs.
  10. Run flycheck-compile.

Now with emacs -Q this does not reproduce the issue I have with my setup. I don't understand why. Here is a printout I get with my setup:

stack ghc -- -Wall -no-link -outputdir /tmp/flycheck-haskell-ghc-cache7515eYD -XHaskell2010 -i/home/mark/projects/programs/haskell/cassava-megaparsec/dist/build -i/home/mark/projects/programs/haskell/cassava-megaparsec/dist/build/autogen -i/home/mark/projects/programs/haskell/cassava-megaparsec/.stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build -i/home/mark/projects/programs/haskell/cassava-megaparsec/.stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/autogen -i/home/mark/projects/programs/haskell/cassava-megaparsec/ -i/home/mark/projects/programs/haskell/cassava-megaparsec/tests -i/home/mark/projects/programs/haskell/cassava-megaparsec/ -Wall -I/home/mark/projects/programs/haskell/cassava-megaparsec/dist/build/autogen -I/home/mark/projects/programs/haskell/cassava-megaparsec/.stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/autogen -optP-include -optPcabal_macros.h -hide-all-packages -package base -package bytestring -package cassava -package containers -package hspec -package hspec-megaparsec -package megaparsec -package unordered-containers -package vector -x hs /home/mark/projects/programs/haskell/cassava-megaparsec/Data/Csv/Parser/Megaparsec.hs
cc1: fatal error: cabal_macros.h: No such file or directory
compilation terminated.
`gcc' failed in phase `C pre-processor'. (Exit code: 1)

And here is what I get with vanilla Emacs:

stack ghc -- -Wall -no-link -outputdir /tmp/flycheck-haskell-ghc-cache7687ibD -i/home/mark/projects/new-tests/cassava-megaparsec/ -x hs /home/mark/projects/new-tests/cassava-megaparsec/Data/Csv/Parser/Megaparsec.hs

The first one fails, the second one succeeds. Apparently the first time (with my setup) stack ghc is passed a lot more arguments, but I'm not sure why. Do you have any idea?


Update. Now following the instructions above I get:

stack ghc -- -Wall -no-link -outputdir /tmp/flycheck-haskell-ghc-cache12983CXE -XHaskell2010 -i/home/mark/projects/new-tests/cassava-megaparsec/dist/build -i/home/mark/projects/new-tests/cassava-megaparsec/dist/build/autogen -i/home/mark/projects/new-tests/cassava-megaparsec/.stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build -i/home/mark/projects/new-tests/cassava-megaparsec/.stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/autogen -i/home/mark/projects/new-tests/cassava-megaparsec/ -i/home/mark/projects/new-tests/cassava-megaparsec/tests -i/home/mark/projects/new-tests/cassava-megaparsec/ -Wall -I/home/mark/projects/new-tests/cassava-megaparsec/dist/build/autogen -I/home/mark/projects/new-tests/cassava-megaparsec/.stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/autogen -optP-include -optPcabal_macros.h -hide-all-packages -package base -package bytestring -package cassava -package containers -package hspec -package hspec-megaparsec -package megaparsec -package unordered-containers -package vector -x hs /home/mark/projects/new-tests/cassava-megaparsec/Data/Csv/Parser/Megaparsec.hs
cc1: fatal error: cabal_macros.h: No such file or directory
compilation terminated.
`gcc' failed in phase `C pre-processor'. (Exit code: 1)

Which seems to reproduce the issue.

sergv commented 7 years ago

Well, at least I have an idea why stack ghc gets more arguments in your setup. Per flycheck-haskells README, you should have added something like (eval-after-load 'flycheck '(add-hook 'flycheck-mode-hook #'flycheck-haskell-setup)) to your .emacs (or its equivalent). The flycheck-haskell-setup function is the one responsible for getting additional options out of .cabal file and passing them to the flycheck checker.

mrkkrp commented 7 years ago

I have updated the previous comment.

sergv commented 7 years ago

The cabal_macros.h file is generated by either cabal or stack during build. So it's absent until you build your project for the first time. After running stack build it should be where flycheck-haskell expects it to be, namely cassava-megaparsec/.stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/autogen. Is that the case for you? On a related note, is it a deal breaker, in your opinion, for flycheck-haskell to not be able to work from "clean slate" and require user to start build using cabal or stack before actual checking can start happening?

mrkkrp commented 7 years ago

That's not a deal-breaker, I always run stack build or stack test before I start working anyway (note the point number 2 in the original instructions). But the problem is that even after that I'm getting the error message that cabal_macros.h isn't there! For some projects Flycheck works, but for others I can't get rid of the error. This is really frustrating. I certainly don't mind running stack build once before I start coding. Can you reproduce this?

sergv commented 7 years ago

I cannot clearly reproduce the issue following your instructions. I.e. after starting emacs -Q and evaluating package-initialize I get a failure on (require 'flycheck) - (file-error "Cannot open load file" "No such file or directory" "flycheck"), which probably means that I need to install a bunch of packages after package-initialize.

After some tweaking I got it to work, e.g. in emacs -Q --no-init-file I evaluate

(progn
  (add-to-list 'load-path "<my-root>/dash.el")
  (add-to-list 'load-path "<my-root>/flycheck")
  (add-to-list 'load-path "<my-root>/flycheck-haskell")
  (add-to-list 'load-path "<my-root>/haskell-mode")
  (load-library "<my-root>/haskell-mode/haskell-mode.el")
  (require 'flycheck)
  (require 'flycheck-haskell)
  (add-hook 'flycheck-mode-hook #'flycheck-haskell-setup)
  (flycheck-haskell-setup)
  (find-file "/tmp/cassava-megaparsec-fresh/Data/Csv/Parser/Megaparsec.hs"))

and when I use M-x flycheck-compile with haskell-stack-ghc checker I get successful check if cabal_macros.h is in place (which is the case for me after executing stack build).

It seems that as if running stack build for you doesn't generate cabal_macros.h under .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/autogen directory. Can you please validate that that's the case with your setup? E.g. could you post output of stack clean; stack build; find .stack-work -name cabal_macros.h?

mrkkrp commented 7 years ago

Heh, I think what's going on. The path has x86_64-linux but stack generates x86_64-linux-nopie subdirectory on my system for some reason.

mrkkrp commented 7 years ago

nopie is what Stack calls "GHC build". It's autodetected. I guess Flycheck should be able to detect it correctly as well. I don't use GHC that comes from the repositories of my distro, I do everything via Stack (i.e. stack setup).

mrkkrp commented 7 years ago

@sergv, ping. Any update on this? I'd prepare a PR, but l'm not sure what to change.

sergv commented 7 years ago

@mrkkrp Yes, I was thinking about fixing this, but now I'm paralyzed with indecision. You see, what if both x86_64_linux and x86_64-linux-nopie directories are present? I.e. user installed a ghc via stack and another one from the system (e.g. two ghcs of different versions). Which one to choose in this case?

Also, how frequently should emacs test for existence of -nopie directory? What if user switches ghc after opening source file? I would be interested to hear your opinion on these issues.

mrkkrp commented 7 years ago

I think the correct behavior it to get from Stack what it thinks is the correct path right now and use that. If it's not possible, I'd favor behavior when GHC installed by Stack takes precedence.


Also, how frequently should emacs test for existence of -nopie directory?

I'm not familiar with the codebase enough to say anything about this.

sergv commented 7 years ago

Just an update: I didn't forget about this issue and will try to fix it to give priority to the -pie variant in the near future, but probably not this week.

sergv commented 7 years ago

@mrkkrp The issue should be fixed now, please give it a try!

mrkkrp commented 7 years ago

Thanks! Everything seems to work now.