Skip to content

Commit

Permalink
[language binding] add c-api, java-api and python-api
Browse files Browse the repository at this point in the history
  • Loading branch information
PikachuHy committed Feb 3, 2024
1 parent 4d39ade commit 1838dc1
Show file tree
Hide file tree
Showing 25 changed files with 470 additions and 52 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/linux_bazel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ jobs:
- name: Test
run: bazel test \:all --test_output=errors

- name: Test Java Binding
run: bazel run //binding/java:pscm_java_api_test

- name: Build Android App
run: bazel build //android/app/src/main:app --android_crosstool_top=@androidndk//:toolchain --fat_apk_cpu=arm64-v8a --config=android

Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/macos_bazel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:

jobs:
build_with_bazel:
runs-on: macos-13
runs-on: macos-14

steps:
- uses: actions/checkout@v3
Expand All @@ -28,6 +28,9 @@ jobs:
- name: Test
run: bazel test \:all --config=macos --test_output=errors

- name: Test Java Binding
run: bazel run //binding/java:pscm_java_api_test

- name: Build with MLIR
run: bazel build \:all --config=macos --define codegen=mlir

Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,5 @@ pscm-build-bin
#coverage
cov/
/build-*

.aswb
9 changes: 9 additions & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
load("version.bzl", "gen_pscm_version_info")
load("test.bzl", "collect_pscm_tests")
load("@llvm-project//mlir:tblgen.bzl", "gentbl_cc_library", "td_library")
load("@pybind11_bazel//:build_defs.bzl", "pybind_extension", "pybind_library")

config_setting(
name = "mlir_codegen",
Expand Down Expand Up @@ -184,3 +185,11 @@ gentbl_cc_library(
td_file = "include/pscm/codegen/mlir/Ops.td",
deps = [":pscm-ops-td-files"],
)

# when import pscm, the pscm.so must in root folder
# TODO: rename pypscm to pscm
pybind_extension(
name = "pypscm",
visibility = ["//visibility:public"],
deps = ["//binding/python:pscm"],
)
60 changes: 59 additions & 1 deletion WORKSPACE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ maven_install(
"androidx.lifecycle:lifecycle-service:2.5.1",
"androidx.lifecycle:lifecycle-viewmodel-savedstate:2.5.1",
"androidx.lifecycle:lifecycle-viewmodel:2.5.1",
"junit:junit:4.12",
],
repositories = [
"https://maven.google.com",
Expand Down Expand Up @@ -246,7 +247,7 @@ new_git_repository(
patches = [
"@dev_pscm//3rd/patch:llvm/fix_build_on_macos_13.patch",
],
remote = "https://github.com/llvm/llvm-project.git"
remote = "https://github.com/llvm/llvm-project.git",
)

load("@llvm-raw//utils/bazel:configure.bzl", "llvm_configure")
Expand Down Expand Up @@ -352,3 +353,60 @@ http_archive(
strip_prefix = "freetype-2.9",
urls = ["https://download.savannah.gnu.org/releases/freetype/freetype-2.9.tar.gz"],
)

# https://thethoughtfulkoala.com/posts/2020/05/16/bazel-hermetic-python.html
# Special logic for building python interpreter with OpenSSL from homebrew.
# See https://devguide.python.org/setup/#macos-and-os-x
_py_configure = """
if [[ "$OSTYPE" == "darwin"* ]]; then
./configure --prefix=$(pwd)/bazel_install --with-openssl=$(brew --prefix openssl)
else
./configure --prefix=$(pwd)/bazel_install
fi
"""

http_archive(
name = "python_interpreter",
build_file_content = """
exports_files(["python_bin"])
filegroup(
name = "files",
srcs = glob(["bazel_install/**"], exclude = ["**/* *"]),
visibility = ["//visibility:public"],
)
""",
patch_cmds = [
"mkdir $(pwd)/bazel_install",
_py_configure,
"make",
"make install",
"ln -s bazel_install/bin/python3 python_bin",
],
sha256 = "5a99f8e7a6a11a7b98b4e75e0d1303d3832cada5534068f69c7b6222a7b1b002",
strip_prefix = "Python-3.10.0",
urls = ["https://www.python.org/ftp/python/3.10.0/Python-3.10.0.tar.xz"],
)

register_toolchains("@dev_pscm//toolchains:my_py_toolchain")

http_archive(
name = "pybind11_bazel",
sha256 = "dc4882b23a617575d0fd822aba88aa4a14133c3d428b5a8fb83d81d03444a475",
strip_prefix = "pybind11_bazel-8889d39b2b925b2a47519ae09402a96f00ccf2b4",
urls = ["https://github.com/pybind/pybind11_bazel/archive/8889d39b2b925b2a47519ae09402a96f00ccf2b4.zip"],
)

http_archive(
name = "pybind11",
build_file = "@pybind11_bazel//:pybind11.BUILD",
sha256 = "c9375b7453bef1ba0106849c83881e6b6882d892c9fae5b2572a2192100ffb8a",
strip_prefix = "pybind11-a54eab92d265337996b8e4b4149d9176c2d428a6",
urls = ["https://github.com/pybind/pybind11/archive/a54eab92d265337996b8e4b4149d9176c2d428a6.tar.gz"],
)

load("@pybind11_bazel//:python_configure.bzl", "python_configure")

python_configure(
name = "local_config_python",
python_interpreter_target = "@python_interpreter//:python_bin",
)
12 changes: 4 additions & 8 deletions android/app/src/main/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,15 @@ android_library(
manifest = "LibraryManifest.xml",
resource_files = glob(["res/**/*"]),
deps = [
":jni_lib",
# ":jni_lib",
"//binding/java:pscm_java_api",
# must depend on cc_library directly
"//binding/java:pscm_java_binding",
"@maven//:androidx_appcompat_appcompat",
"@maven//:androidx_constraintlayout_constraintlayout",
],
)

cc_library(
name = "jni_lib",
srcs = ["cpp/native-lib.cpp"],
copts = ["-std=c++20"],
deps = ["//:pscm"],
)

android_binary(
name = "app",
manifest = "AndroidManifest.xml",
Expand Down
28 changes: 0 additions & 28 deletions android/app/src/main/cpp/native-lib.cpp

This file was deleted.

19 changes: 5 additions & 14 deletions android/app/src/main/java/dev/pscm/android/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import dev.pscm.PSCMScheme;

public class MainActivity extends AppCompatActivity {
private long scm;
private PSCMScheme scm;

static {
System.loadLibrary("app");
}
Expand All @@ -14,20 +16,9 @@ public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// Example of a call to a native method
scm = new PSCMScheme();
TextView tv = (TextView)findViewById(R.id.sample_text);
tv.setText(stringFromJNI());
scm = createScheme();
String ret = evalSchemeCode(scm, "(version)");
String ret = scm.eval("(version)");
tv.setText(ret);
}

/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
public native long createScheme();
public native String evalSchemeCode(long scm, String code);
}
9 changes: 9 additions & 0 deletions binding/c/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
cc_library(
name = "pscm_c_api",
srcs = ["pscm_c_api.cpp"],
hdrs = ["pscm_c_api.h"],
copts = ["-std=c++20"],
implementation_deps = ["//:pscm"],
includes = ["."],
visibility = ["//visibility:public"],
)
27 changes: 27 additions & 0 deletions binding/c/pscm_c_api.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "pscm_c_api.h"
#include <pscm/Scheme.h>
using namespace pscm;

void *pscm_create_scheme() {
return new Scheme();
}

void pscm_destroy_scheme(void *scm) {
auto p = (Scheme *)scm;
delete p;
}

void *pscm_eval(void *scm, const char *code) {
auto p = (Scheme *)scm;
auto ret = p->eval(code);
return new Cell(ret);
}

const char *pscm_to_string(void *value) {
auto p = (Cell *)value;
auto s = p->to_std_string();
char *c_str = new char[s.size() + 1];
strcpy(c_str, s.c_str());
c_str[s.size()] = '\0';
return c_str;
}
8 changes: 8 additions & 0 deletions binding/c/pscm_c_api.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

extern "C" {
void *pscm_create_scheme();
void pscm_destroy_scheme(void *scm);
void *pscm_eval(void *scm, const char *code);
const char *pscm_to_string(void *value);
}
73 changes: 73 additions & 0 deletions binding/java/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
java_library(
name = "pscm_java_api",
srcs = ["dev/pscm/PSCMScheme.java"],
visibility = ["//visibility:public"],
deps = select({
"@platforms//os:android": [],
"//conditions:default": [":pscm-jni"],
}),
)

cc_library(
name = "pscm_java_binding",
srcs = ["pscm_java_binding.cpp"],
copts = ["-std=c++20"],
visibility = ["//visibility:public"],
deps = [
":copy_jni_hdr_lib",
"//binding/c:pscm_c_api",
],
alwayslink = True,
)

cc_binary(
name = "pscm-jni",
linkshared = True,
deps = [":pscm_java_binding"],
)

java_test(
name = "pscm_java_api_test",
srcs = ["test/PSCMSchemeTest.java"],
test_class = "test.PSCMSchemeTest",
deps = [
":pscm_java_api",
"@maven//:junit_junit",
],
)

java_binary(
name = "pscm_java_api_example",
srcs = ["example/PSCMSchemeExample.java"],
main_class = "PSCMSchemeExample",
deps = [
":pscm_java_api",
],
)

genrule(
name = "copy_link_jni_md_header",
srcs = select({
"@platforms//os:macos": ["@bazel_tools//tools/jdk:jni_md_header-darwin"],
"@platforms//os:linux": ["@bazel_tools//tools/jdk:jni_md_header-linux"],
"//conditions:default": [],
}),
outs = ["jni_md.h"],
cmd = "cp -f $< $@",
)

genrule(
name = "copy_link_jni_header",
srcs = ["@bazel_tools//tools/jdk:jni_header"],
outs = ["jni.h"],
cmd = "cp -f $< $@",
)

cc_library(
name = "copy_jni_hdr_lib",
hdrs = [
":copy_link_jni_header",
":copy_link_jni_md_header",
],
includes = ["."],
)
27 changes: 27 additions & 0 deletions binding/java/dev/pscm/PSCMScheme.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package dev.pscm;

public class PSCMScheme {

private long scm = 0;

public PSCMScheme() {
init();
}

public void init() {
if (scm == 0) {
scm = createScheme();
}
}

public String eval(String code) {
return evalSchemeCode(scm, code);
}

/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native long createScheme();
public native String evalSchemeCode(long scm, String code);
}
17 changes: 17 additions & 0 deletions binding/java/example/PSCMSchemeExample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import dev.pscm.PSCMScheme;

public class PSCMSchemeExample {

static {
// load shared library
System.loadLibrary("pscm-jni");
}

public static void main(String args[]) {
System.out.println("Hello World");
PSCMScheme scm = new PSCMScheme();
// eval (version)
String ret = scm.eval("(version)");
System.out.println(ret);
}
}
Loading

0 comments on commit 1838dc1

Please sign in to comment.