Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/grpc-clib-checksum.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Verify gRPC CLib Checksum is Up-to-Date

on:
pull_request:

permissions:
contents: read

jobs:
verify-platforms-table:
name: Run Verification
runs-on: ubuntu-latest
steps:
- name: Checkout Sources
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Run gRPC Checksum Generation
run: ./gradlew grpc:grpc-core:computeSha256AllTargetsForCLibGrpc_fat --info --stacktrace
- name: Check if prebuilt gRPC library checksum is up-to-date
run: |
if [[ -n "$(git status --porcelain | grep cinterop-c/prebuilt-deps/grpc_fat/)" ]]; then
echo "Prebuilt gRPC library checksum is not up to date. Please run './gradlew grpc:grpc-core:computeSha256AllTargetsForCLibGrpc_fat' and commit changes"
exit 1
fi
2 changes: 0 additions & 2 deletions cinterop-c/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,3 @@
/.aswb/
/.clwb/
.idea/

out/
14 changes: 4 additions & 10 deletions cinterop-c/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
load("@rules_cc//cc:defs.bzl", "cc_library")

cc_static_library(
name = "kgrpc_static",
deps = [
":kgrpc",
],
)

cc_library(
name = "kgrpc",
srcs = ["src/kgrpc.cpp"],
Expand All @@ -15,12 +9,12 @@ cc_library(
includes = ["include"],
visibility = ["//visibility:public"],
deps = [
"@com_github_grpc_grpc//:grpc",
"//prebuilt-deps/grpc_fat:grpc_core_prebuilt",
],
)

cc_static_library(
name = "protowire_static",
name = "protowire_fat",
deps = [
":protowire",
],
Expand All @@ -34,6 +28,6 @@ cc_library(
includes = ["include"],
visibility = ["//visibility:public"],
deps = [
"@com_google_protobuf//:protobuf_lite",
"@com_github_protobuffers_protobuf//:protobuf_lite",
],
)
9 changes: 7 additions & 2 deletions cinterop-c/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,22 @@ bazel_dep(

# required to build for apple targets (like iOS)
bazel_dep(name = "apple_support", version = "1.22.1", repo_name = "build_bazel_apple_support")
bazel_dep(name = "platforms", version = "1.0.0")

# Protobuf
bazel_dep(
name = "protobuf",
version = "31.1",
repo_name = "com_google_protobuf",
repo_name = "com_github_protobuffers_protobuf",
)

# gRPC library
GRPC_VERSION = "1.74.1"

## gRPC source dependency

bazel_dep(
name = "grpc",
version = "1.74.1",
version = GRPC_VERSION,
repo_name = "com_github_grpc_grpc",
)
3 changes: 2 additions & 1 deletion cinterop-c/MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cinterop-c/build_target.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ out="$(bazel cquery "$LABEL" --platforms="$PLATFORM" --apple_platform_type="$OS"

cp -f "$out" "$DST"

echo "Done. Binary written to: $DST"
echo "Done. Binary written to: $DST" >&2
33 changes: 33 additions & 0 deletions cinterop-c/extract_include_dir.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
#
# Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
#

set -Eeuo pipefail
trap 'echo "ERROR: Build failed at ${BASH_SOURCE}:${LINENO}" >&2' ERR

# Extract all headers in the /include directory of the given target.
#
# Usage:
# ./extract_include_dir.sh <target> <output-directory>
# Example:
# ./extract_include_dir.sh //prebuilt-deps/grpc_fat:grpc_fat prebuilt-deps/grpc_fat
#
# The example will produce the prebuilt-deps/grpc_fat/include directory with all headers.

LABEL="${1:?need bazel target label}"
DST="${2:?need output destination}"

CONFIG=release

mkdir -p $(dirname "$DST")

bazel build "$LABEL" >/dev/null

# Ask Bazel what file(s) this target produced
out="$(bazel cquery "$LABEL" --output=files | head -n1)"
[[ -n "$out/include" ]] || { echo "No output for $LABEL"; exit 1; }

rm -rf "$DST/include"
cp -rLf "$out/include" "$DST/include"
chmod -R u+w "$DST"
9 changes: 4 additions & 5 deletions cinterop-c/include/kgrpc.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
/*
* Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
// Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.

/*
* Helper functions required for gRPC Core cinterop.
Expand All @@ -25,10 +23,11 @@ typedef struct {
void *user_data;
} kgrpc_cb_tag;

/*

/*
* Call to grpc_iomgr_run_in_background(), which is not exposed as extern "C" and therefore must be wrapped.
*/
bool kgrpc_iomgr_run_in_background();
bool kgrpc_iomgr_run_in_background();

#ifdef __cplusplus
}
Expand Down
99 changes: 99 additions & 0 deletions cinterop-c/prebuilt-deps/grpc_fat/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
load("@rules_cc//cc:defs.bzl", "cc_import", "cc_library")
load("//:tools/collect_headers.bzl", "cc_headers_only", "include_dir")

package(default_visibility = ["//visibility:public"])

#### Compile gRPC from scratch ####

cc_static_library(
name = "grpc_fat",
deps = [
"@com_github_grpc_grpc//:grpc",
],
)

include_dir(
name = "grpc_include_dir",
target = "@com_github_grpc_grpc//:grpc",
)

#### Targets for pre-built dependency ####

# extract only the header files from grpc without compiling it
cc_headers_only(
name = "grpc_hdrs_ccinfo",
dep = "@com_github_grpc_grpc//:grpc",
)

cc_library(
name = "grpc_core_prebuilt",
visibility = ["//visibility:public"],
deps = [":grpc_hdrs_ccinfo"] +
# pick the right prebuilt .a:
select({
":ios_device_arm64": [":grpc_core_ios_arm64"],
":ios_simulator_arm64": [":grpc_core_ios_sim_arm64"],
":ios_simulator_x64": [":grpc_core_ios_x64"],
":macos_arm64": [":grpc_core_macos_arm64"],
"//conditions:default": [],
}),
)

config_setting(
name = "ios_device_arm64",
constraint_values = [
"@platforms//os:ios",
"@platforms//cpu:arm64",
"@build_bazel_apple_support//constraints:device",
],
)

config_setting(
name = "ios_simulator_arm64",
constraint_values = [
"@platforms//os:ios",
"@platforms//cpu:arm64",
"@build_bazel_apple_support//constraints:simulator",
],
)

config_setting(
name = "ios_simulator_x64",
constraint_values = [
"@platforms//os:ios",
"@platforms//cpu:x86_64",
"@build_bazel_apple_support//constraints:simulator",
],
)

config_setting(
name = "macos_arm64",
constraint_values = [
"@platforms//os:macos",
"@platforms//cpu:arm64",
],
)

cc_import(
name = "grpc_core_ios_arm64",
static_library = ":libgrpc_fat.ios_arm64.a",
visibility = ["//visibility:public"],
)

cc_import(
name = "grpc_core_ios_sim_arm64",
static_library = ":libgrpc_fat.ios_simulator_arm64.a",
visibility = ["//visibility:public"],
)

cc_import(
name = "grpc_core_ios_x64",
static_library = ":libgrpc_fat.ios_x64.a",
visibility = ["//visibility:public"],
)

cc_import(
name = "grpc_core_macos_arm64",
static_library = ":libgrpc_fat.macos_arm64.a",
visibility = ["//visibility:public"],
)
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
7bc13a15c59850048e77b5719ea262a6fcc22884ab42c9f14f38859200faac9b
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
55fde875508372860125ee8505ef4e84b95c9620744378a99f8f4095292dcae5
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
7544113fe9b6c9d0a57c8b8864b5272e01e3a64ea36cd0802d4a76e98ad5e232
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
6cf466a285832ecd0f41041164c412e9b541388210058310d7bb59f6a27d09de
5 changes: 1 addition & 4 deletions cinterop-c/src/kgrpc.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
/*
* Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
// Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.

#include <kgrpc.h>

#include "src/core/lib/iomgr/iomgr.h"

extern "C" {
Expand Down
91 changes: 91 additions & 0 deletions cinterop-c/tools/collect_headers.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
HeaderInfo = provider(fields = ["headers_dir", "headers"])

# determines if the file is in the given repository
def _same_repo(file, repo_name):
p = file.path
if repo_name:
return ("external/%s/" % repo_name) in p

return "external/" not in p

def _include_dir_impl(ctx):
cc = ctx.attr.target[CcInfo].compilation_context

# transitive headers
all_hdrs = cc.headers
hdrs = all_hdrs.to_list() if type(all_hdrs) == "depset" else all_hdrs

repo_name = ctx.attr.target.label.repo_name

# filter: same repo + paths that contain /include/
hdrs = [
f
for f in hdrs
if "/include/" in f.path and _same_repo(f, repo_name)
]

manifest = ctx.actions.declare_file(ctx.label.name + ".headers.list")
outdir = ctx.actions.declare_directory(ctx.label.name + "_includes")

ctx.actions.write(manifest, "\n".join([f.path for f in hdrs]))

# copy them to some output directory
ctx.actions.run_shell(
inputs = hdrs + [manifest],
outputs = [outdir],
command = r"""
set -euo pipefail
OUT="$1"; MAN="$2"
python3 - <<'PY' "$OUT" "$MAN"
import os, shutil, sys
out, man = sys.argv[1], sys.argv[2]
for p in open(man):
p = p.strip()
if not p: continue
# keep include/ prefix once
rel = p.split("/include/", 1)[1]
dst = os.path.join(out, "include", rel)
os.makedirs(os.path.dirname(dst), exist_ok=True)
shutil.copy2(p, dst)
PY
""",
arguments = [outdir.path, manifest.path],
progress_message = "Collecting repo-scoped headers into %s" % outdir.path,
mnemonic = "CollectIncludes",
)

return [
DefaultInfo(files = depset([outdir])),
HeaderInfo(headers_dir = outdir, headers = depset(hdrs)),
]

# rule to copy the include directory of some target to some location
include_dir = rule(
implementation = _include_dir_impl,
attrs = {
"target": attr.label(mandatory = True),
},
)

def _cc_headers_only_impl(ctx):
dep_cc = ctx.attr.dep[CcInfo].compilation_context

# keep only source headers; this skips generated headers and their actions.
all_hdrs = dep_cc.headers.to_list()
src_hdrs = [f for f in all_hdrs if getattr(f, "is_source", False)]
cc_ctx = cc_common.create_compilation_context(
headers = depset(src_hdrs),
includes = dep_cc.includes,
quote_includes = dep_cc.quote_includes,
system_includes = dep_cc.system_includes,
framework_includes = dep_cc.framework_includes,
defines = dep_cc.defines,
)
return [CcInfo(compilation_context = cc_ctx)]

# rule to build a CcInfo that only contains the headers of a given CcInfo target.
# this allows us to combine the headers of the dependency sources with our pre-compiled dependencies.
cc_headers_only = rule(
implementation = _cc_headers_only_impl,
attrs = {"dep": attr.label(mandatory = True, providers = [CcInfo])},
)
4 changes: 4 additions & 0 deletions compiler-plugin/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,7 @@ kotlinx.rpc.plugin.internalDevelopment=true

# set to true when building IDE compiler plugin artifacts
kotlinx.rpc.forIdeBuild=false

# enable code sharing between similar native targets:
# https://www.jetbrains.com/help/kotlin-multiplatform-dev/multiplatform-share-on-platforms.html
kotlin.mpp.enableCInteropCommonization=true
Loading
Loading