rules_haskell icon indicating copy to clipboard operation
rules_haskell copied to clipboard

Support includes in hsc files

Open googleson78 opened this issue 2 years ago • 3 comments

Is your feature request related to a problem? Please describe. Very often when people have .hsc files they will also have some headers which they're including. We currently don't seem to have support for #include, as we don't do any work in the hsc invocations to make sure files that are being included are actually there during a build.

Describe the solution you'd like Some way to have headers available for hsc to process. My current idea (which I've implemented) is to allow users to specify headers in extra_srcs, and then try to mirror the directory structure that's in the project in our build environment.

Describe alternatives you've considered I'm not sure if reusing extra_srcs is a good idea - it does the job, but if someone is using extra_srcs already.

I'm also not sure about the "mirror the directory structure", as it seems a bit fragile (e.g. it doesn't work if someone includes a file from outside the project structure). We could use hsc2hs's ability to include files via the CLI, however that would require either

  • we tell the user to adapt their project and manually remove #includes
  • we manipulate source files to remove the #includes from there both of which are rather unsatisfying. (and way more involved than the current solution that I'm proposing).

googleson78 avatar Apr 18 '22 13:04 googleson78

Upon some further thought - I'm not sure if supporting this is even desirable. Usually you'd prefer to let bazel manage the dependencies instead of introducing implicit such dependencies via #includes in files. There already seems to be a way to do that by adding a cc_library exposing the headers as a dependency.

So this feature would then only be useful if you're

  • converting a project that uses #includes and you don't want to "clean them up" immediately
  • you want to only add bazel as an option for building, and not necessarily replace what already exists.

googleson78 avatar Apr 19 '22 10:04 googleson78

I think I agree.

If we want to add Bazel as an option for building without changing the #includes (I was told that in general this brings more problems than it solves), it is maybe better to find a solution which also uses the explicit cc_library targets.

I tried a bit to do this without modifying rules_haskell but did not find a perfect solution (though it may be enough in some cases).

I managed to make the example from PR #1729 build without changing the includes of the hsc files, with the following cc_library rule by using the includes attribute.

cc_library(
    name = "point_headers",
    hdrs = [
        "WithHeader/point.h",
        "headers/point.h",
    ],
    includes = ["WithHeader"],
)

It has some disadvantages:

  • as mentioned in the cc_library, the include flags may be propagated to targets which do not need it.
  • The includes attribute here points to the file which contains the #include directive. So we may need multiple of these rules.

If one does not exist already, maybe we could add a way to manually pass the same flags that are generated by the includes attribute to the target that does the #include.

ylecornec avatar Apr 22 '22 10:04 ylecornec

I think the solution to add something like an include_dirs attribute to haskell_{library,binary,test} sounds better to me - it's very implicit otherwise, using the includes header of cc_library. It would also be great if we could directly link this include_dirs to the cc_library target somehow.

googleson78 avatar Apr 27 '22 09:04 googleson78