Files
ortools-clone/bazel/swig_java.bzl

221 lines
7.0 KiB
Python
Raw Normal View History

2025-01-10 11:35:44 +01:00
# Copyright 2010-2025 Google LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
2023-01-05 14:49:05 +01:00
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Build definitions for SWIG Java."""
2024-11-15 10:22:39 +01:00
load("@bazel_skylib//lib:paths.bzl", "paths")
2025-07-23 09:05:10 +00:00
load("@rules_cc//cc:cc_library.bzl", "cc_library")
load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
load("@rules_java//java:java_library.bzl", "java_library")
load("@rules_java//java/common:java_common.bzl", "java_common")
def _create_src_jar(ctx, java_runtime_info, input_dir, output_jar):
jar_args = ctx.actions.args()
jar_args.add("cf", output_jar)
jar_args.add_all([input_dir])
ctx.actions.run(
outputs = [output_jar],
inputs = [input_dir],
executable = "%s/bin/jar" % java_runtime_info.java_home,
tools = java_runtime_info.files,
arguments = [jar_args],
mnemonic = "SwigJar",
)
def _java_wrap_cc_impl(ctx):
if len(ctx.files.srcs) != 1:
fail("There must be exactly one *.swig file", attr = "srcs")
swig_src = ctx.files.srcs[0]
outfile = ctx.outputs.outfile
2022-12-30 11:40:33 +01:00
outhdr = ctx.outputs.outhdr
header_sets = [] # depsets of Files
include_path_sets = [] # depsets of strings
# Include headers from deps.
for target in ctx.attr.deps:
cc_context = target[CcInfo].compilation_context
header_sets.append(cc_context.headers)
include_path_sets.append(cc_context.includes)
# Include workspace root in include path for when target is defined in an
# external workspace.
if target.label.workspace_root:
include_path_sets.append(depset([target.label.workspace_root]))
2023-01-02 11:39:58 +01:00
java_files_dir = ctx.actions.declare_directory("java_files")
swig_args = ctx.actions.args()
swig_args.add("-c++")
swig_args.add("-java")
swig_args.add("-package", ctx.attr.package)
swig_args.add_all("-outdir", [java_files_dir], expand_directories = False)
if ctx.attr.swig_opt:
swig_args.add(ctx.attr.swig_opt)
swig_args.add("-o", outfile)
if ctx.attr.module:
swig_args.add("-module", ctx.attr.module)
for include_path in depset(transitive = include_path_sets).to_list():
swig_args.add("-I" + include_path)
swig_args.add(swig_src.path)
2022-12-30 11:40:33 +01:00
generated_c_files = [outfile]
if ctx.attr.use_directors:
generated_c_files.append(outhdr)
# Add swig LIB files.
2024-11-15 10:22:39 +01:00
swig_lib = {"SWIG_LIB": paths.dirname(ctx.files._swig_lib[0].path)}
ctx.actions.run(
2022-12-30 11:40:33 +01:00
outputs = generated_c_files + [java_files_dir],
inputs = depset([swig_src] + ctx.files.swig_includes + ctx.files._swig_lib, transitive = header_sets),
env = swig_lib,
executable = ctx.executable._swig,
arguments = [swig_args],
mnemonic = "SwigCompile",
)
java_runtime = ctx.attr._jdk[java_common.JavaRuntimeInfo]
_create_src_jar(ctx, java_runtime, java_files_dir, ctx.outputs.srcjar)
_java_wrap_cc = rule(
doc = """
Wraps C++ in Java using Swig.
It's expected that the `swig` binary exists in the host's path.
""",
implementation = _java_wrap_cc_impl,
attrs = {
"srcs": attr.label_list(
allow_empty = False,
allow_files = [".swig", ".i"],
flags = ["DIRECT_COMPILE_TIME_INPUT", "ORDER_INDEPENDENT"],
doc = """
A list of one <code>swig</code> source.
""",
),
"deps": attr.label_list(
doc = "C++ dependencies.",
providers = [CcInfo],
),
2022-12-30 11:40:33 +01:00
"java_deps": attr.label_list(
doc = "Java dependencies.",
),
"package": attr.string(
doc = "Package for generated Java.",
mandatory = True,
),
"module": attr.string(doc = "Optional Swig module name."),
"outfile": attr.output(
doc = "Generated C++ output file.",
mandatory = True,
),
2022-12-30 11:40:33 +01:00
"outhdr": attr.output(
doc = "Generated C++ header output file.",
),
"srcjar": attr.output(
doc = "Generated Java source jar.",
mandatory = True,
),
"_jdk": attr.label(
default = Label("@bazel_tools//tools/jdk:current_java_runtime"),
providers = [java_common.JavaRuntimeInfo],
),
"_swig": attr.label(
default = Label("@swig//:swig"),
executable = True,
cfg = "exec",
),
2024-11-15 10:22:39 +01:00
"_swig_lib": attr.label(
default = Label("@swig//:lib_java"),
),
"swig_includes": attr.label_list(
doc = "SWIG includes.",
allow_files = True,
),
"swig_opt": attr.string(doc = "Optional Swig opt."),
2023-01-05 15:06:46 +01:00
"use_directors": attr.bool(doc = "use directors"),
},
)
def java_wrap_cc(
name,
srcs,
package,
deps = [],
2022-12-30 11:40:33 +01:00
java_deps = [],
2023-01-05 15:06:46 +01:00
swig_opt = "",
swig_includes = [],
2022-12-30 11:40:33 +01:00
use_directors = False,
module = None,
visibility = None,
**kwargs):
"""Wraps C++ in Java using Swig.
It's expected that the `swig` binary exists in the host's path.
Args:
name: target name.
srcs: A list of one <code>swig</code> source.
package: package of generated Java files.
deps: C++ deps.
2022-12-30 11:40:33 +01:00
java_deps: Java deps.
module: optional name of Swig module.
2022-12-30 11:40:33 +01:00
swig_opt: optional defines passed to the swig command.
swig_includes: list of swig files included by the current swig file.
use_directors: Boolean flag.
visibility: global visibility of the rule.
**kwargs: extra generic arguments, usually passed to sub-rules.
Generated targets:
{name}: java_library
lib{name}_cc: cc_library
"""
wrapper_name = "_" + name + "_wrapper"
cc_name = name + "_cc"
outfile = name + ".cc"
2022-12-30 11:40:33 +01:00
outhdr = name + ".h"
srcjar = name + ".srcjar"
_java_wrap_cc(
name = wrapper_name,
srcs = srcs,
package = package,
outfile = outfile,
2022-12-30 11:40:33 +01:00
outhdr = outhdr if use_directors else None,
srcjar = srcjar,
deps = deps,
swig_opt = swig_opt,
module = module,
2024-11-15 10:22:39 +01:00
swig_includes = swig_includes,
2022-12-30 11:40:33 +01:00
use_directors = use_directors,
visibility = ["//visibility:private"],
**kwargs
)
cc_library(
name = cc_name,
srcs = [outfile],
2022-12-30 11:40:33 +01:00
hdrs = [outhdr] if use_directors else [],
2024-11-15 10:22:39 +01:00
deps = deps + [Label("@bazel_tools//tools/jdk:jni")],
alwayslink = True,
visibility = visibility,
**kwargs
)
java_library(
name = name,
srcs = [srcjar],
2022-12-30 11:40:33 +01:00
deps = java_deps,
visibility = visibility,
**kwargs
)