Skip to main content
Glama
julia_binary.bzl5.47 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//linking:shared_libraries.bzl", "create_shlib_symlink_tree", "merge_shared_libraries", "traverse_shared_library_info", ) load("@prelude//utils:utils.bzl", "flatten") load(":julia_info.bzl", "JuliaLibraryInfo", "JuliaLibraryTSet", "JuliaToolchainInfo") def build_jll_shlibs_mapping(ctx: AnalysisContext, json_info_file: Artifact): """ Builds a mapping of julia shared library names to their corresponding.so files We need to create a JSON file that contains all the relevant jlls, all the shlibs that that particular jll needs to link to, and the solib locations. Julia requires an absolute path. We get around this by establishing the paths of all the libraries relative to the current JSON file, and then pull the absolute path of the JSON file during runtime with a python script. We populate the JSON file with the following structure: Generates a list with the following structure: [ ("first_jll", "uuid", [ ("julia_foo_solib_name", symlink_dir_location, shlib_label), ("julia_bar_solib_name", symlink_dir_location, shlib_label), ] ) ... etc ] """ # build a tree for the jlls deps = filter(None, [dep.get(JuliaLibraryInfo) for dep in ctx.attrs.deps]) julia_library_info = ctx.actions.tset( JuliaLibraryTSet, children = [j.julia_tsets for j in deps], ) # build a tree for the c/c++ shlibs shlibs = traverse_shared_library_info(merge_shared_libraries( ctx.actions, None, filter(None, [d.shared_library_info for d in deps]), )) shared_libs_symlink_tree = create_shlib_symlink_tree( actions = ctx.actions, out = "__shared_libs_symlink_tree__", shared_libs = shlibs, ) shlib_label_to_soname = {shlib.label: shlib.soname.ensure_str() for shlib in shlibs} # iterate through all the jll libraries json_info = [] for jli in julia_library_info.traverse(): jll = jli.jll if jll == None: continue # iterate through all the shlib dependencies for the current jll artifact_info = [] for julia_name, label in jll.libs.items(): symlink_dir = cmd_args( shared_libs_symlink_tree, delimiter = "", relative_to = json_info_file, # That cannot be produced by a tset projection ) artifact_info.append((julia_name, symlink_dir, shlib_label_to_soname[label])) json_info.append((jll.name, jli.uuid, artifact_info)) return json_info def build_load_path_symtree(ctx: AnalysisContext): """Builds symtree of all julia library files.""" dep_julia_library_infos = filter(None, [dep.get(JuliaLibraryInfo) for dep in ctx.attrs.deps]) julia_library_info = ctx.actions.tset( JuliaLibraryTSet, children = [j.julia_tsets for j in dep_julia_library_infos], ) traversed = list(julia_library_info.traverse()) src_labels = flatten([t.src_labels for t in traversed]) srcs = flatten([t.srcs for t in traversed]) dict_from_tree = { k: p for k, p in zip(src_labels, srcs) } symlink_dir = ctx.actions.symlinked_dir("_modules_", dict_from_tree) return symlink_dir def build_julia_command(ctx): """ run a command of the form: $ julia -flag_1 -flag_2 -- my_script.jl arg1 arg2 https://docs.julialang.org/en/v1/manual/command-line-options/ """ julia_toolchain = ctx.attrs._julia_toolchain[JuliaToolchainInfo] # build out the symlink tree for libs symlink_dir = build_load_path_symtree(ctx) # build symdir for sources srcs_by_path = {f.short_path: f for f in ctx.attrs.srcs} srcs = ctx.actions.symlinked_dir("srcs_tree", srcs_by_path) if ctx.attrs.main not in srcs_by_path: fail("main should be in srcs!") # python processor cmd = cmd_args( [julia_toolchain.cmd_processor], hidden = [symlink_dir] + [srcs], ) # prepare a json file to hold all the data the python preprocessor needs to # execute the julia interpreter. json_info_file = ctx.actions.declare_output("artifacts/Overrides.json") json_info_dict = { "env": julia_toolchain.env, "jll_mapping": build_jll_shlibs_mapping(ctx, json_info_file), "julia_args": ctx.attrs.julia_args, "julia_binary": cmd_args(julia_toolchain.julia, delimiter = " ", relative_to = json_info_file), "julia_flags": ctx.attrs.julia_flags, "lib_path": cmd_args(symlink_dir, delimiter = " ", relative_to = json_info_file), "main": cmd_args(srcs.project(ctx.attrs.main), delimiter = " ", relative_to = json_info_file), } json_file_loc = ctx.actions.write_json(json_info_file, json_info_dict, with_inputs = True) # json path cmd.add(["--json-path", json_file_loc]) return cmd, json_info_file def julia_binary_impl(ctx: AnalysisContext) -> list[Provider]: cmd, json_info_file = build_julia_command(ctx) return [DefaultInfo(default_output = json_info_file, other_outputs = [cmd]), RunInfo(cmd)]

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