From 88da0582de0e82541675c88be0abce585363b230 Mon Sep 17 00:00:00 2001 From: Jakob Degen Date: Tue, 4 Feb 2025 19:20:46 -0800 Subject: [PATCH] modefilefree: RFC: Get C flags from toolchain Summary: Alrighty, so I'm starting with what may be the most ambitious proposal. Haskell compilation requires passing approximately all of the C compiler flags to ghc, prefixed with `-optl`, `-optc`, or `-opta`. That was previously implemented in gen_modes.py by just using the compiler flags there. This diff proposes to instead depend on the CXX toolchain directly from the haskell toolchain and get access to the flags that way. The first problem with this is that the flags we need are just exposed in the cxx toolchain as a `cmd_args`, but that doesn't provide a convenient way to filter out the subset of the flags that we want to remove, so we have to do some `dynamic_outputs` shenanigans. Not super correct, but not the biggest problem either. The bigger issue though is that I don't actually know what the right plan for handling this is. Specifically, it's obvious that "just pass all of the C flags to ghc" is not correct (especially since this is using gcc even on clang toolchains if I'm reading things right). But I don't know how I'm supposed to distinguish either. This is particularly concerning since we expect to move more things to the toolchain in the future - what happens if sanitizer flags start showing up here? How do we make sure that people changing cxx toolchain flags in the future don't have to start learning about ghc oddities? So if there's a better suggestion for how to do this than "assume everything from the C++ toolchain works and then filter a couple things out," I'm all ears. This is just the first proposal. Reviewed By: scottcao Differential Revision: D68888352 fbshipit-source-id: 1a2aa8442f341078436745f882d8250fa514b2e5 --- prelude/haskell/compile.bzl | 8 ++++++-- prelude/haskell/haskell_haddock.bzl | 1 + prelude/haskell/toolchain.bzl | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/prelude/haskell/compile.bzl b/prelude/haskell/compile.bzl index f37bca128b7ae..080c51cb09f81 100644 --- a/prelude/haskell/compile.bzl +++ b/prelude/haskell/compile.bzl @@ -128,11 +128,15 @@ def compile_args( link_style: LinkStyle, enable_profiling: bool, pkgname = None, - suffix: str = "") -> CompileArgsInfo: + suffix: str = "", + for_haddock: bool = False) -> CompileArgsInfo: haskell_toolchain = ctx.attrs._haskell_toolchain[HaskellToolchainInfo] compile_cmd = cmd_args() - compile_cmd.add(haskell_toolchain.compiler_flags) + if for_haddock and haskell_toolchain.compiler_flags_for_haddock != None: + compile_cmd.add(haskell_toolchain.compiler_flags_for_haddock) + else: + compile_cmd.add(haskell_toolchain.compiler_flags) # Some rules pass in RTS (e.g. `+RTS ... -RTS`) options for GHC, which can't # be parsed when inside an argsfile. diff --git a/prelude/haskell/haskell_haddock.bzl b/prelude/haskell/haskell_haddock.bzl index 4154e3aba4f83..92ec996b7fe35 100644 --- a/prelude/haskell/haskell_haddock.bzl +++ b/prelude/haskell/haskell_haddock.bzl @@ -37,6 +37,7 @@ def haskell_haddock_lib(ctx: AnalysisContext, pkgname: str) -> Provider: enable_profiling = False, suffix = "-haddock", pkgname = pkgname, + for_haddock = True, ) cmd = cmd_args(haskell_toolchain.haddock) diff --git a/prelude/haskell/toolchain.bzl b/prelude/haskell/toolchain.bzl index 1b7bed5139763..fc36d6d7b6db1 100644 --- a/prelude/haskell/toolchain.bzl +++ b/prelude/haskell/toolchain.bzl @@ -17,6 +17,7 @@ HaskellToolchainInfo = provider( "linker": provider_field(typing.Any, default = None), "linker_flags": provider_field(typing.Any, default = None), "haddock": provider_field(typing.Any, default = None), + "compiler_flags_for_haddock": provider_field(cmd_args | None, default = None), "compiler_major_version": provider_field(typing.Any, default = None), "package_name_prefix": provider_field(typing.Any, default = None), "packager": provider_field(typing.Any, default = None),