.jar TLS13Server
+# Run (Java 8)
+java -cp .:bcprov-jdk15on-1.69.jar:tongsuo-openjdk-1.1.0-uber.jar TLS13Server
```
+
+## Choosing the Right JAR
+
+We provide two uber JARs:
+
+### Static Uber JAR (Recommended) ⭐
+- **Filename:** `tongsuo-openjdk-{version}-uber.jar`
+- **Size:** ~15-20 MB
+- **Dependencies:** None - all Tongsuo libraries are statically linked
+- **Use when:** You want simplicity and portability
+- **Pros:** Works everywhere, no installation required
+- **Cons:** Larger file size
+
+### Dynamic Uber JAR (Advanced)
+- **Filename:** `tongsuo-openjdk-{version}-dynamic-uber.jar`
+- **Size:** ~1-2 MB
+- **Dependencies:** **Requires Tongsuo installed on your system**
+- **Use when:** You have Tongsuo already installed system-wide
+- **Pros:** Much smaller file size, can use system-optimized libraries
+- **Cons:** Requires system setup
+
+#### Installing Tongsuo (for Dynamic Uber JAR)
+
+**macOS:**
+```bash
+brew install tongsuo
+# Or build from source and install to /usr/local
+```
+
+**Linux:**
+```bash
+# Install to /usr/local/lib
+sudo ldconfig # Update library cache
+```
+
+**Windows:**
+```bash
+# Add Tongsuo bin/ directory to PATH
+```
+
+**For most users, the static uber JAR is recommended** as it requires no system setup.
+
+## Troubleshooting
+
+### InaccessibleObjectException (Java 9+)
+
+**Error:**
+```
+java.lang.reflect.InaccessibleObjectException: Unable to make java.net.InetAddress$InetAddressHolder java.net.InetAddress.holder() accessible
+```
+
+**Solution:** Add the required JVM parameters:
+```bash
+java --add-opens java.base/java.net=ALL-UNNAMED \
+ --add-opens java.base/sun.security.x509=ALL-UNNAMED \
+ -cp .:tongsuo-openjdk-1.1.0-uber.jar \
+ YourClass
+```
+
+Or use the convenience scripts which handle this automatically.
+
+### UnsatisfiedLinkError (Dynamic Uber JAR only)
+
+**Error:**
+```
+java.lang.UnsatisfiedLinkError: ... libssl.3.dylib ... no such file
+```
+
+**Solution:** Install Tongsuo on your system:
+- **macOS:** `brew install tongsuo`
+- **Linux:** Install to `/usr/local/lib` and run `sudo ldconfig`
+
+Or switch to the static uber JAR which has no external dependencies.
+
+### Compilation Errors
+
+If you encounter compilation errors, try forcing recompilation:
+```bash
+./run-client.sh --force-compile tongsuo-openjdk-1.1.0-uber.jar
+./run-server.sh --force-compile bcprov-jdk15on-1.69.jar tongsuo-openjdk-1.1.0-uber.jar
+```
+
+## Complete Example Session
+
+```bash
+cd examples/jce
+
+# 1. Download dependencies
+wget https://github.com/Tongsuo-Project/tongsuo-java-sdk/releases/download/v1.1.0/tongsuo-openjdk-1.1.0-uber.jar
+wget https://repo1.maven.org/maven2/org/bouncycastle/bcprov-jdk15on/1.69/bcprov-jdk15on-1.69.jar
+
+# 2. Start server in one terminal
+./run-server.sh bcprov-jdk15on-1.69.jar tongsuo-openjdk-1.1.0-uber.jar
+
+# 3. In another terminal, run client
+./run-client.sh tongsuo-openjdk-1.1.0-uber.jar
+```
+
+That's it! The scripts handle everything else automatically. 🎉
diff --git a/examples/jce/TLS13Client.java b/examples/jce/TLS13Client.java
index e9ab4cf4b..867a9e081 100644
--- a/examples/jce/TLS13Client.java
+++ b/examples/jce/TLS13Client.java
@@ -29,7 +29,7 @@
public class TLS13Client {
public static void main(String[] args)throws Exception{
String ip = "127.0.0.1";
- int port = 443;
+ int port = 8443;
String ciperSuites = "TLS_SM4_GCM_SM3:TLS_SM4_CCM_SM3";
String caCert = "chain.crt";
@@ -79,28 +79,55 @@ public void checkServerTrusted(X509Certificate[] certs, String authType) throws
}
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(sslSocket.getOutputStream()));
+ System.out.println("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
+ System.out.println("Sending HTTP request to server...");
+ System.out.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
out.write("GET / HTTP/1.0\r\n\r\n");
out.flush();
- System.out.println("client ssl send msessage success...");
+ System.out.println("Request sent successfully");
BufferedInputStream streamReader = new BufferedInputStream(sslSocket.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(streamReader, "utf-8"));
+
+ System.out.println("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
+ System.out.println("Response from server:");
+ System.out.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
+
String line = null;
+ int lineCount = 0;
while((line = bufferedReader.readLine())!= null){
- System.out.println("client receive server data:" + line);
+ System.out.println(line);
+ lineCount++;
+ }
+
+ if (lineCount == 0) {
+ System.out.println("⚠️ No data received from server!");
+ } else {
+ System.out.println("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
+ System.out.println("✅ Successfully received " + lineCount + " lines from server");
+ System.out.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
}
- while (true) {
- try {
- sslSocket.sendUrgentData(0xFF);
- Thread.sleep(1000L);
- System.out.println("client waiting server close");
- } catch (Exception e) {
- bufferedReader.close();
- out.close();
- sslSocket.close();
- }
+ // Close resources in correct order: writers first, then readers, then socket
+ try {
+ out.close();
+ } catch (Exception e) {
+ // Ignore close errors
+ }
+
+ try {
+ bufferedReader.close();
+ } catch (Exception e) {
+ // Ignore close errors
+ }
+
+ try {
+ sslSocket.close();
+ } catch (Exception e) {
+ // Ignore close errors
}
+
+ System.out.println("\nConnection closed");
}
}
diff --git a/examples/jce/TLS13Server.java b/examples/jce/TLS13Server.java
index 2d17d0650..1e4f0ef12 100644
--- a/examples/jce/TLS13Server.java
+++ b/examples/jce/TLS13Server.java
@@ -66,7 +66,7 @@ public static void main(String[] args)throws Exception{
System.out.println("Server SSL context init success...");
SSLServerSocketFactory socketFactory = sslContext.getServerSocketFactory();
- SSLServerSocket serverSocket = (SSLServerSocket)socketFactory.createServerSocket(443);
+ SSLServerSocket serverSocket = (SSLServerSocket)socketFactory.createServerSocket(8443);
if(ciperSuites != null && !"".equals(ciperSuites.trim())){
String[] ciperSuiteArray = ciperSuites.split(":");
@@ -79,24 +79,54 @@ public static void main(String[] args)throws Exception{
while (true){
SSLSocket sslSocket = (SSLSocket)serverSocket.accept();
+ System.out.println("Client connected from: " + sslSocket.getInetAddress());
try {
BufferedReader in = new BufferedReader( new InputStreamReader(sslSocket.getInputStream()) );
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(sslSocket.getOutputStream()));
- String msg = null;
- char[] cbuf = new char[1024];
- int len = 0;
- while((len = in.read(cbuf, 0, 1024)) != -1 ){
- msg = new String(cbuf, 0, len);
- out.write(msg);
- out.flush();
-
- if("Bye".equals(msg)) {
- break;
+
+ // Read the HTTP request
+ String requestLine = null;
+ StringBuilder request = new StringBuilder();
+ String line;
+ while ((line = in.readLine()) != null) {
+ if (requestLine == null) {
+ requestLine = line;
+ }
+ request.append(line).append("\n");
+ // HTTP request ends with an empty line
+ if (line.isEmpty()) {
+ break;
}
- System.out.printf("Received Message --> %s \n", msg);
}
+
+ System.out.println("Received request:");
+ System.out.println(request.toString());
+
+ // Send HTTP response
+ String response = "HTTP/1.0 200 OK\r\n" +
+ "Content-Type: text/html; charset=UTF-8\r\n" +
+ "Content-Length: 116\r\n" +
+ "Connection: close\r\n" +
+ "\r\n" +
+ "\n" +
+ "Tongsuo TLS 1.3 Server\n" +
+ "\n" +
+ "Hello from Tongsuo!
\n" +
+ "TLS 1.3 with SM cipher suites is working! 🎉
\n" +
+ "\n" +
+ "\n";
+
+ out.write(response);
+ out.flush();
+ System.out.println("Response sent successfully");
+
+ // Close the connection
+ sslSocket.close();
+ System.out.println("Connection closed\n");
+
} catch (IOException e){
+ System.err.println("Error handling client connection:");
e.printStackTrace();
}
}
diff --git a/examples/jce/run-client.sh b/examples/jce/run-client.sh
new file mode 100755
index 000000000..d0c384462
--- /dev/null
+++ b/examples/jce/run-client.sh
@@ -0,0 +1,92 @@
+#!/bin/bash
+#
+# Convenience script to run TLS13Client with proper JVM parameters
+#
+
+set -e
+
+# Parse options
+FORCE_COMPILE=0
+while [[ $# -gt 0 ]]; do
+ case $1 in
+ --force-compile|-f)
+ FORCE_COMPILE=1
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+# Detect Java version
+JAVA_VERSION=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2 | cut -d'.' -f1)
+
+# Check if JAR path is provided
+if [ -z "$1" ]; then
+ echo "Usage: $0 [--force-compile] "
+ echo ""
+ echo "Options:"
+ echo " --force-compile, -f Force recompilation even if .class file exists"
+ echo ""
+ echo "Examples:"
+ echo " $0 tongsuo-openjdk-1.1.0-uber.jar"
+ echo " $0 --force-compile tongsuo-openjdk-1.1.0-uber.jar"
+ exit 1
+fi
+
+JAR_PATH="$1"
+
+if [ ! -f "$JAR_PATH" ]; then
+ echo "Error: JAR file not found: $JAR_PATH"
+ exit 1
+fi
+
+echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+echo "Running TLS13Client"
+echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+echo "JAR: $JAR_PATH"
+echo "Java version: $JAVA_VERSION"
+echo ""
+
+# Check if compilation is needed
+NEED_COMPILE=0
+
+if [ $FORCE_COMPILE -eq 1 ]; then
+ echo "🔄 Force compilation requested"
+ NEED_COMPILE=1
+elif [ ! -f "TLS13Client.class" ]; then
+ echo "⚠️ TLS13Client.class not found"
+ NEED_COMPILE=1
+elif [ "TLS13Client.java" -nt "TLS13Client.class" ]; then
+ echo "⚠️ TLS13Client.java is newer than TLS13Client.class"
+ NEED_COMPILE=1
+fi
+
+# Compile if needed
+if [ $NEED_COMPILE -eq 1 ]; then
+ echo "📦 Compiling TLS13Client.java..."
+ javac -cp "$JAR_PATH" TLS13Client.java
+ if [ $? -eq 0 ]; then
+ echo "✅ Compilation successful"
+ else
+ echo "❌ Compilation failed"
+ exit 1
+ fi
+ echo ""
+else
+ echo "✅ TLS13Client.class is up to date"
+ echo ""
+fi
+
+# Run with appropriate parameters based on Java version
+if [ "$JAVA_VERSION" -ge 9 ]; then
+ echo "Using Java 9+ with --add-opens parameters"
+ java --add-opens java.base/java.net=ALL-UNNAMED \
+ --add-opens java.base/sun.security.x509=ALL-UNNAMED \
+ -cp ".:$JAR_PATH" \
+ TLS13Client
+else
+ echo "Using Java 8 (no --add-opens needed)"
+ java -cp ".:$JAR_PATH" TLS13Client
+fi
diff --git a/examples/jce/run-server.sh b/examples/jce/run-server.sh
new file mode 100755
index 000000000..b1482c3b1
--- /dev/null
+++ b/examples/jce/run-server.sh
@@ -0,0 +1,115 @@
+#!/bin/bash
+#
+# Convenience script to run TLS13Server with proper JVM parameters
+#
+
+set -e
+
+# Parse options
+FORCE_COMPILE=0
+while [[ $# -gt 0 ]]; do
+ case $1 in
+ --force-compile|-f)
+ FORCE_COMPILE=1
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+# Detect Java version
+JAVA_VERSION=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2 | cut -d'.' -f1)
+
+# Check if JAR paths are provided
+if [ -z "$1" ] || [ -z "$2" ]; then
+ echo "Usage: $0 [--force-compile] "
+ echo ""
+ echo "Options:"
+ echo " --force-compile, -f Force recompilation even if .class file exists"
+ echo ""
+ echo "Examples:"
+ echo " $0 bcprov-jdk15on-1.69.jar tongsuo-openjdk-1.1.0-uber.jar"
+ echo " $0 --force-compile bcprov-jdk15on-1.69.jar tongsuo-openjdk-1.1.0-uber.jar"
+ echo ""
+ echo "Note: You can download bcprov from:"
+ echo " https://repo1.maven.org/maven2/org/bouncycastle/bcprov-jdk15on/1.69/bcprov-jdk15on-1.69.jar"
+ exit 1
+fi
+
+BCPROV_JAR="$1"
+TONGSUO_JAR="$2"
+
+if [ ! -f "$BCPROV_JAR" ]; then
+ echo "Error: BouncyCastle JAR not found: $BCPROV_JAR"
+ exit 1
+fi
+
+if [ ! -f "$TONGSUO_JAR" ]; then
+ echo "Error: Tongsuo JAR not found: $TONGSUO_JAR"
+ exit 1
+fi
+
+# Check required certificate files
+if [ ! -f "sm2.crt" ] || [ ! -f "sm2.key" ] || [ ! -f "chain.crt" ]; then
+ echo "Error: Required certificate files not found!"
+ echo " - sm2.crt"
+ echo " - sm2.key"
+ echo " - chain.crt"
+ exit 1
+fi
+
+echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+echo "Running TLS13Server"
+echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+echo "BouncyCastle JAR: $BCPROV_JAR"
+echo "Tongsuo JAR: $TONGSUO_JAR"
+echo "Java version: $JAVA_VERSION"
+echo ""
+
+# Check if compilation is needed
+NEED_COMPILE=0
+
+if [ $FORCE_COMPILE -eq 1 ]; then
+ echo "🔄 Force compilation requested"
+ NEED_COMPILE=1
+elif [ ! -f "TLS13Server.class" ]; then
+ echo "⚠️ TLS13Server.class not found"
+ NEED_COMPILE=1
+elif [ "TLS13Server.java" -nt "TLS13Server.class" ]; then
+ echo "⚠️ TLS13Server.java is newer than TLS13Server.class"
+ NEED_COMPILE=1
+fi
+
+# Compile if needed
+if [ $NEED_COMPILE -eq 1 ]; then
+ echo "📦 Compiling TLS13Server.java..."
+ javac -cp "$BCPROV_JAR:$TONGSUO_JAR" TLS13Server.java
+ if [ $? -eq 0 ]; then
+ echo "✅ Compilation successful"
+ else
+ echo "❌ Compilation failed"
+ exit 1
+ fi
+ echo ""
+else
+ echo "✅ TLS13Server.class is up to date"
+ echo ""
+fi
+
+# Run with appropriate parameters based on Java version
+if [ "$JAVA_VERSION" -ge 9 ]; then
+ echo "Using Java 9+ with --add-opens parameters"
+ echo "Server will listen on port 8443..."
+ echo ""
+ java --add-opens java.base/java.net=ALL-UNNAMED \
+ --add-opens java.base/sun.security.x509=ALL-UNNAMED \
+ -cp ".:$BCPROV_JAR:$TONGSUO_JAR" \
+ TLS13Server
+else
+ echo "Using Java 8 (no --add-opens needed)"
+ echo "Server will listen on port 8443..."
+ echo ""
+ java -cp ".:$BCPROV_JAR:$TONGSUO_JAR" TLS13Server
+fi
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 1cc5168dd..999133be9 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-#distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
-distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-7.5-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
+#distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-7.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/openjdk/build.gradle b/openjdk/build.gradle
index d52e38b42..21719d7b2 100644
--- a/openjdk/build.gradle
+++ b/openjdk/build.gradle
@@ -21,7 +21,9 @@ description = 'Tongsuo: OpenJdk'
// about native builds, more of which will migrate in here over time.
enum NativeBuildInfo {
WINDOWS_X86_64("windows", "x86_64"),
+ WINDOWS_AARCH64("windows", "aarch_64"),
LINUX_X86_64("linux", "x86_64"),
+ LINUX_AARCH64("linux", "aarch_64"),
MAC_X86_64("osx", "x86_64") {
String libDir() {
"build.x86"
@@ -258,9 +260,20 @@ publishing.publications.maven {
}
jar.manifest {
+ def gitCommit = 'git rev-parse --short HEAD'.execute().text.trim() ?: 'unknown'
+ def gitBranch = 'git rev-parse --abbrev-ref HEAD'.execute().text.trim() ?: 'unknown'
+ def buildTime = new Date().format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC"))
+
attributes ('Automatic-Module-Name' : 'org.conscrypt',
'Bundle-SymbolicName': 'org.conscrypt',
- '-exportcontents': 'org.conscrypt.*')
+ '-exportcontents': 'org.conscrypt.*',
+ 'Implementation-Title': 'Tongsuo Java SDK',
+ 'Implementation-Version': "${version}",
+ 'Implementation-Vendor': 'Tongsuo',
+ 'Build-Time': buildTime,
+ 'Git-Commit': gitCommit,
+ 'Git-Branch': gitBranch,
+ 'Build-Jdk': System.getProperty('java.version'))
}
dependencies {
@@ -410,9 +423,28 @@ model {
cppCompiler.define "CONSCRYPT_CHECK_ERROR_QUEUE"
}
+ // Add custom compiler flags if provided
+ if (rootProject.hasProperty('cppFlags')) {
+ def flags = rootProject.property('cppFlags').toString().split()
+ cppCompiler.args(flags)
+ System.out.println("Added C++ compiler flags: ${flags}")
+ }
+ if (rootProject.hasProperty('cFlags')) {
+ def flags = rootProject.property('cFlags').toString().split()
+ cppCompiler.args(flags)
+ System.out.println("Added C compiler flags: ${flags}")
+ }
+
linker.args "-O3",
"-fvisibility=hidden",
"-lpthread"
+
+ // Add custom linker flags if provided
+ if (rootProject.hasProperty('ldFlags')) {
+ def flags = rootProject.property('ldFlags').toString().split()
+ linker.args(flags)
+ System.out.println("Added linker flags: ${flags}")
+ }
if (tongsuoDynamic == "1" || tongsuoDynamic == "true") {
linker.args "-L" + libPath,
@@ -502,6 +534,7 @@ model {
// Everything under will be included in the native jar.
into nativeBuild.jarNativeResourcesDir()
}
+
processResources {
dependsOn copyTask
}
@@ -509,6 +542,112 @@ model {
dependsOn copyTask
}
+ // Detect if this is a dynamic build for rpath fixing
+ def tongsuoHome = System.getenv('TONGSUO_HOME')
+ def isDynamicBuild = false
+
+ if (tongsuoHome && new File(tongsuoHome).exists()) {
+ def tongsuoLibDir = new File(tongsuoHome, 'lib')
+ if (tongsuoLibDir.exists()) {
+ // Check for shared library files (indicates dynamic build)
+ if (osdetector.os == 'osx') {
+ isDynamicBuild = tongsuoLibDir.listFiles()?.any { it.name.matches('libssl.*\\.dylib') }
+ } else if (osdetector.os == 'linux') {
+ isDynamicBuild = tongsuoLibDir.listFiles()?.any { it.name.matches('libssl\\.so.*') }
+ } else if (osdetector.os == 'windows') {
+ def tongsyoBinDir = new File(tongsuoHome, 'bin')
+ isDynamicBuild = tongsyoBinDir.exists() && tongsyoBinDir.listFiles()?.any { it.name.matches('libssl-.*\\.dll') }
+ }
+ }
+ }
+
+ // Fix dynamic library paths (rpath) for macOS
+ // Only fix if this is a dynamic build
+ if (osdetector.os == 'osx' && isDynamicBuild) {
+ def fixRpathTask = binary.tasks.taskName("fixRpath")
+ project.tasks.register(fixRpathTask as String) {
+ dependsOn binary.tasks.link
+
+ doLast {
+ def libFile = binary.tasks.link.linkedFile.asFile.get()
+
+ if (tongsuoHome) {
+ // Change absolute paths to @rpath
+ project.exec {
+ executable "install_name_tool"
+ args "-change", "${tongsuoHome}/lib/libssl.3.dylib", "@rpath/libssl.3.dylib", libFile
+ ignoreExitValue = true
+ }
+ project.exec {
+ executable "install_name_tool"
+ args "-change", "${tongsuoHome}/lib/libcrypto.3.dylib", "@rpath/libcrypto.3.dylib", libFile
+ ignoreExitValue = true
+ }
+
+ // Add @loader_path as rpath
+ project.exec {
+ executable "install_name_tool"
+ args "-add_rpath", "@loader_path", libFile
+ ignoreExitValue = true
+ }
+ project.exec {
+ executable "install_name_tool"
+ args "-add_rpath", "@loader_path/.", libFile
+ ignoreExitValue = true
+ }
+
+ // Add system library paths
+ project.exec {
+ executable "install_name_tool"
+ args "-add_rpath", "/usr/local/lib", libFile
+ ignoreExitValue = true
+ }
+ project.exec {
+ executable "install_name_tool"
+ args "-add_rpath", "/opt/homebrew/lib", libFile
+ ignoreExitValue = true
+ }
+ }
+ }
+ }
+ copyTask.configure {
+ dependsOn fixRpathTask
+ }
+ }
+
+ // Fix dynamic library paths (rpath) for Linux
+ // Only fix if this is a dynamic build
+ if (osdetector.os == 'linux' && isDynamicBuild) {
+ def fixRpathTask = binary.tasks.taskName("fixRpath")
+ project.tasks.register(fixRpathTask as String) {
+ dependsOn binary.tasks.link
+
+ doLast {
+ def libFile = binary.tasks.link.linkedFile.asFile.get()
+
+ // Check if patchelf is available
+ try {
+ project.exec {
+ executable "which"
+ args "patchelf"
+ }
+
+ // Set rpath to search in common locations
+ project.exec {
+ executable "patchelf"
+ args "--set-rpath", '$ORIGIN:/usr/local/lib:/usr/lib:/lib', libFile
+ ignoreExitValue = true
+ }
+ } catch (Exception e) {
+ logger.warn("patchelf not found, skipping rpath fix for Linux")
+ }
+ }
+ }
+ copyTask.configure {
+ dependsOn fixRpathTask
+ }
+ }
+
// Now define a task to strip the release binary (linux only)
if (osdetector.os == 'linux' && (!rootProject.hasProperty('nostrip') ||
!rootProject.nostrip.toBoolean())) {