Skip to main content
Glama
compile.bzl8.32 kB
# Copyright (c) Meta Platforms, Inc. and affiliates. # # This source code is licensed under both the MIT license found in the # LICENSE-MIT file in the root directory of this source tree and the Apache # License, Version 2.0 found in the LICENSE-APACHE file in the root directory # of this source tree. load( "@prelude//cxx:preprocessor.bzl", "cxx_inherited_preprocessor_infos", "cxx_merge_cpreprocessors", ) load( "@prelude//haskell:library_info.bzl", "HaskellLibraryInfoTSet", ) load( "@prelude//haskell:toolchain.bzl", "HaskellToolchainInfo", ) load( "@prelude//haskell:util.bzl", "attr_deps_haskell_lib_infos", "attr_deps_haskell_link_infos", "get_artifact_suffix", "is_haskell_src", "output_extensions", "srcs_to_pairs", ) load( "@prelude//linking:link_info.bzl", "LinkStyle", ) load("@prelude//utils:argfile.bzl", "at_argfile") # The type of the return value of the `_compile()` function. CompileResultInfo = record( objects = field(Artifact), hi = field(Artifact), stubs = field(Artifact), producing_indices = field(bool), ) CompileArgsInfo = record( result = field(CompileResultInfo), srcs = field(cmd_args), args_for_cmd = field(cmd_args), args_for_file = field(cmd_args), ) PackagesInfo = record( exposed_package_args = cmd_args, packagedb_args = cmd_args, transitive_deps = field(HaskellLibraryInfoTSet), ) def _package_flag(toolchain: HaskellToolchainInfo) -> str: if toolchain.support_expose_package: return "-expose-package" else: return "-package" def get_packages_info( ctx: AnalysisContext, link_style: LinkStyle, specify_pkg_version: bool, enable_profiling: bool) -> PackagesInfo: haskell_toolchain = ctx.attrs._haskell_toolchain[HaskellToolchainInfo] # Collect library dependencies. Note that these don't need to be in a # particular order. direct_deps_link_info = attr_deps_haskell_link_infos(ctx) libs = ctx.actions.tset( HaskellLibraryInfoTSet, children = [ lib.prof_info[link_style] if enable_profiling else lib.info[link_style] for lib in direct_deps_link_info ], ) # base is special and gets exposed by default package_flag = _package_flag(haskell_toolchain) exposed_package_args = cmd_args([package_flag, "base"]) packagedb_args = cmd_args() packagedb_set = {} for lib in libs.traverse(): packagedb_set[lib.db] = None hidden_args = cmd_args(hidden = [ lib.import_dirs.values(), lib.stub_dirs, # libs of dependencies might be needed at compile time if # we're using Template Haskell: lib.libs, ]) exposed_package_args.add(hidden_args) packagedb_args.add(hidden_args) # These we need to add for all the packages/dependencies, i.e. # direct and transitive (e.g. `fbcode-common-hs-util-hs-array`) packagedb_args.add([cmd_args("-package-db", x) for x in packagedb_set]) haskell_direct_deps_lib_infos = attr_deps_haskell_lib_infos( ctx, link_style, enable_profiling, ) # Expose only the packages we depend on directly for lib in haskell_direct_deps_lib_infos: pkg_name = lib.name if (specify_pkg_version): pkg_name += "-{}".format(lib.version) exposed_package_args.add(package_flag, pkg_name) return PackagesInfo( exposed_package_args = exposed_package_args, packagedb_args = packagedb_args, transitive_deps = libs, ) def compile_args( ctx: AnalysisContext, link_style: LinkStyle, enable_profiling: bool, pkgname = None, suffix: str = "") -> CompileArgsInfo: haskell_toolchain = ctx.attrs._haskell_toolchain[HaskellToolchainInfo] compile_cmd = cmd_args() 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. compile_cmd.add(ctx.attrs.compiler_flags) compile_args = cmd_args() compile_args.add("-no-link", "-i") compile_args.add("-package-env=-") if enable_profiling: compile_args.add("-prof") if link_style == LinkStyle("shared"): compile_args.add("-dynamic", "-fPIC") elif link_style == LinkStyle("static_pic"): compile_args.add("-fPIC", "-fexternal-dynamic-refs") osuf, hisuf = output_extensions(link_style, enable_profiling) compile_args.add("-osuf", osuf, "-hisuf", hisuf) if getattr(ctx.attrs, "main", None) != None: compile_args.add(["-main-is", ctx.attrs.main]) artifact_suffix = get_artifact_suffix(link_style, enable_profiling, suffix) objects = ctx.actions.declare_output( "objects-" + artifact_suffix, dir = True, ) hi = ctx.actions.declare_output("hi-" + artifact_suffix, dir = True) stubs = ctx.actions.declare_output("stubs-" + artifact_suffix, dir = True) compile_args.add( "-odir", objects.as_output(), "-hidir", hi.as_output(), "-hiedir", hi.as_output(), "-stubdir", stubs.as_output(), ) # Add -package-db and -package/-expose-package flags for each Haskell # library dependency. packages_info = get_packages_info( ctx, link_style, specify_pkg_version = False, enable_profiling = enable_profiling, ) compile_args.add(packages_info.exposed_package_args) compile_args.add(packages_info.packagedb_args) # Add args from preprocess-able inputs. inherited_pre = cxx_inherited_preprocessor_infos(ctx.attrs.deps) pre = cxx_merge_cpreprocessors(ctx, [], inherited_pre) pre_args = pre.set.project_as_args("args") compile_args.add(cmd_args(pre_args, format = "-optP={}")) if pkgname: compile_args.add(["-this-unit-id", pkgname]) arg_srcs = [] hidden_srcs = [] for (path, src) in srcs_to_pairs(ctx.attrs.srcs): # hs-boot files aren't expected to be an argument to compiler but does need # to be included in the directory of the associated src file if is_haskell_src(path): arg_srcs.append(src) else: hidden_srcs.append(src) srcs = cmd_args( arg_srcs, hidden = hidden_srcs, ) producing_indices = "-fwrite-ide-info" in ctx.attrs.compiler_flags return CompileArgsInfo( result = CompileResultInfo( objects = objects, hi = hi, stubs = stubs, producing_indices = producing_indices, ), srcs = srcs, args_for_cmd = compile_cmd, args_for_file = compile_args, ) # Compile all the context's sources. def compile( ctx: AnalysisContext, link_style: LinkStyle, enable_profiling: bool, pkgname: str | None = None) -> CompileResultInfo: haskell_toolchain = ctx.attrs._haskell_toolchain[HaskellToolchainInfo] compile_cmd = cmd_args(haskell_toolchain.compiler) args = compile_args(ctx, link_style, enable_profiling, pkgname) compile_cmd.add(args.args_for_cmd) artifact_suffix = get_artifact_suffix(link_style, enable_profiling) if args.args_for_file: if haskell_toolchain.use_argsfile: compile_cmd.add(at_argfile( actions = ctx.actions, name = artifact_suffix + ".haskell_compile_argsfile", args = [args.args_for_file, args.srcs], allow_args = True, )) else: compile_cmd.add(args.args_for_file) compile_cmd.add(args.srcs) artifact_suffix = get_artifact_suffix(link_style, enable_profiling) ctx.actions.run( compile_cmd, category = "haskell_compile_" + artifact_suffix.replace("-", "_"), # We can't use no_outputs_cleanup because GHC's recompilation checking # is based on file timestamps, and Buck doesn't maintain timestamps when # artifacts may come from RE. # TODO: enable this for GHC 9.4 which tracks file changes using hashes # not timestamps. # no_outputs_cleanup = True, ) return args.result

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server