Skip to content

Commit

Permalink
[language binding] add c-api and java-api
Browse files Browse the repository at this point in the history
  • Loading branch information
PikachuHy committed Feb 2, 2024
1 parent 4d39ade commit ed268be
Show file tree
Hide file tree
Showing 16 changed files with 275 additions and 51 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
3 changes: 3 additions & 0 deletions .github/workflows/macos_bazel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 2 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
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);
}

}
19 changes: 19 additions & 0 deletions binding/java/pscm_java_binding.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "pscm_c_api.h"
#include <jni.h>
#include <string>

extern "C" JNIEXPORT jlong JNICALL Java_dev_pscm_PSCMScheme_createScheme(JNIEnv *env, jobject /* this */) {
auto scm = pscm_create_scheme();
return (jlong)scm;
}

extern "C" JNIEXPORT jstring JNICALL Java_dev_pscm_PSCMScheme_evalSchemeCode(JNIEnv *env, jobject /* this
*/
,
jlong scm, jstring code) {
auto p = (void *)scm;
auto c_str = env->GetStringUTFChars(code, nullptr);
auto ret = pscm_eval(p, c_str);
auto s = pscm_to_string(ret);
return env->NewStringUTF(s);
}
26 changes: 26 additions & 0 deletions binding/java/test/PSCMSchemeTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package test;
import static org.junit.Assert.assertEquals;

import dev.pscm.PSCMScheme;
import org.junit.Test;

public class PSCMSchemeTest {

static {
System.loadLibrary("pscm-jni");
}

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

@Test
public void testAdd() {
PSCMScheme scm = new PSCMScheme();
String ret = scm.eval("(+ 2 3)");
assertEquals("should return 5 when calculate (+ 2 3)", "5", ret);
}
}
6 changes: 6 additions & 0 deletions docs/cn/how_to_build_pscm.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ Note: don't
use `bazel mobile-install //android/app/src/main:app --android_crosstool_top=@androidndk//:toolchain --fat_apk_cpu=arm64-v8a`,
which may cause app crash

- launch pscm android app

```
adb shell am start -n dev.pscm.android/dev.pscm.android.MainActivity
```

- build pscm ios app

```
Expand Down
Loading

0 comments on commit ed268be

Please sign in to comment.