rustgn

11 commits
Updated 2026-05-09 17:23:41
scripts/thirdparty
scripts/thirdparty/mod.nu
const ROOT = (path self | path dirname | path dirname | path dirname)

const THIRDPARTY = ($ROOT | path join "third_party")

const RUST_VENDOR = ($THIRDPARTY | path join "rust" | path join "vendor")
const RUST_GN = ($THIRDPARTY | path join "rust")

# Vendor all rust dependencies in third_party/rust/vendor
export def "thirdparty rust vendor" [] {
    mkdir $RUST_VENDOR
    cargo vendor -q --no-delete --manifest-path ($THIRDPARTY | path join "rust" | path join "Cargo.toml") $RUST_VENDOR
}

# Generates GN build files for third-party Rust crates
export def "thirdparty rust gnrt" [crate?: string] {
    let entries = (thirdparty rust resolve)

    mkdir $RUST_GN

    if $crate == null {
        $entries
    } else {
        $entries | where name == $crate
    } | each { |it|
        mkdir ($RUST_GN | path join $it.name)
        let gn_file = $RUST_GN | path join $it.name | path join "BUILD.gn"
        let name = $it.name
        let deps = $it.dependencies
        let cargo_name = $it.cargo_name

        let sources = (glob ($RUST_VENDOR | path join $cargo_name | path join "src" | path join "**" | path join "*")) |
            where { |it| $it | str ends-with ".rs" } |
            each { |it|
                let gn_path = "//third_party" | path join ($it | path relative-to $THIRDPARTY)

                "\"" + ($gn_path) + "\""
            } |
            reduce { |it, acc|
                $acc + ",\n        " + $it
            }

        let deps = try { $deps | each { |dep|
            let gn_path = "//third_party" | path join "rust" | path join $dep
            "\"" + ($gn_path) + "\""
        } |
        reduce { |it, acc|
            $acc + ",\n        " + $it
        }
        } catch {
            ""
        }

        let gn_content = $"rust_static_library\(\"($name)\"\) {
    sources = [
        ($sources)
    ]
    crate_root = \"//third_party/rust/vendor/($cargo_name)/src/lib.rs\"
    deps = [
        ($deps)
    ]
}"
        try { $gn_content | save $gn_file }
    }
}

export def "thirdparty rust resolve" [] {
    let entries = cargo metadata --format-version 1 --manifest-path ($THIRDPARTY | path join "rust" | path join "Cargo.toml") |
        from json |
        get resolve |
        get nodes |
        each { |it|
            let name = ($it.id | split row '#' | last | split row '@' | first)

            {
                name: ($name | str snake-case),
                cargo_name: $name,
                dependencies: ($it.deps | where { |$it| $it.dep_kinds.target | any { |it| $it != "cfg(windows)" } } | get name)
            }
        }

    $entries | where name != "third_party_rust"
}