Skip to main content
Glama
get_compiler_settings.bxl7.19 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("flags_parser_utils.bxl", "flatten_flag_lists", "get_compiler_settings_from_flags") load("get_attrs.bxl", "get_attrs") load("utils.bxl", "basename", "dedupe_by_value", "dirname", "escape_xml", "get_argsfiles_output_path", "get_project_file_path", "h", "normcase", "normpath") def _get_additional_include_directories(target: bxl.ConfiguredTargetNode, attrs: dict) -> list: dirs = attrs["include_directories"] dirs = [target.label.package + "/" + d for d in dirs] # Headers shall not be directly added to additional include directories. dirs = ["$(RepoRoot)\\" + d for d in dirs] return dedupe_by_value(dirs) def _get_exported_additional_include_directories(target: bxl.ConfiguredTargetNode, attrs: dict, bxl_ctx) -> list: dirs = attrs["public_include_directories"] + attrs["public_system_include_directories"] dirs = [target.label.package + "/" + d for d in dirs] # TODO: handle header files with header_path_prefix for name, path in attrs["exported_headers"].items(): header_namespace = attrs["header_namespace"] if header_namespace != None: if name == path: # Assuming exported_header is a list and no customized export name specified. # e.g., # header: arvr/projects/xrtech/resources/FaceTracker/models:FaceWaveBinaryResources https://fburl.com/code/ee9ewpv7 # usage: arvr/projects/facetracking/FaceWave:OVRLipSyncCommon https://fburl.com/code/76zx2fmw name = header_namespace + "/" + basename(name) else: # e.g., # header: xplat/ocean/impl/ocean/base:base https://fburl.com/code/uiyr5ay9 # usage: xplat/ocean/impl/ocean/math:math https://fburl.com/code/ebtcvn44 name = header_namespace + "/" + name name = normcase(name) # If file path is in generated buck-out, the file will be either not available or more correct form buck-headers exists. if "buck-out" not in path and path.endswith(name): # e.g., # header: xplat/ocean/impl/ocean/base:base https://fburl.com/code/uiyr5ay9 # usage: xplat/ocean/impl/ocean/math:math https://fburl.com/code/ebtcvn44 include_dir = path.removesuffix(name) if include_dir: dirs.append(include_dir) else: # Header tree created by buck. This is the most correct form but depends on previous local build to materialize. # e.g., # header: xplat/third-party/yajl:yajl https://fburl.com/code/xqzlvuot # usage: xplat/mobileconfig/FBMobileConfigCore:FBMobileConfigCore https://fburl.com/code/p4qw1cx3 argsfiles_output_path = get_argsfiles_output_path(target, bxl_ctx) if argsfiles_output_path: dirs.append(dirname(argsfiles_output_path) + "/buck-headers") dirs = [normpath(d) for d in dirs] dirs = dedupe_by_value(dirs) dirs = ["$(RepoRoot)\\" + d for d in dirs] return dirs def _format_compiler_settings(compiler_settings: dict) -> dict: # Starlark passed in reference of dict. We don't want to accidentally override values, thus creating hard copy. concat_compiler_settings = dict(compiler_settings) concat_compiler_settings["AdditionalIncludeDirectories"] = ";".join(compiler_settings["AdditionalIncludeDirectories"] + ["%(AdditionalIncludeDirectories)"]) concat_compiler_settings["AdditionalOptions"] = " ".join(compiler_settings["AdditionalOptions"] + ["%(AdditionalOptions)"]) concat_compiler_settings["PreprocessorDefinitions"] = ";".join([escape_xml(s) for s in compiler_settings["PreprocessorDefinitions"]] + ["%(PreprocessorDefinitions)"]) concat_compiler_settings["UndefinePreprocessorDefinitions"] = ";".join(compiler_settings["UndefinePreprocessorDefinitions"] + ["%(UndefinePreprocessorDefinitions)"]) concat_compiler_settings["DisableSpecificWarnings"] = ";".join(compiler_settings["DisableSpecificWarnings"] + ["%(DisableSpecificWarnings)"]) concat_compiler_settings["ForcedIncludeFiles"] = ";".join(compiler_settings["ForcedIncludeFiles"] + ["%(ForcedIncludeFiles)"]) return concat_compiler_settings def get_compiler_settings(target: bxl.ConfiguredTargetNode, attrs: dict) -> dict: """return private compiler settings to be written to .vcxproj for given buck target""" compiler_flags = flatten_flag_lists(attrs["preprocessor_flags"] + attrs["compiler_flags"]) compiler_settings = get_compiler_settings_from_flags(compiler_flags) compiler_settings["AdditionalIncludeDirectories"].extend(_get_additional_include_directories(target, attrs)) return compiler_settings def get_exported_compiler_settings(target: bxl.ConfiguredTargetNode, attrs: dict, bxl_ctx) -> dict: """return exported compiler settings that propogate to transitive dependants""" exported_compiler_flags = flatten_flag_lists(attrs["exported_preprocessor_flags"]) exported_compiler_settings = get_compiler_settings_from_flags(exported_compiler_flags) exported_compiler_settings["AdditionalIncludeDirectories"].extend(_get_exported_additional_include_directories(target, attrs, bxl_ctx)) return exported_compiler_settings def gen_compiler_settings(compiler_settings: dict): concat_compiler_settings = _format_compiler_settings(compiler_settings) return h( "ClCompile", [ h(key, value, indent_level = 3) for key, value in concat_compiler_settings.items() ], { "Label": "CompilerSettings", }, indent_level = 2, ) def _main(bxl_ctx): target = bxl_ctx.cli_args.target target_node = bxl_ctx.configured_targets(target) actions = bxl_ctx.bxl_actions().actions attrs = get_attrs(target_node, bxl_ctx) attrs_outfile = actions.write_json(get_project_file_path(target_node.label, ".attrs.json"), attrs, pretty = True) out = actions.declare_output(get_project_file_path(target_node.label, ".compiler_settings.json")) def f(ctx, artifacts, outputs, attrs_outfile = attrs_outfile, out = out, target = target_node): attrs_input = artifacts[attrs_outfile].read_json() settings = {} settings["compiler_settings"] = get_compiler_settings(target, attrs_input) settings["exported_compiler_settings"] = get_exported_compiler_settings(target, attrs_input, ctx) ctx.bxl_actions().actions.write_json(outputs[out].as_output(), settings, pretty = True) actions.dynamic_output( dynamic = [attrs_outfile], inputs = [], outputs = [out.as_output()], f = f, ) bxl_ctx.output.print(bxl_ctx.output.ensure(out)) main = bxl_main( impl = _main, cli_args = { "log_level": cli_args.int(default = 30), "target": cli_args.target_label(), }, )

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