Skip to main content
Glama
gen_vcxproj.bxl7.28 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("constants.bxl", "BY_MODES") load("gen_user_macros.bxl", "gen_user_macros") load("get_attrs.bxl", "get_attrs") load("get_compiler_settings.bxl", "gen_compiler_settings") load("get_linker_settings.bxl", "gen_linker_settings") load("get_vs_settings.bxl", "get_vs_settings") load("utils.bxl", "get_mode_config_path", "get_project_file_path", "get_root_path_relative_to", "get_vs_configuration", "h", "log_debug") def _gen_project_configurations(project_configurations): return h("ItemGroup", [ h( "ProjectConfiguration", [ h("Configuration", config["Configuration"], indent_level = 3), h("Platform", config["Platform"], indent_level = 3), ], { "Include": config["Configuration"] + "|" + config["Platform"], }, indent_level = 2, ) for config in project_configurations ], { "Label": "ProjectConfigurations", }, indent_level = 1) def _gen_configuration_type(project_configurations): return h( "PropertyGroup", [ h("ConfigurationType", project_configurations[0]["ConfigurationType"], indent_level = 2), ], indent_level = 1, ) def _gen_headers(headers): return h("ItemGroup", [ h("ClInclude", None, { "Include": cmd_args("$(RepoRoot)\\", header, delimiter = ""), }, indent_level = 2) for header in headers ], indent_level = 1) def _gen_sources(sources): source_entries = [ h("ClCompile", [h("BuckObjSubTarget", object, indent_level = 3)], { "Include": cmd_args("$(RepoRoot)\\", source, delimiter = ""), }, indent_level = 2) for source, object in sources.items() ] return h("ItemGroup", source_entries, indent_level = 1) def _gen_import_mode_configs(vs_settings: dict, target): imports = [] for (mode_file, _) in vs_settings[BY_MODES].items(): import_config = ' <Import Condition="\'$(Configuration)\'==\'{}\'" Project="{}mode_configs\\{}" />\n'.format( get_vs_configuration(mode_file), get_root_path_relative_to(target.label), get_mode_config_path(mode_file), ) imports.append(import_config) return h("ImportGroup", imports, { "Label": "PropertySheets", }, indent_level = 1) def gen_vcxproj(target: bxl.ConfiguredTargetNode, vs_settings: dict, cli_args, buck_root): log_debug("# Generating vcxproj for {}", target.label.raw_target(), log_level = cli_args.log_level) project_configurations = _gen_project_configurations(vs_settings["ProjectConfigurations"]) configuration_type = _gen_configuration_type(vs_settings["ProjectConfigurations"]) user_macros = gen_user_macros(target, vs_settings, cli_args, buck_root) headers = _gen_headers(vs_settings["Headers"]) sources = _gen_sources(vs_settings["Sources"]) compiler_settings = gen_compiler_settings(vs_settings["CompilerSettings"]) linker_settings = gen_linker_settings(vs_settings["LinkerSettings"]) import_mode_configs = _gen_import_mode_configs(vs_settings, target) # Why are we using cmd_args instead of strings? Because bxl resolved_attrs does not support string manipulation (as of July 2024) # See https://fb.workplace.com/groups/buck2users/permalink/3703593843230303/ for more context vcxproj_content = cmd_args( """<?xml version="1.0" encoding="utf-8"?>""", """<Project DefaultTargets="Build" ToolsVersion="17.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">""", project_configurations, "", h( "PropertyGroup", [ h(key, value, indent_level = 2) for (key, value) in vs_settings["Globals"].items() ], { "Label": "Globals", }, indent_level = 1, ), "", configuration_type, "", """ <ImportGroup Label="ExtensionSettings" />""", "", user_macros, "", import_mode_configs, # mode configs must be imported early but after user_macros so that it can be overwrite "", """ <ItemDefinitionGroup>""", compiler_settings, linker_settings, """ </ItemDefinitionGroup>""", "", headers, "", sources, "", h( "Target", [ h( "Exec", None, { "Command": "$(vs_buck_build_command)[objects][%(ClCompile.BuckObjSubTarget)] $(ExtraBuckOptions)", "WorkingDirectory": "$(RepoRoot)", }, indent_level = 2, ), ], { "Condition": "\'@(ClCompile)\' != \'\'", "DependsOnTargets": "SelectClCompile", "Name": "ClCompile", }, indent_level = 1, ), """ <ImportGroup Label="ExtensionTargets" /> </Project>""", delimiter = "\n", ) return vcxproj_content def _main(bxl_ctx): target_label = bxl_ctx.cli_args.target target_node = bxl_ctx.configured_targets(target_label) 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, ".json"), attrs) vcxproj_artifact = actions.declare_output(get_project_file_path(target_node.label, ".vcxproj")) def f(ctx, artifacts, outputs, attrs_outfile = attrs_outfile, vcxproj_artifact = vcxproj_artifact, target = target_node, cli_args = bxl_ctx.cli_args, buck_root = bxl_ctx.root()): attrs_input = artifacts[attrs_outfile].read_json() vs_settings = get_vs_settings(target, attrs_input, {}, cli_args, buck_root, ctx) vcxproj_content = gen_vcxproj(target, vs_settings, cli_args, buck_root) ctx.bxl_actions().actions.write(outputs[vcxproj_artifact].as_output(), vcxproj_content, allow_args = True) actions.dynamic_output( dynamic = [attrs_outfile], inputs = [], outputs = [ vcxproj_artifact.as_output(), ], f = f, ) bxl_ctx.output.print(bxl_ctx.output.ensure(vcxproj_artifact)) main = bxl_main( impl = _main, cli_args = { "debug_settings": cli_args.option(cli_args.json()), # target label => debug_settings. "extra_buck_options": cli_args.list(cli_args.string(), default = []), "immediate_buck_options": cli_args.list(cli_args.string(), default = []), "log_level": cli_args.int(default = 30), "mode_files": cli_args.list(cli_args.string(), default = ["fbsource//arvr/mode/win/dev"]), "mode_hashes": cli_args.option(cli_args.json()), # mode => configuration hash. "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