pijul nest
guest [sign in]

Rust compilation works!

pmeunier
Jul 2, 2025, 9:23 PM
LTB4YNHF75FTVQG6S5PL46CGS4CMDWZRAEXWEIXUHQHIWVYVKFKAC

Dependencies

  • [2] 6BIW5YDC Rust builder: compiling the crates
  • [3] R7J4254Z Reorganisation of the frontend
  • [4] LQBZJUGC Adding a basic Rust builder
  • [5] AJLMC7UM Forwarding log to frontend

Change contents

  • edit in elpe/lib/rust.ml at line 5
    [3.66]
    [3.66]
    (* Create a derivation whose build function fetches a crate from a
    registry, using the checksum to stay referentially
    transparent. Currently only crates.io is supported. *)
  • edit in elpe/lib/rust.ml at line 19
    [3.454]
    [3.454]
    (* Extract a string value from a toml table and a key..*)
  • replacement in elpe/lib/rust.ml at line 25
    [3.618][3.618:634]()
    let unzip pkg =
    [3.618]
    [3.634]
    (* Unzip a crate, creating a `.cargo-checksum.json` file at the root,
    which is required by Cargo registry replacement. *)
    let unzip_checksum pkg hash =
  • replacement in elpe/lib/rust.ml at line 34
    [3.771][3.771:981]()
    Lwt.return
    [
    (ubuntu "libc6-dev" :> derivation);
    (ubuntu "coreutils" :> derivation);
    (ubuntu "tar" :> derivation);
    (ubuntu "gzip" :> derivation);
    ]
    [3.771]
    [3.981]
    Lwt.return (List.map ubuntu [ "coreutils"; "tar"; "gzip"; "findutils" ])
  • replacement in elpe/lib/rust.ml at line 39
    [3.1068][3.1068:1150]()
    ("mkdir -p $DESTDIR; tar -xf " ^ List.hd zipped.destdir ^ " -C $DESTDIR")
    [3.1068]
    [3.1150]
    ("mkdir -p $DESTDIR; tar -xf " ^ List.hd zipped.destdir
    ^ " -C $DESTDIR; cd $DESTDIR/*; echo -n \\{\\\"files\\\":\\{ \
    >.cargo-checksum.json\n\
    n=0\n\
    for f in $(find . -type f -printf '%P\\n'); do\n\
    if [[ $n -gt 0 ]]; then\n\
    echo -n , >>.cargo-checksum.json\n\
    fi\n\
    echo -n \\\"$f\\\":\\\"$(sha256sum $f | cut -d\" \" -f 1)\\\" >> \
    .cargo-checksum.json;\n\
    n=$((n+1))\n\
    done\n\
    echo -n \\},\\\"package\\\":\\\"" ^ hash
    ^ "\\\"\\} >> .cargo-checksum.json")
  • replacement in elpe/lib/rust.ml at line 55
    [2.187][2.187:207]()
    let packages toml =
    [2.187]
    [2.207]
    (* Parse the Cargo.lock file, returning a hash table of all packages
    that have a `source` field, i.e. packages that come from a
    registry. *)
    let parse_cargo_lock destdir =
    let lock = Stdlib.open_in (Filename.concat destdir "Cargo.lock") in
    let toml =
    match Toml.Parser.from_channel lock with
    | `Ok toml -> toml
    | `Error (err, _) -> failwith ("Error: " ^ err)
    in
  • replacement in elpe/lib/rust.ml at line 83
    [2.845][2.845:895]()
    let drv = (unzip h :> derivation) in
    [2.845]
    [2.895]
    let drv = (unzip_checksum h checksum :> derivation) in
  • replacement in elpe/lib/rust.ml at line 103
    [2.1473][2.1473:1546]()
    let metadata rust_version cargo rustc platform src n_packages packages =
    [2.1473]
    [3.1192]
    (* Run `cargo metadata` in a derivation. This derivation doesn't
    produce anything and only forwards the stdandard output of `cargo
    metadata`. *)
    class metadata rust_version cargo rustc platform src n_packages packages =
  • replacement in elpe/lib/rust.ml at line 109
    [3.1235][2.1547:1572]()
    method name = "test"
    [3.1235]
    [3.1260]
    method name = "metadata"
  • replacement in elpe/lib/rust.ml at line 125
    [2.1984][2.1984:2128]()
    if Hashtbl.find_opt h crate_name = None then
    crate_name ^ "-" ^ version
    else crate_name
    [2.1984]
    [2.2128]
    if Hashtbl.find_opt h crate_name = None then (
    Hashtbl.add h crate_name ();
    crate_name)
    else crate_name ^ "-" ^ version
  • edit in elpe/lib/rust.ml at line 130
    [2.2147]
    [2.2147]
    List.iter self#add_path built.destdir;
  • replacement in elpe/lib/rust.ml at line 152
    [2.2938][2.2938:3015]()
    method! build_inputs = Lwt.return [ (ubuntu "coreutils" :> derivation) ]
    [2.2938]
    [2.3015]
    method! build_inputs = Lwt.return [ ubuntu "coreutils" ]
  • replacement in elpe/lib/rust.ml at line 155
    [3.1640][2.3022:3151]()
    let compile_crate rust_version rustc platform package path deps features =
    let target_platform = "x86_64-unknown-linux-gnu" in
    [3.1640]
    [2.3151]
    let underscorize = String.map (fun c -> if c = '-' then '_' else c)
    type deps = { build_dependencies : string; dependencies : string }
    (* A derivation building a crate, created from the crate's resolved
    parameters. *)
    class compiled_crate rust_version rustc cc platform package path deps features =
  • replacement in elpe/lib/rust.ml at line 163
    [2.3167][2.3167:3194]()
    inherit std_derivation
    [2.3167]
    [2.3194]
    inherit std_derivation as super
  • edit in elpe/lib/rust.ml at line 165
    [2.3250]
    [2.3250]
    method version = package |> member "version" |> to_string
  • edit in elpe/lib/rust.ml at line 167
    [2.3284]
    [2.3284]
    val target_platform = platform
  • replacement in elpe/lib/rust.ml at line 169
    [2.3285][2.3285:3310]()
    method! post_setup =
    [2.3285]
    [2.3310]
    (* Ubuntu installs Rust in a convoluted path with wrapper
    scripts. *)
    method! setup =
  • edit in elpe/lib/rust.ml at line 173
    [2.3347]
    [3.2324]
    let* s = super#setup in
  • replacement in elpe/lib/rust.ml at line 175
    [3.2341][2.3348:3485]()
    ("export HOME=/home/me\nmkdir -p $HOME\nexport PATH=" ^ List.hd rustc
    ^ "/usr/lib/rust-" ^ rust_version ^ "/bin:$PATH\n")
    [3.2341]
    [3.2913]
    (s ^ "export HOME=/home/me\nmkdir -p $HOME\nexport PATH="
    ^ List.hd rustc ^ "/usr/lib/rust-" ^ rust_version ^ "/bin:$PATH\n")
  • replacement in elpe/lib/rust.ml at line 178
    [3.2914][3.2914:2940](),[3.2940][2.3486:3688]()
    method! build_phase =
    let platform =
    match platform with Some s -> " --filter-platform " ^ s | None -> ""
    in
    let features =
    String.concat ", " (List.map (fun x -> "\"" ^ x ^ "\"") features)
    [3.2914]
    [3.3114]
    (* Rustc has the option of generating extra filenames to
    disambiguate things. We keep track of these in the `hash`
    parameter of built derivations. *)
    val hash =
    let id = package |> member "id" |> to_string in
    let f =
    List.fold_left
    (fun acc x -> acc ^ " --cfg 'feature=\"" ^ x ^ "\"'")
    "" features
  • edit in elpe/lib/rust.ml at line 189
    [3.3123]
    [2.3689]
    String.sub
    (Digest.BLAKE128.to_hex
    (Digest.BLAKE128.string (rust_version ^ "\000" ^ id ^ "\000" ^ f)))
    0 16
  • replacement in elpe/lib/rust.ml at line 194
    [2.3690][2.3690:4202]()
    let setup = ref "set -x\nrustc --print sysroot\n" in
    let dependencies = "" in
    let compile_target target kind =
    let src_path = target |> member "src_path" |> to_string in
    let name = target |> member "name" |> to_string in
    let edition =
    try " --edition=" ^ (target |> member "edition" |> to_string) ^ " "
    with Not_found -> (
    try " --edition=" ^ (package |> member "edition" |> to_string) ^ " "
    with Not_found -> " ")
    in
    [2.3690]
    [2.4202]
    method hash = hash
    (* If this src_path comes from a vendored directory (i.e. if it's
    a dependency), remove the "vendor" prefix. *)
    method private strip_src_path src_path =
    let prefix = "/src/vendor/" ^ self#name ^ "-" ^ self#version ^ "/" in
    if String.starts_with ~prefix src_path then
    String.sub src_path (String.length prefix)
    (String.length src_path - String.length prefix)
    else
    let prefix_ = "/src/vendor/" ^ self#name ^ "/" in
    if String.starts_with ~prefix:prefix_ src_path then
    String.sub src_path (String.length prefix_)
    (String.length src_path - String.length prefix_)
    else src_path
    (* Concatenation of `--cfg feature=…`. *)
    val features_args =
    List.fold_left
    (fun acc x -> acc ^ " --cfg 'feature=\"" ^ x ^ "\"'")
    "" features
  • edit in elpe/lib/rust.ml at line 216
    [2.4203]
    [2.4203]
    method private compile_target setup platform target kind dependencies out =
    let initial_src_path = target |> member "src_path" |> to_string in
    let src_path = self#strip_src_path initial_src_path in
    let name = target |> member "name" |> to_string in
    let under = underscorize name in
    let edition =
    try " --edition=" ^ (target |> member "edition" |> to_string) ^ " "
    with Not_found -> (
    try " --edition=" ^ (package |> member "edition" |> to_string) ^ " "
    with Not_found -> " ")
    in
    let platform =
    match platform with Some p -> " --target " ^ p | None -> ""
    in
    if kind = "bin" then
  • replacement in elpe/lib/rust.ml at line 232
    [2.4220][2.4220:4754]()
    !setup ^ "rustc --crate-name " ^ name ^ edition ^ src_path
    ^ " --crate-type " ^ kind
    ^ " --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2 \
    --cfg 'feature=\"cargo-build \"' --cfg 'feature=\"default\"' \
    --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values("
    ^ features
    ^ "))' -C metadata=db5f6b051938318f -C \
    extra-filename=-99d0a40c2aab0586 --out-dir $DESTDIR/lib "
    ^ dependencies ^ " --cap-lints allow\n"
    [2.4220]
    [3.3274]
    !setup ^ "rustc --crate-name " ^ under ^ edition ^ src_path ^ platform
    ^ " --crate-type bin -C linker=gcc" ^ features_args ^ " -C metadata="
    ^ hash ^ " --out-dir " ^ out ^ dependencies ^ " --cap-lints allow\n"
    else
    setup :=
    !setup ^ "rustc --crate-name " ^ under ^ edition ^ src_path
    ^ " --crate-type " ^ kind ^ platform
    ^ " --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2"
    ^ features_args ^ " -C metadata=" ^ hash ^ " --out-dir " ^ out
    ^ " -C extra-filename=-" ^ hash ^ dependencies
    ^ " --cap-lints allow\n";
    under
    (* The `dependencies` method below computes the build and regular
    dependencies in one go, caching them in the
    `computed_dependencies` value. *)
    val computed_dependencies = ref None
    method private dependencies =
    match !computed_dependencies with
    | Some d -> Lwt.return d
    | None ->
    let package_deps =
    let d = package |> member "dependencies" |> to_list in
    let h = Hashtbl.create (List.length d) in
    List.iter
    (fun d -> Hashtbl.add h (d |> member "name" |> to_string) d)
    d;
    h
    in
    let de = ref "" in
    let build_de = ref "" in
    let* deps =
    Lwt_list.map_p
    (fun x ->
    let* b = x#build in
    Lwt.return (x#name, x#hash, b))
    deps
    in
    List.iter
    (fun (x_name, x_hash, b) ->
    let d = Hashtbl.find package_deps x_name in
    let is_build =
    d |> member "kind" |> to_option to_string = Some "build"
    in
    List.iter self#add_path b.destdir;
    let name =
    match d |> member "rename" |> to_option to_string with
    | Some rename -> rename
    | None -> x_name
    in
    let r = if is_build then build_de else de in
    r :=
    !r ^ " -L dependency=target/deps --extern " ^ name ^ "="
    ^ List.hd b.destdir ^ "/lib/lib" ^ x_name ^ "-" ^ x_hash
    ^ ".rlib")
    deps;
    let result = { build_dependencies = !build_de; dependencies = !de } in
    computed_dependencies := Some result;
    Lwt.return result
    method! build_inputs = Lwt.return [ ubuntu "coreutils"; cc ]
    (* Run the build script, if any. Also `cd` to the correct
    directory. *)
    method! configure_phase =
    let setup =
    ref ("set -x\nmkdir -p target/build-" ^ hash ^ "\nexport RUSTC=rustc\n")
    in
    let has_source =
    try
    let _ = package |> member "source" |> to_string in
    true
    with Not_found | Yojson.Basic.Util.Type_error _ -> false
    in
    let* d = self#dependencies in
    (* The following fold does two things in one pass: *)
    let _, build_script =
    List.fold_left
    (fun (is_first_target, build_script) target ->
    if is_first_target && has_source then
    setup := !setup ^ "cd " ^ self#name ^ "-" ^ self#version ^ "\n"
    else ();
    (* The other task is to add the build script if there is
    one, and return its name. *)
    ( false,
    List.fold_left
    (fun has_it kind ->
    match kind with
    | "custom-build" ->
    Some
    (self#compile_target setup None target "bin"
    d.build_dependencies ("target/build-" ^ hash))
    | _ -> has_it)
    build_script
    (target |> member "kind" |> to_list |> filter_string) ))
    (true, None)
    (package |> member "targets" |> to_list)
    in
    (* If there is a build script, call it. *)
    let _ =
    match build_script with
    | Some bs_name ->
    setup := !setup ^ "target/build-" ^ hash ^ "/" ^ bs_name ^ "\n"
    | None -> ()
  • edit in elpe/lib/rust.ml at line 341
    [3.3283]
    [2.4755]
    Lwt.return !setup
    (* Run the main build command and install the results at the same
    time. *)
    method! build_phase =
    let* d = self#dependencies in
    let setup = ref "" in
    let has_bin = ref false in
    let has_lib = ref false in
  • edit in elpe/lib/rust.ml at line 355
    [2.4839]
    [2.4839]
    if kind = "bin" then
    if !has_bin then ()
    else (
    has_bin := true;
    setup := !setup ^ "mkdir -p $DESTDIR/bin\n")
    else if !has_lib then ()
    else (
    has_lib := true;
    setup := !setup ^ "mkdir -p $DESTDIR/lib\n");
  • edit in elpe/lib/rust.ml at line 366
    [2.4950]
    [2.4950]
    ->
    let _ =
    self#compile_target setup target_platform target kind
    d.dependencies "$DESTDIR/lib"
    in
    ()
  • replacement in elpe/lib/rust.ml at line 373
    [2.4975][2.4975:5020]()
    compile_target target kind
    [2.4975]
    [2.5020]
    let _ =
    self#compile_target setup target_platform target kind
    d.dependencies "$DESTDIR/bin"
    in
    ()
  • edit in elpe/lib/rust.ml at line 382
    [2.5186][3.3475:3476](),[3.3475][3.3475:3476](),[3.3476][2.5187:5264]()
    method! build_inputs = Lwt.return [ (ubuntu "coreutils" :> derivation) ]
  • replacement in elpe/lib/rust.ml at line 384
    [3.4399][2.5271:5346]()
    let rust ?(rust_version = "1.84") ?(platform = None) ?(crate = None) src =
    [3.4399]
    [2.5346]
    let rust ?(rust_version = "1.84") ?(platform = None) src =
  • replacement in elpe/lib/rust.ml at line 386
    [2.5378][2.5378:5665]()
    let lock =
    Stdlib.open_in (Filename.concat (List.hd src_built.destdir) "Cargo.lock")
    in
    let parsed =
    match Toml.Parser.from_channel lock with
    | `Ok toml -> toml
    | `Error (err, _) -> failwith ("Error: " ^ err)
    in
    let* packages_drv, packages = packages parsed in
    [2.5378]
    [2.5665]
    let* packages_drv, packages = parse_cargo_lock (List.hd src_built.destdir) in
  • edit in elpe/lib/rust.ml at line 393
    [2.5896]
    [2.5896]
    let cc = ubuntu "build-essential" in
  • replacement in elpe/lib/rust.ml at line 396
    [2.5914][2.5914:5985]()
    metadata rust_version cargo rustc platform src n_packages packages
    [2.5914]
    [2.5985]
    new metadata rust_version cargo rustc platform src n_packages packages
  • edit in elpe/lib/rust.ml at line 413
    [2.6520][2.6520:6521]()
  • edit in elpe/lib/rust.ml at line 431
    [2.7105][2.7105:7158]()
    let deps = node |> member "deps" |> to_list in
  • replacement in elpe/lib/rust.ml at line 434
    [2.7258][2.7258:7331]()
    compile_crate rust_version rustc platform meta drv deps features
    [2.7258]
    [3.4792]
    new compiled_crate
    rust_version rustc cc platform meta drv dependencies features
  • edit in elpe/lib/derivation.ml at line 116
    [3.3342]
    [3.3342]
    val cached_build = ref None
    val build_lock = Lwt_mutex.create ()
  • replacement in elpe/lib/derivation.ml at line 120
    [3.3363][3.3363:4112]()
    let c =
    match !backend_conn with None -> failwith "no conn" | Some c -> c
    in
    let* index =
    Lwt_list.map_p
    (fun repository ->
    let* res = ubuntu_release c ~release ~arch:Amd64 ~repository in
    let res, _ = Result.get_ok res in
    match res with
    | `Ok r -> Lwt.return r.destdir
    | `Error e -> failwith e
    | _ -> assert false)
    [ "main"; "universe" ]
    in
    let index = List.concat index in
    let* res = ubuntu_package c ~index ~name in
    let res, _ = Result.get_ok res in
    match res with
    | `Ok r -> Lwt.return { destdir = r.destdir; paths = r.paths }
    | `Error e -> failwith e
    | _ -> assert false
    [3.3363]
    [3.4112]
    match !cached_build with
    | Some x -> Lwt.return x
    | None ->
    Lwt_mutex.with_lock build_lock (fun () ->
    let c =
    match !backend_conn with
    | None -> failwith "no conn"
    | Some c -> c
    in
    let* index =
    Lwt_list.map_p
    (fun repository ->
    let arch =
    match arch with
    | Amd64 -> Elpegrpc.Elpe.Arch.Amd64
    | Aarch64 -> Elpegrpc.Elpe.Arch.Aarch64
    in
    let* res = ubuntu_release c ~release ~arch ~repository in
    let res, _ = Result.get_ok res in
    match res with
    | `Ok r -> Lwt.return r.destdir
    | `Error e -> raise (DerivationError e)
    | _ -> assert false)
    [ "main"; "universe" ]
    in
    let index = List.concat index in
    let* res = ubuntu_package c ~index ~name in
    let r = Result.get_ok res in
    let x = { destdir = r.destdir; paths = r.paths } in
    cached_build := Some x;
    Lwt.return x)
  • replacement in elpe/lib/derivation.ml at line 233
    [3.6888][2.7960:8029]()
    List.fold_right (fun r () -> self#add_path r) path.destdir ();
    [3.6888]
    [3.7132]
    List.iter self#add_path path.destdir;
  • edit in elpe/lib/derivation.ml at line 237
    [3.7236]
    [3.7236]
    val post_setup = ""
  • edit in elpe/lib/derivation.ml at line 247
    [3.7499][3.7499:7552]()
    extra_paths := p.destdir @ !extra_paths;
  • edit in elpe/lib/derivation.ml at line 250
    [3.7618]
    [3.7618]
    List.iter (List.iter self#add_path) paths;
  • edit in elpe/lib/derivation.ml at line 258
    [3.7811][3.7811:7854]()
    let* post_setup = self#post_setup in
  • replacement in elpe/lib/derivation.ml at line 264
    [3.8109][3.8109:8224]()
    method post_setup = Lwt.return ""
    method pre_unpack = Lwt.return ""
    method post_unpack = Lwt.return ""
    [3.8109]
    [3.8224]
    val pre_unpack = ""
    val post_unpack = ""
  • replacement in elpe/lib/derivation.ml at line 270
    [3.8316][3.8316:8371]()
    extra_paths := src_built.destdir @ !extra_paths;
    [3.8316]
    [3.8371]
    List.iter self#add_path src_built.destdir;
  • replacement in elpe/lib/derivation.ml at line 272
    [3.8372][3.8372:8611]()
    let* all = Lwt.all [ self#pre_unpack; self#post_unpack ] in
    match all with
    | pre :: post :: _ ->
    Lwt.return
    (pre ^ "\ncp -R " ^ List.hd src_built.destdir ^ "/. .\n" ^ post)
    | _ -> assert false
    [3.8372]
    [3.8611]
    Lwt.return
    (pre_unpack ^ "\ncp -R " ^ List.hd src_built.destdir ^ "/. .\n"
    ^ post_unpack)
  • replacement in elpe/lib/derivation.ml at line 276
    [3.8612][3.8612:8695]()
    method pre_configure = Lwt.return ""
    method post_configure = Lwt.return ""
    [3.8612]
    [3.8695]
    val pre_configure = ""
    val post_configure = ""
  • replacement in elpe/lib/derivation.ml at line 280
    [3.8725][3.8725:8970]()
    let* all = Lwt.all [ self#pre_configure; self#post_configure ] in
    match all with
    | pre :: post :: _ ->
    Lwt.return
    (pre ^ "\nif [[ -e configure ]]; then ./configure; fi\n" ^ post)
    | _ -> assert false
    [3.8725]
    [3.8970]
    Lwt.return
    (pre_configure ^ "\nif [[ -e configure ]]; then ./configure; fi\n"
    ^ post_configure)
  • replacement in elpe/lib/derivation.ml at line 284
    [3.8971][3.8971:9046]()
    method pre_build = Lwt.return ""
    method post_build = Lwt.return ""
    [3.8971]
    [3.9046]
    val pre_build = ""
    val post_build = ""
  • replacement in elpe/lib/derivation.ml at line 288
    [3.9072][3.9072:9289]()
    let* all = Lwt.all [ self#pre_build; self#post_build ] in
    match all with
    | pre :: post :: _ ->
    Lwt.return (pre ^ "\nif [[ -e Makefile ]]; then make; fi\n" ^ post)
    | _ -> assert false
    [3.9072]
    [3.9289]
    Lwt.return
    (pre_build ^ "\nif [[ -e Makefile ]]; then make; fi\n" ^ post_build)
  • replacement in elpe/lib/derivation.ml at line 291
    [3.9290][3.9290:9369]()
    method pre_install = Lwt.return ""
    method post_install = Lwt.return ""
    [3.9290]
    [3.9369]
    val pre_install = ""
    val post_install = ""
  • replacement in elpe/lib/derivation.ml at line 295
    [3.9397][3.9397:9638]()
    let* all = Lwt.all [ self#pre_install; self#post_install ] in
    match all with
    | pre :: post :: _ ->
    Lwt.return
    (pre ^ "\nif [[ -e Makefile ]]; then make install; fi\n" ^ post)
    | _ -> assert false
    [3.9397]
    [3.9638]
    Lwt.return
    (pre_install ^ "\nif [[ -e Makefile ]]; then make install; fi\n"
    ^ post_install)
  • edit in elpe/lib/derivation.ml at line 300
    [2.8062]
    [2.8062]
    val build_lock = Lwt_mutex.create ()
  • replacement in elpe/lib/derivation.ml at line 303
    [3.9659][2.8064:9075]()
    match !cached_build with
    | Some cached -> Lwt.return cached
    | None -> (
    let* phases =
    Lwt.all
    [
    self#setup;
    self#unpack_phase;
    self#configure_phase;
    self#build_phase;
    self#install_phase;
    ]
    in
    let builder = String.concat "\n" phases in
    let c =
    match !backend_conn with None -> failwith "no conn" | Some c -> c
    in
    let* output_hash = self#output_hash in
    let* r =
    derivation c ~name:self#name ~builder ~paths:!extra_paths
    ~stdout:!(self#stdout) ~stderr:!(self#stderr) ~target:self#target
    ~output_hash
    in
    match r with
    | `Ok r ->
    let c = { destdir = r.destdir; paths = r.paths } in
    cached_build := Some c;
    Lwt.return c
    | `Error e -> failwith e
    | _ -> assert false)
    [3.9659]
    [3.10404]
    Lwt_mutex.with_lock build_lock (fun () ->
    match !cached_build with
    | Some cached -> Lwt.return cached
    | None -> (
    let* setup = self#setup in
    let* unpack_phase = self#unpack_phase in
    let* configure_phase = self#configure_phase in
    let* build_phase = self#build_phase in
    let* install_phase = self#install_phase in
    let phases =
    [
    setup;
    unpack_phase;
    configure_phase;
    build_phase;
    install_phase;
    ]
    in
    let builder = String.concat "\n" phases in
    let c =
    match !backend_conn with
    | None -> failwith "no conn"
    | Some c -> c
    in
    let* output_hash = self#output_hash in
    let* r =
    derivation c ~name:self#name ~builder ~paths:!extra_paths
    ~stdout:!(self#stdout) ~stderr:!(self#stderr)
    ~target:self#target ~output_hash
    in
    match r with
    | `Ok r ->
    let c = { destdir = r.destdir; paths = r.paths } in
    cached_build := Some c;
    Lwt.return c
    | `Error e -> failwith e
    | _ -> assert false))
  • edit in elpe/lib/derivation.ml at line 384
    [3.11907]
    let unzip pkg =
    object (self)
    inherit std_derivation
    method name = "rust"
    method! unpack_phase = Lwt.return ""
    method! build_inputs =
    Lwt.return
    [
    (ubuntu "libc6-dev" :> derivation);
    (ubuntu "coreutils" :> derivation);
    (ubuntu "tar" :> derivation);
    (ubuntu "gzip" :> derivation);
    ]
    method! build_phase =
    let* zipped = self#derivation pkg in
    Lwt.return
    ("mkdir -p $DESTDIR; tar -xf " ^ List.hd zipped.destdir ^ " -C $DESTDIR")
    end