diff --git a/sp-dr-client/java/pom.xml b/sp-dr-client/java/pom.xml index bc39e56..798b40b 100644 --- a/sp-dr-client/java/pom.xml +++ b/sp-dr-client/java/pom.xml @@ -28,6 +28,12 @@ javacpp ${javacpp.version} + + org.junit.jupiter + junit-jupiter-engine + 5.3.1 + test + @@ -165,7 +171,7 @@ eu.atspace.hash.FooLib is the wrapper class --> - -jar ${project.build.directory}/lib/javacpp-${javacpp.version}.jar -o libspdr.so -Xcompiler -L${basedir}/target/classes/spdr/client/linux-x86_64 -Xcompiler -I${basedir}/../lib -classpath target/classes spdr.client.Spdr + -jar ${project.build.directory}/lib/javacpp-${javacpp.version}.jar -Xcompiler -L${basedir}/target/classes/spdr/client/linux-x86_64 -Xcompiler -I${basedir}/../lib -classpath target/classes spdr.client.Spdr diff --git a/sp-dr-client/java/src/main/java/spdr/client/Spdr.java b/sp-dr-client/java/src/main/java/spdr/client/Spdr.java index 9dbf82c..4bdb864 100644 --- a/sp-dr-client/java/src/main/java/spdr/client/Spdr.java +++ b/sp-dr-client/java/src/main/java/spdr/client/Spdr.java @@ -11,13 +11,9 @@ public static class Client extends Pointer { public Client(String host, int port) { allocate(host, port); } private native void allocate(String host, int port); - public native void connect(); - public native void disconnect(); + public native int connect(); + public native int disconnect(); } - public static void main(String[] args) { - Client client = new Client("localhost", 8080); - client.connect(); - client.disconnect(); - } + public static void main(String[] args) {} } diff --git a/sp-dr-client/java/src/test/java/spdr/client/TestSpdr.java b/sp-dr-client/java/src/test/java/spdr/client/TestSpdr.java new file mode 100644 index 0000000..8f2e353 --- /dev/null +++ b/sp-dr-client/java/src/test/java/spdr/client/TestSpdr.java @@ -0,0 +1,16 @@ +package spdr.client; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class TestSpdr { + + @Test + public void testSample() { + Spdr.Client instance = new Spdr.Client("localhost", 8080); + + assertEquals(0, instance.connect()); + assertEquals(0, instance.disconnect()); + } +} \ No newline at end of file diff --git a/sp-dr-client/lib/Makefile b/sp-dr-client/lib/Makefile index 5ea8968..bbc2f27 100644 --- a/sp-dr-client/lib/Makefile +++ b/sp-dr-client/lib/Makefile @@ -1,19 +1,23 @@ CC=g++ -all: webassembly +all: webassembly java python clean: rm -f *.o *.so *.js *.wasm -libspdr.so: spdr.o - $(CC) -shared -o libspdr.so spdr.o - -spdr.o: spdr_client.cpp spdr_client.h - $(CC) -c -fPIC spdr_client.cpp -o spdr.o - webassembly: spdr_client.cpp spdr_client.h em++ spdr_client.cpp --bind -DUSE_EMSCRIPTEN -o spdr.js -java: libspdr.so +java: spdr_client.cpp spdr_client.h + # Build library without support + $(CC) -c -fPIC spdr_client.cpp -o spdr.o + $(CC) -shared -o libspdr.so spdr.o + + # Copy libraries for Maven to use mkdir -p ../java/target/classes/spdr/client/linux-x86_64 - cp libspdr.so ../java/target/classes/spdr/client/linux-x86_64 \ No newline at end of file + cp libspdr.so ../java/target/classes/spdr/client/linux-x86_64 + +python: spdr_client.cpp spdr_client.h + # Build library with boost support + $(CC) -c -fPIC spdr_client.cpp -o spdr.o -Iboost/ -I/usr/include/python3.11 -DUSE_PYTHON + $(CC) -shared -Wl,-soname,libspdr.so -o libspdr.so spdr.o -lpython3.11 -lboost_python311 -Iboost -Lboost/stage/lib \ No newline at end of file diff --git a/sp-dr-client/lib/install_boost.sh b/sp-dr-client/lib/install_boost.sh new file mode 100755 index 0000000..bb90581 --- /dev/null +++ b/sp-dr-client/lib/install_boost.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +PYTHON_HEADERS_PATH="/usr/include/python3.11/" + +if [[ ! -d boost ]]; then + echo "[*] Downloading boost 1.82.0..." + wget https://boostorg.jfrog.io/artifactory/main/release/1.82.0/source/boost_1_82_0.tar.gz + CHECKSUM=$(sha256sum boost_1_82_0.tar.gz | cut -d' ' -f1) + + if [[ ${CHECKSUM} != "66a469b6e608a51f8347236f4912e27dc5c60c60d7d53ae9bfe4683316c6f04c" ]]; then + >&2 echo "[-] ERROR: Wrong checksum" + exit 1 + fi + + echo "[*] Decompressing archive..." + tar xf boost_1_82_0.tar.gz && rm boost_1_82_0.tar.gz + mv boost_* boost +fi + +cd boost + +echo "[*] Building boost...." +./bootstrap.sh --with-python=$(python --version | cut -d' ' -f2) +mkdir -p ../boost_build +CPLUS_INCLUDE_PATH="$CPLUS_INCLUDE_PATH:$PYTHON_HEADERS_PATH" ./b2 --build-dir=../boost_build diff --git a/sp-dr-client/lib/spdr_client.cpp b/sp-dr-client/lib/spdr_client.cpp index 709b55e..6219f14 100644 --- a/sp-dr-client/lib/spdr_client.cpp +++ b/sp-dr-client/lib/spdr_client.cpp @@ -10,11 +10,13 @@ namespace spdr { std::cout << "Client::~Client()" << std::endl; } - void Client::connect() const { + int Client::connect() const { std::cout << "Client::connect()" << std::endl; + return 0; } - void Client::disconnect() const { + int Client::disconnect() const { std::cout << "Client::disconnect()" << std::endl; + return 0; } -} \ No newline at end of file +} diff --git a/sp-dr-client/lib/spdr_client.h b/sp-dr-client/lib/spdr_client.h index 2e96d81..4fca2d4 100644 --- a/sp-dr-client/lib/spdr_client.h +++ b/sp-dr-client/lib/spdr_client.h @@ -9,15 +9,15 @@ namespace spdr { public: explicit Client(const std::string host, const int port); ~Client(); - void connect() const; - void disconnect() const; + int connect() const; + int disconnect() const; private: std::string host; int port; }; } -#ifdef USE_EMSCRIPTEN +#ifdef USE_EMSCRIPTEN // Javascript / WASM bindings #include #include @@ -30,4 +30,18 @@ EMSCRIPTEN_BINDINGS(spdr_client) { } #endif // USE_EMSCRIPTEN +#ifdef USE_PYTHON // Python bindings using Boost::Python +#include + +BOOST_PYTHON_MODULE(libspdr) +{ + using namespace boost::python; + class_("Client", init()) + .def("connect", &spdr::Client::connect) + .def("disconnect", &spdr::Client::disconnect) + ; +} + +#endif // USE_PYTHON + #endif // __SPDR_CLIENT_H__ diff --git a/sp-dr-client/p5/spdr-wrapper.js b/sp-dr-client/p5/spdr-wrapper.js index 319a93d..9b0d04d 100644 --- a/sp-dr-client/p5/spdr-wrapper.js +++ b/sp-dr-client/p5/spdr-wrapper.js @@ -3,6 +3,7 @@ if (!window.p5) { throw new Error('p5 is not loaded'); } +// Disable p5 autolaunch p5.instance = true; // Load the WASM module @@ -21,6 +22,7 @@ script.onload = () => { return new Module.Client(host, port); } + // Enable p5 new p5(); } } diff --git a/sp-dr-client/python/bootstrap.sh b/sp-dr-client/python/bootstrap.sh new file mode 100755 index 0000000..a7fb868 --- /dev/null +++ b/sp-dr-client/python/bootstrap.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +ORIGIN_DIR=$(pwd) + +build_library() { + cd ../lib + make clean + make python + cp libspdr.so ../python/ + make clean + + cd ${ORIGIN_DIR} +} + +run_test() { + LIBRARY_LOCATION=$(pwd) + cd test + PYTHONPATH=${LIBRARY_LOCATION} python main.py + rm ../libspdr.so +} + +case "$1" in + build) + build_library + ;; + + test) + build_library + run_test + ;; +esac \ No newline at end of file diff --git a/sp-dr-client/python/test/main.py b/sp-dr-client/python/test/main.py new file mode 100644 index 0000000..f6b0513 --- /dev/null +++ b/sp-dr-client/python/test/main.py @@ -0,0 +1,9 @@ +import libspdr + +def main(): + instance = libspdr.Client("localhost", 8080) + assert instance.connect() == 0 + assert instance.disconnect() == 0 + +if __name__ == "__main__": + main() \ No newline at end of file