kcl-lang / kcl

KCL Programming Language (CNCF Sandbox Project). https://kcl-lang.io
https://kcl-lang.io
Apache License 2.0
1.41k stars 110 forks source link

[BUG] Support configurable PROTOC environment variable with fallback to vendored binaries #1413

Closed MatisseB closed 2 weeks ago

MatisseB commented 2 weeks ago

Bug Report

Please answer these questions before submitting your issue. Thanks!

Description

I am having problems trying to build a rust binary with embeded kclvm-api with an alpine docker image.

Currently, prost builds does not provide the flexibility to specify a custom protocol buffer compiler through an environment variable. This issue proposes a fix allowing to set a PROTOC environment variable. If this variable is not set, the system will default to using the protoc_bin_vendored binaries.

1. Minimal reproduce step (Required)

For a simlple testing project:

cargo new kclvm_musl && cd kclvm_musl
cargo add --git https://github.com/kcl-lang/kcl kclvm-api
cargo add anyhow

main.rs (code from rust api quickstart):

use kclvm_api::*;
use anyhow::Result;

fn main() -> Result<()> {
    let api = API::default();
    let args = &ExecProgramArgs {
        k_filename_list: vec!["main.k".to_string()],
        k_code_list: vec!["a = 1".to_string()],
        ..Default::default()
    };
    let exec_result = api.exec_program(args)?;
    println!("{}", exec_result.yaml_result);
    Ok(())
}

Cargo.toml:

[package]
name = "kclvm_musl"
version = "0.1.0"
edition = "2021"

[dependencies]
anyhow = "1.0.86"
kclvm-api = { git = "https://github.com/kcl-lang/kcl", version = "0.9.0" }

Dockerfile:

# -----
FROM docker.io/library/rust:1.78-alpine as builder

# # Set `SYSROOT` to a dummy path (default is /usr) because pkg-config-rs *always*
# # links those located in that path dynamically but we want static linking, c.f.
# # https://github.com/rust-lang/pkg-config-rs/blob/54325785816695df031cef3b26b6a9a203bbc01b/src/lib.rs#L613
ENV SYSROOT=/dummy

# Install dependencies
# -----
FROM docker.io/library/rust:1.78-alpine as builder

ENV SYSROOT=/dummy

RUN apk update && apk add --no-cache \
    g++ \
    musl-dev \
    pkgconfig \
    protobuf-dev \
    protoc

ENV PROTOC=/usr/bin/protoc

WORKDIR /wd
COPY . .

RUN cargo build --bin kclvm_musl --release

# -----
FROM cgr.dev/chainguard/static

COPY --from=builder /wd/target/release/kclvm_musl /kclvm_musl
ENTRYPOINT ["/kclvm_musl"]

2. What did you expect to see? (Required)

A successful docker build

3. What did you see instead (Required)

error: failed to run custom build command for `prost-wkt-types v0.4.1 (https://github.com/kcl-lang/kcl#33629fda)`

Caused by:
  process didn't exit successfully: `/wd/target/release/build/prost-wkt-types-0e704431d83ef171/build-script-build` (exit status: 101)
  --- stderr
  thread 'main' panicked at /usr/local/cargo/git/checkouts/kcl-578669463c900b87/33629fd/kclvm/third-party/prost-wkt/wkt-types/build.rs:48:10:
  called `Result::unwrap()` on an `Err` value: Custom { kind: NotFound, error: "failed to invoke protoc (hint: https://docs.rs/prost-build/#sourcing-protoc): (path: \"/usr/local/cargo/registry/src/index.crates.io-6f17d22bba15001f/protoc-bin-vendored-linux-x86_64-3.0.0/bin/protoc\"): No such file or directory (os error 2)" }
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...
------
Dockerfile:22
--------------------
  20 |     COPY . .
  21 |     
  22 | >>> RUN cargo build --bin kclvm_musl --release
  23 |     
  24 |     # -----
--------------------
ERROR: failed to solve: process "/bin/sh -c cargo build --bin kclvm_musl --release" did not complete successfully: exit code: 101

4. What is your KCL components version? (Required)

Version: 0.9.0