Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions MODULE.release.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module(

bazel_dep(name = "platforms", version = "0.0.11")
bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "rules_cc", version = "0.0.16")
bazel_dep(name = "rules_java", version = "8.9.0")
bazel_dep(name = "rules_android", version = "0.7.1")
bazel_dep(name = "bazel_features", version = "1.39.0")
Expand Down
15 changes: 15 additions & 0 deletions examples/nested_module_resources/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
load("@rules_cc//cc:cc_binary.bzl", "cc_binary")
load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_binary", "kt_jvm_library", "kt_jvm_test")

kt_jvm_binary(
Expand Down Expand Up @@ -75,3 +76,17 @@ kt_jvm_test(
"@nested//:printer",
],
)

cc_binary(
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May not be the best place to include this test in the long run, but added it to the module resources sample since these tests provide some assertions around how non-JVM things get linked up into the kt_ targets at runtime.

name = "native_resource_helper",
srcs = ["native/native_resource_helper.cc"],
linkshared = 1,
)

kt_jvm_test(
name = "native_library_test",
srcs = ["NativeLibraryPathTest.kt"],
main_class = "NativeLibraryPathTest",
test_class = "NativeLibraryPathTest",
runtime_deps = [":native_resource_helper"],
)
1 change: 1 addition & 0 deletions examples/nested_module_resources/MODULE.bazel
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module(name = "nested_module_resources")

bazel_dep(name = "rules_cc", version = "0.0.16")
bazel_dep(name = "rules_kotlin", version = "1.9.5")
local_path_override(
module_name = "rules_kotlin",
Expand Down
7 changes: 7 additions & 0 deletions examples/nested_module_resources/NativeLibraryPathTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
object NativeLibraryPathTest {
@JvmStatic
fun main(args: Array<String>) {
System.loadLibrary("native_resource_helper")
println("Loaded native_resource_helper from runtime_deps.")
}
}
1 change: 1 addition & 0 deletions examples/nested_module_resources/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## What This Tests

This example tests **resource path resolution across Bazel module boundaries** when using `resource_strip_prefix`.
It also includes a `kt_jvm_test` that loads a shared native library from `runtime_deps`, so the example fails if `java.library.path` is not wired correctly.

## Problem Statement

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
extern "C" int native_resource_helper_symbol() {
return 0;
}
9 changes: 9 additions & 0 deletions kotlin/internal/jvm/compile.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ load(
"@bazel_skylib//lib:sets.bzl",
_sets = "sets",
)
load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
load(
"@rules_java//java:defs.bzl",
"JavaInfo",
Expand Down Expand Up @@ -818,6 +819,7 @@ def _kt_jvm_produce_output_jar_actions(
deps = compile_deps.deps,
runtime_deps = compile_deps.runtime_deps,
exports = compile_deps.exports,
native_libraries = compile_deps.native_libraries,
neverlink = getattr(ctx.attr, "neverlink", False),
generated_source_jar = generated_source_jar,
generated_class_jar = generated_class_jar,
Expand Down Expand Up @@ -975,6 +977,7 @@ def _run_kt_java_builder_actions(
deps = compile_deps.deps,
runtime_deps = compile_deps.runtime_deps,
exports = compile_deps.exports,
native_libraries = compile_deps.native_libraries,
neverlink = getattr(ctx.attr, "neverlink", False),
)
java_infos.append(kt_java_info)
Expand Down Expand Up @@ -1121,7 +1124,13 @@ def _export_only_providers(ctx, actions, attr, outputs):
output_jar = toolchains.kt.empty_jar,
compile_jar = toolchains.kt.empty_jar,
deps = [_java_info(d) for d in attr.deps],
runtime_deps = [
runtime_dep
for runtime_dep in [_java_info(d) for d in getattr(attr, "runtime_deps", [])]
if runtime_dep != None
],
exports = [_java_info(d) for d in getattr(attr, "exports", [])],
native_libraries = [d[CcInfo] for d in getattr(attr, "runtime_deps", []) if CcInfo in d],
neverlink = getattr(attr, "neverlink", False),
jdeps = output_jdeps,
)
Expand Down
46 changes: 44 additions & 2 deletions kotlin/internal/jvm/impl.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,48 @@ load("//third_party:jarjar.bzl", "jarjar_action")
def _artifact_short_path(artifact):
return artifact.short_path

def _native_library_artifact(library_to_link):
for field in [
"resolved_symlink_dynamic_library",
"dynamic_library",
]:
artifact = getattr(library_to_link, field, None)
if artifact:
return artifact
return None

def _native_library_jvm_flags(ctx, java_info):
native_library_dirs = []
seen_dirs = {}
for library_to_link in java_info.transitive_native_libraries.to_list():
artifact = _native_library_artifact(library_to_link)
if not artifact:
continue

short_path_dir = paths.dirname(artifact.short_path)
if short_path_dir in seen_dirs:
continue

seen_dirs[short_path_dir] = True
native_library_dirs.append(short_path_dir)

if not native_library_dirs:
return []

if is_windows(ctx):
workspace_prefix = ctx.workspace_name + "\\"
java_library_path = ctx.configuration.host_path_separator.join([
"%JAVA_RUNFILES%\\%s%s" % (workspace_prefix, path) if path != "." else "%JAVA_RUNFILES%\\%s" % ctx.workspace_name
for path in native_library_dirs
])
else:
java_library_path = ctx.configuration.host_path_separator.join([
"${RUNPATH}%s" % path if path != "." else "${RUNPATH}"
for path in native_library_dirs
])

return ["-Djava.library.path=%s" % java_library_path]

def _make_providers(ctx, providers, runfiles_targets, transitive_files = depset(order = "default"), executable = None, *additional_providers):
files = [ctx.outputs.jar]
if providers.java.outputs.jdeps:
Expand Down Expand Up @@ -359,7 +401,7 @@ def kt_jvm_binary_impl(ctx):
ctx,
providers.java.transitive_runtime_jars,
ctx.attr.main_class,
jvm_flags,
jvm_flags + _native_library_jvm_flags(ctx, providers.java),
)
if len(ctx.attr.srcs) == 0 and len(ctx.attr.deps) > 0:
fail("deps without srcs is invalid. To add runtime classpath and resources, use runtime_deps.", attr = "deps")
Expand Down Expand Up @@ -425,7 +467,7 @@ def kt_jvm_junit_test_impl(ctx):
jvm_flags = [
"-ea",
"-Dbazel.test_suite=%s" % test_class,
] + jvm_flags,
] + jvm_flags + _native_library_jvm_flags(ctx, providers.java),
is_test = True,
)

Expand Down
8 changes: 7 additions & 1 deletion kotlin/internal/jvm/jvm_deps.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
load("@bazel_skylib//lib:sets.bzl", _sets = "sets")
load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
load(
"@rules_java//java:defs.bzl",
"JavaInfo",
Expand Down Expand Up @@ -60,7 +61,12 @@ def _jvm_deps(ctx, toolchains, associate_deps, deps = [], deps_java_infos = [],
exports = [_java_info(d) for d in exports],
associate_jars = associates.jars,
compile_jars = depset(direct = compile_depset_list_filtered),
runtime_deps = [_java_info(d) for d in runtime_deps],
runtime_deps = [
java_info
for java_info in [_java_info(d) for d in runtime_deps]
if java_info != None
],
native_libraries = [d[CcInfo] for d in runtime_deps if CcInfo in d],
)

jvm_deps_utils = struct(
Expand Down
34 changes: 33 additions & 1 deletion src/test/data/jvm/basic/BUILD
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
load("@rules_cc//cc:cc_binary.bzl", "cc_binary")
load("@rules_java//java:defs.bzl", "java_binary", "java_library")
load("//kotlin:jvm.bzl", "kt_jvm_binary", "kt_jvm_library")
load("//kotlin:jvm.bzl", "kt_jvm_binary", "kt_jvm_library", "kt_jvm_test")

# Copyright 2018 The Bazel Authors. All rights reserved.
#
Expand Down Expand Up @@ -111,6 +112,27 @@ kt_jvm_library(
visibility = ["//src/test/kotlin:__subpackages__"],
)

cc_binary(
name = "native_lib",
srcs = ["native/native_lib.cc"],
linkshared = 1,
)

kt_jvm_binary(
name = "NativeLibraryPathBinary",
srcs = ["native/NativeLibraryPathBinary.kt"],
main_class = "NativeLibraryPathBinaryKt",
runtime_deps = [":native_lib"],
)

kt_jvm_test(
name = "NativeLibraryPathTest",
srcs = ["native/NativeLibraryPathTest.kt"],
test_class = "NativeLibraryPathTest",
runtime_deps = [":native_lib"],
deps = ["@kotlin_rules_maven//:junit_junit"],
)

filegroup(
name = "basic",
srcs = [
Expand All @@ -129,3 +151,13 @@ filegroup(
],
visibility = ["//visibility:public"],
)

filegroup(
name = "basic_test_data",
testonly = 1,
srcs = [
":NativeLibraryPathBinary",
":NativeLibraryPathTest",
],
visibility = ["//visibility:public"],
)
3 changes: 3 additions & 0 deletions src/test/data/jvm/basic/native/NativeLibraryPathBinary.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fun main() {
System.loadLibrary("native_lib")
}
8 changes: 8 additions & 0 deletions src/test/data/jvm/basic/native/NativeLibraryPathTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import org.junit.Test

class NativeLibraryPathTest {
@Test
fun loadsSharedLibraryFromRuntimeDeps() {
System.loadLibrary("native_lib")
}
}
3 changes: 3 additions & 0 deletions src/test/data/jvm/basic/native/native_lib.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
extern "C" int native_lib_symbol() {
return 0;
}
5 changes: 4 additions & 1 deletion src/test/kotlin/io/bazel/kotlin/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ kt_jvm_library(
kt_rules_e2e_test(
name = "KotlinJvmBasicAssertionTest",
srcs = ["KotlinJvmBasicAssertionTest.kt"],
data = ["//src/test/data/jvm/basic"],
data = [
"//src/test/data/jvm/basic",
"//src/test/data/jvm/basic:basic_test_data",
],
)

kt_rules_e2e_test(
Expand Down
12 changes: 12 additions & 0 deletions src/test/kotlin/io/bazel/kotlin/KotlinJvmBasicAssertionTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ class KotlinJvmBasicAssertionTest : KotlinAssertionTestCase("src/test/data/jvm/b
)
}

@Test
fun testNativeLibraryRuntimeDeps() {
assertExecutableRunfileSucceeds(
"NativeLibraryPathBinary",
description = "kt_jvm_binary should load shared libraries from runtime_deps"
)
assertExecutableRunfileSucceeds(
"NativeLibraryPathTest",
description = "kt_jvm_test should load shared libraries from runtime_deps"
)
}

@Test
fun testModuleNaming() {
jarTestCase(
Expand Down
3 changes: 3 additions & 0 deletions src/test/starlark/internal/jvm/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
load(":jvm_deps_tests.bzl", "jvm_deps_test_suite")
load(":kt_jvm_binary_env_test.bzl", "kt_jvm_binary_env_test_suite")
load(":native_libraries_tests.bzl", "native_libraries_test_suite")

jvm_deps_test_suite(name = "jvm_tests")

kt_jvm_binary_env_test_suite(name = "kt_jvm_binary_env_tests")

native_libraries_test_suite(name = "native_libraries_tests")
Loading