Skip to main content
Glama
flags_parser_utils.bxl6.62 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("ppflags.bxl", "COMPILER_FLAGS_MAP", "COMPILER_IGNORE_OPTIONS", "LANGUAGE_STANDARD_MAP", "LINKER_FLAGS_MAP") load("utils.bxl", "dedupe_by_value") def flatten_flag_lists(flag_lists): # Flags are in form of list of list like [["/WX"],["/W4"],["/w15038"]] in attrs and list of strings in mode config flatten_list = [] for flag in flag_lists: if isinstance(flag, list): flatten_list.extend(flag) elif isinstance(flag, str): flatten_list.append(flag) return flatten_list def unquote_flag(flag): if flag.startswith('"') and flag.endswith('"'): return flag[1:-1] elif flag.startswith('\\"') and flag.endswith('\\"'): return flag[2:-2] return flag def parse_include_dirs_from_flags(flags): include_dirs = [] filtered_flags = [] skip_next = False for i in range(len(flags)): if skip_next: skip_next = False continue include_path = None flag = unquote_flag(flags[i]) if flag in ["/I", "-I", "/isystem", "-isystem"]: include_path = unquote_flag(flags[i + 1]) skip_next = True elif flag.startswith("/I") or flag.startswith("-I"): include_path = flag[2:] elif flag.startswith("/isystem") or flag.startswith("-isystem"): include_path = flag[len("-isystem"):] if include_path: include_dirs.append("$(RepoRoot)\\" + include_path) else: filtered_flags.append(flag) return include_dirs, filtered_flags def parse_defines_from_flags(flags): defines = [] undefines = [] filtered_flags = [] skip_next = False for i in range(len(flags)): if skip_next: skip_next = False continue define = None undefine = None flag = unquote_flag(flags[i]) if flag == "/D" or flag == "-D": define = unquote_flag(flags[i + 1]) skip_next = True elif flag.startswith("/D") or flag.startswith("-D"): define = flag[2:] splits = define.split("=") if len(splits) == 2: define = splits[0] + "=" + unquote_flag(splits[1]) elif flag == "/U" or flag == "-U": undefine = unquote_flag(flags[i + 1]) skip_next = True elif flag.startswith("/U") or flag.startswith("-U"): undefine = flag[2:] splits = undefine.split("=") if len(splits) == 2: undefine = splits[0] + "=" + unquote_flag(splits[1]) if define: defines.append(define) elif undefine: undefines.append(undefine) else: filtered_flags.append(flag) return dedupe_by_value(defines), dedupe_by_value(undefines), filtered_flags def get_linker_settings_from_flags(flags, buck_root): linker_settings = {} additional_library_directories = [] additional_dependencies = [] additional_options = [] no_default_libs = [] for flag in flags: original_flag = flag # Unify leading character to "/" for easier matching if flag.startswith("-"): flag = "/" + flag[1:] if not flag.startswith("/"): additional_dependencies.append(flag) elif flag.startswith("/LIBPATH:"): additional_library_directories.append(flag[len("/LIBPATH:"):]) elif flag.startswith("/NODEFAULTLIB:"): no_default_libs.append(flag[len("/NODEFAULTLIB:"):]) elif flag in LINKER_FLAGS_MAP: linker_settings.update(LINKER_FLAGS_MAP[flag]) elif flag.startswith("/TLBID:"): linker_settings["TypeLibraryResourceID"] = flag[len("/TLBID:"):] elif flag.startswith("/PDBALTPATH"): pass elif flag.startswith("/PDBSOURCEPATH"): # Overwrite the /PDBSOURCEPATH to the buck root instead of using the default additional_options.append("/PDBSOURCEPATH:" + buck_root) elif flag.startswith("/INCLUDE:"): if "ForceSymbolReferences" not in linker_settings: linker_settings["ForceSymbolReferences"] = [] linker_settings["ForceSymbolReferences"].append( flag[len("/INCLUDE:"):], ) else: additional_options.append(original_flag) linker_settings["AdditionalLibraryDirectories"] = dedupe_by_value( additional_library_directories, ) linker_settings["AdditionalDependencies"] = dedupe_by_value(additional_dependencies) linker_settings["AdditionalOptions"] = dedupe_by_value(additional_options) linker_settings["IgnoreDefaultLibraryNames"] = dedupe_by_value(no_default_libs) return linker_settings def get_compiler_settings_from_flags(flags): compiler_settings = {} disable_specific_warnings = [] forced_include_files = [] additional_options = [] include_directories, flags = parse_include_dirs_from_flags(flags) defines, undefines, flags = parse_defines_from_flags(flags) for flag in flags: original_flag = flag # Unify leading character to "/" for easier matching if flag.startswith("-"): flag = "/" + flag[1:] if flag in COMPILER_FLAGS_MAP: compiler_settings.update(COMPILER_FLAGS_MAP[flag]) elif flag in LANGUAGE_STANDARD_MAP: compiler_settings["LanguageStandard"] = LANGUAGE_STANDARD_MAP[flag] elif flag in COMPILER_IGNORE_OPTIONS: pass elif flag.startswith("/FI"): forced_include_files.append(flag[3:]) elif flag.startswith("/wd"): disable_specific_warnings.append(flag[3:]) elif flag.startswith("/W"): pass # Incompatible gcc style warnings else: additional_options.append(original_flag) compiler_settings["AdditionalIncludeDirectories"] = include_directories compiler_settings["AdditionalOptions"] = additional_options compiler_settings["PreprocessorDefinitions"] = defines compiler_settings["UndefinePreprocessorDefinitions"] = undefines compiler_settings["DisableSpecificWarnings"] = disable_specific_warnings compiler_settings["ForcedIncludeFiles"] = forced_include_files return compiler_settings

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