Skip to content

Commit 9b28e9d

Browse files
committed
Add support for unit-based hie-bios script for ghc 9.4+
Starting with GHC 9.4, GHC, and therefore HLS indirectly, will segregate the command line flags for different compilation units if the flags for that unit are placed in a file and passed as -unit @unitfile. GHC will accept multiple unitfiles on the command line and keep the arguments separate. As an example of something this fixes, currently if you have to haskell_library targets, A and B, and A depends on B and B imports external library C, the current hie-bios script makes modules from C visible for import into A, which will fail to compile unless A also explicitly depends on C. A -> B -> C, but not A -> C (directly) Add a multi flag to a repl. This currently doesn't affect the base repl target, it only affects the hie-bios target that also gets generated. This change would be a good basis for starting a repl with multiple unit files as arguments. For a multi-repl, we carefully segregate out what should be transitive, and what should not be transitive. For example, package databases should be transitive, but package ids should not be. In order to correctly build the unit files for each unit, we collect the haskell dependency graph as a part of _create_HaskellReplCollectInfo. Then we can use this dependency graph to build up HaskellReplDepInfo and HaskellReplLoadInfo for haskell targets from the HaskellReplLoadInfo and HaskellReplDepInfo from the corresponding structs of their direct dependencies. Because we are going to use some of these intermediate products to produce the corresponding unit files, it is important that we have more control as we build these up. To build the unit files, we walk the haskell dependency graph in post order. We build the load_info and dep_info as above, and if we determine that this is a source-loaded dependency, then we pair the load_info and dep_info into a HaskellReplInfo. Each HaskellReplInfo corresponds to a unit file. The actual script just outputs "-hide-all-packages" and "-unit @unitfile" for each of the unit files generated in this way. Where possible, the filenames and include paths are output relative to the workspace root. This is done because the editor, and hls, are expected to be running in the workspace root, and not in the execution root. Anything that is a generated file, or a directory (e.g. an import directory) for generated files must be prefixed with the execution root. The execution root is unavailable while creating an output. Bazel does this so that particularities of a given machine don't leak out into the outputs. In order to write unit files that contain the execution root, the unit files can't be direct outputs of bazel rules. Instead, they are outputs of a shell script, which is itself a rule output. For each of the unit files, we produce a shell script fragment that is included by the hie-bios shell script and writes to the corresponding unit file.
1 parent 7d88e4f commit 9b28e9d

File tree

2 files changed

+339
-20
lines changed

2 files changed

+339
-20
lines changed

haskell/private/hie_bios_wrapper.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,10 @@ SCRIPT_ABS="$(rlocation %{OUTPUT_RLOCATION_PATH})"
1818
RULES_HASKELL_EXEC_ROOT=${SCRIPT_ABS%/"$SCRIPT_REL"}
1919
ARGS="%{ARGS}"
2020
echo "$ARGS"
21+
UNIT_FILE_FRAGMENTS="%{UNIT_FILE_FRAGMENTS}"
22+
for FRAGMENT in $UNIT_FILE_FRAGMENTS; do
23+
UNIT_FILE=${FRAGMENT%.sh}
24+
. "$FRAGMENT" >"$UNIT_FILE"
25+
echo "-unit"
26+
echo "@${UNIT_FILE}"
27+
done

0 commit comments

Comments
 (0)