Generate HDL from a file not part of a cabal library

I am working on some library, I have an example that can run in simulation but should also be able to translate to HDL. My cabal setup is

project/
  app/
    Example.hs
    HdlTest.hs
  src/
    ...

In the project.cabal file there is a library definition with the modules in src/ and there are two executables for Example.hs and HdlTest.hs in app/.

The HdlTest.hs looks like this

import Prelude

import qualified Clash.Main as Clash

main :: IO ()
main = Clash.defaultMain ["SomeModuleInSrc", "-main-is", "topLevel", "--verilog"]

If it’s pointed at some module in the library (in src) then it works fine! If I try to point it at project/app/Example.hs I’m getting compile errors.
The error is about a GHC language extension not being enabled (that is enabled for the executable definition in the cabal file though)

Is there a convenient way to run Clash on a file that belongs to an executable target while keeping the GHC options?

Unfortunately, there is currently no way to do that.

Usually we sidestep this by putting all the definitions Clash needs to compile in the library.

Like Martijn said to take advantage of the extenstions and other GHC options defined in the cabal file your module needs to be in a library.
But if you like you can hide your module in an internal library.

Starting with the simple starter project.
In addition to that I’ve got:

  • app/HdlTest.hs (your HdlTest.hs, but with SomeModuleInApp instead of SomeModuleInSrc)
  • app/SomeModuleInApp.hs (the module to be translated to Verilog)
  • these changes to the cabal file:
--- a/simple.cabal
+++ b/simple.cabal
@@ -88,6 +88,18 @@ library
     Example.Project
   default-language: Haskell2010
 
+library simple-internal
+  import: common-options
+  hs-source-dirs: app
+  exposed-modules:
+    SomeModuleInApp
+  default-language: Haskell2010
+
+executable HdlTest
+  main-is: app/HdlTest.hs
+  default-language: Haskell2010
+  Build-Depends: base, clash-ghc, simple, simple-internal
+

Thanks to the dependency on simple-internal, HdlTest can now access the precompiled SomeModuleInApp.

Alternatively you can just pass all needed options manually to clash inside of your HdlTest.hs file.
The relevant language extensions are available programmatically in Clash.Util.wantedLanguageExtensions and unwantedLanguageExtensions.