From 121cf1343ba3df44e771bbc22046a5dc29684bc0 Mon Sep 17 00:00:00 2001 From: digitalsmile Date: Thu, 27 Mar 2025 10:54:31 +0300 Subject: [PATCH 1/9] Fix issue with return types, added some docs and support for maven. --- annotation-processor-test/gradle.properties | 3 +- .../gpio/functions/LibcFunctionTests.java | 16 ++++++ .../{FunctionTest.java => LibcFunctions.java} | 9 +--- .../digitalsmile/gpio/libcurl/Libcurl.java | 2 +- .../digitalsmile/gpio/libvlc/LibVLC.java | 2 +- .../github/digitalsmile/NativeProcessor.java | 4 +- .../composers/ContextComposer.java | 19 ++++++- .../composers/FunctionComposer.java | 52 ++++++++++++++----- .../functions/FunctionOptions.java | 4 +- .../function/NativeManualFunction.java | 7 +++ 10 files changed, 89 insertions(+), 29 deletions(-) create mode 100644 annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/functions/LibcFunctionTests.java rename annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/functions/{FunctionTest.java => LibcFunctions.java} (81%) diff --git a/annotation-processor-test/gradle.properties b/annotation-processor-test/gradle.properties index d04e9b2..7a91b2d 100644 --- a/annotation-processor-test/gradle.properties +++ b/annotation-processor-test/gradle.properties @@ -1 +1,2 @@ -systemProp.version=6.2.0-39 \ No newline at end of file +systemProp.version=6.8.0-52-generic +systemProp.gcc-version=11 \ No newline at end of file diff --git a/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/functions/LibcFunctionTests.java b/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/functions/LibcFunctionTests.java new file mode 100644 index 0000000..ea4a688 --- /dev/null +++ b/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/functions/LibcFunctionTests.java @@ -0,0 +1,16 @@ +package io.github.digitalsmile.gpio.functions; + +import io.github.digitalsmile.annotation.NativeMemoryException; +import org.junit.jupiter.api.Test; + +public class LibcFunctionTests { + + @Test + public void testOpenRead() throws NativeMemoryException { + var file = new LibcFunctionsNative(); + var osRelease = file.open("/etc/os-release", 0); + var buffer = file.read(osRelease, new byte[1024], 1024); + System.out.println(new String(buffer)); + file.close(); + } +} diff --git a/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/functions/FunctionTest.java b/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/functions/LibcFunctions.java similarity index 81% rename from annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/functions/FunctionTest.java rename to annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/functions/LibcFunctions.java index b6d7c75..9e20949 100644 --- a/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/functions/FunctionTest.java +++ b/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/functions/LibcFunctions.java @@ -1,15 +1,10 @@ package io.github.digitalsmile.gpio.functions; -import io.github.digitalsmile.annotation.NativeMemory; import io.github.digitalsmile.annotation.function.*; import io.github.digitalsmile.annotation.NativeMemoryException; -import io.github.digitalsmile.annotation.library.NativeFunction; -import io.github.digitalsmile.annotation.library.NativeMemoryLibrary; import io.github.digitalsmile.annotation.types.interfaces.NativeMemoryLayout; -import java.util.List; - -public interface FunctionTest { +public interface LibcFunctions { @NativeManualFunction(name = "ioctl", useErrno = true) int callByValue(int fd, long command, long data) throws NativeMemoryException; @@ -28,7 +23,7 @@ public interface FunctionTest { @NativeManualFunction(name = "close") void close(int fd) throws NativeMemoryException; - @NativeManualFunction(name = "read", useErrno = true) + @NativeManualFunction(name = "read", useErrno = true, nativeReturnType = int.class) byte[] read(int fd, @Returns @ByAddress byte[] buffer, int size) throws NativeMemoryException; @NativeManualFunction(name = "write", useErrno = true) diff --git a/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/libcurl/Libcurl.java b/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/libcurl/Libcurl.java index d4cc901..e253938 100644 --- a/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/libcurl/Libcurl.java +++ b/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/libcurl/Libcurl.java @@ -17,7 +17,7 @@ @NativeMemory(headers = "libcurl/curl/include/curl/curl.h") @NativeMemoryOptions(systemIncludes = { - "/usr/lib/gcc/x86_64-linux-gnu/12/include/" + "/usr/lib/gcc/x86_64-linux-gnu/${gcc-version}/include/" }, debugMode = true, processRootConstants = true) @Structs({ @Struct(name = "CURL", javaName = "CurlInstance") diff --git a/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/libvlc/LibVLC.java b/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/libvlc/LibVLC.java index 14f898c..acb614e 100644 --- a/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/libvlc/LibVLC.java +++ b/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/libvlc/LibVLC.java @@ -16,7 +16,7 @@ @NativeMemory(headers = "libvlc/vlc/include/vlc/vlc.h") @NativeMemoryOptions( includes = "libvlc/vlc/include", - systemIncludes = "/usr/lib/gcc/x86_64-linux-gnu/12/include/", + systemIncludes = "/usr/lib/gcc/x86_64-linux-gnu/${gcc-version}/include/", debugMode = true ) @Structs diff --git a/annotation-processor/src/main/java/io/github/digitalsmile/NativeProcessor.java b/annotation-processor/src/main/java/io/github/digitalsmile/NativeProcessor.java index 153bdec..6f2ae38 100644 --- a/annotation-processor/src/main/java/io/github/digitalsmile/NativeProcessor.java +++ b/annotation-processor/src/main/java/io/github/digitalsmile/NativeProcessor.java @@ -298,7 +298,7 @@ private void processFunctions(Element rootElement, List functionElement var parameterNode = new ParameterNode(variableName, node, returns != null, byAddress); parameters.add(parameterNode); } - var functionOptions = new FunctionOptions(instance.name(), instance.isAlreadyLoaded(), instance.useErrno()); + var functionOptions = new FunctionOptions(instance.name(), instance.isAlreadyLoaded(), instance.useErrno(), OriginalType.of(instance.nativeReturnType())); var functionNode = new FunctionNode(functionElement.getSimpleName().toString(), functionOptions, returnNode, parameters, functionElement.getTypeParameters()); nodes.add(functionNode); var libraryFileName = instance.library(); @@ -398,7 +398,7 @@ private List getHeaderPaths(String... headerFiles) throws ValidationExcept } private File calculatePath(File directory) { - if (directory.isDirectory() && directory.getName().equals("build")) { + if (directory.isDirectory() && (directory.getName().equals("build") || directory.getName().equals("target"))) { return directory.getParentFile(); } return calculatePath(directory.getParentFile()); diff --git a/annotation-processor/src/main/java/io/github/digitalsmile/composers/ContextComposer.java b/annotation-processor/src/main/java/io/github/digitalsmile/composers/ContextComposer.java index 9d98b72..e1ed749 100644 --- a/annotation-processor/src/main/java/io/github/digitalsmile/composers/ContextComposer.java +++ b/annotation-processor/src/main/java/io/github/digitalsmile/composers/ContextComposer.java @@ -68,8 +68,8 @@ public String compose(String packageName, String javaName, Map parameters.add(CodeBlock.builder().add("$T.$L", ValueLayout.class, primitiveTypeMapping.valueLayoutName()).build()); case ObjectOriginalType _, ArrayOriginalType _ -> { @@ -81,6 +81,21 @@ public String compose(String packageName, String javaName, Map throw new IllegalStateException("Unexpected value: " + returnType); } + } else { + if (!returnType.carrierClass().equals(void.class)) { + switch (returnType) { + case PrimitiveOriginalType primitiveTypeMapping -> + parameters.add(CodeBlock.builder().add("$T.$L", ValueLayout.class, primitiveTypeMapping.valueLayoutName()).build()); + case ObjectOriginalType _, ArrayOriginalType _ -> { + if (returnNode.getNodeType().isEnum()) { + parameters.add(CodeBlock.builder().add("$T.JAVA_INT", ValueLayout.class).build()); + } else { + parameters.add(CodeBlock.builder().add("$T.ADDRESS", ValueLayout.class).build()); + } + } + default -> throw new IllegalStateException("Unexpected value: " + returnType); + } + } } for (ParameterNode parameterNode : functionNode.functionParameters()) { var node = parameterNode.nativeMemoryNode(); diff --git a/annotation-processor/src/main/java/io/github/digitalsmile/composers/FunctionComposer.java b/annotation-processor/src/main/java/io/github/digitalsmile/composers/FunctionComposer.java index c5f9cb3..150f901 100644 --- a/annotation-processor/src/main/java/io/github/digitalsmile/composers/FunctionComposer.java +++ b/annotation-processor/src/main/java/io/github/digitalsmile/composers/FunctionComposer.java @@ -116,26 +116,50 @@ public String compose(String packageName, String originalName, List + methodBody.addStatement("var callResult = ($T) $T.$L.invoke($L)", + functionNode.returnNode().getNodeType().isEnum() ? int.class : MemorySegment.class, + context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", ")); + default -> methodBody.addStatement("var callResult = ($T) $T.$L.invoke($L)", + returnType.carrierClass(), + context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", ")); + } + } + } } else { - if (returnType.carrierClass().equals(void.class)) { - methodBody.addStatement("$T.$L.invoke($L)", context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", ")); + if (options.useErrno()) { + methodBody.addStatement("var capturedState = context.allocate(CAPTURED_STATE_LAYOUT)"); + methodBody.addStatement("var callResult = ($T) $T.$L.invoke(capturedState, $L)", options.nativeReturnType().carrierClass(), context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", ")); + methodBody.addStatement("processError(callResult, capturedState, $S, $L)", functionNode.functionName(), CodeBlock.join(arguments, ", ")); } else { - switch (returnType) { - case ArrayOriginalType _, ObjectOriginalType _ -> - methodBody.addStatement("var callResult = ($T) $T.$L.invoke($L)", - functionNode.returnNode().getNodeType().isEnum() ? int.class : MemorySegment.class, - context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", ")); - default -> methodBody.addStatement("var callResult = ($T) $T.$L.invoke($L)", - returnType.carrierClass(), - context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", ")); + if (returnType.carrierClass().equals(void.class)) { + methodBody.addStatement("$T.$L.invoke($L)", context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", ")); + } else { + switch (returnType) { + case ArrayOriginalType _, ObjectOriginalType _ -> + methodBody.addStatement("var callResult = ($T) $T.$L.invoke($L)", + functionNode.returnNode().getNodeType().isEnum() ? int.class : MemorySegment.class, + context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", ")); + default -> methodBody.addStatement("var callResult = ($T) $T.$L.invoke($L)", + returnType.carrierClass(), + context, nativeFunctionNames.get(functionNode), CodeBlock.join(arguments, ", ")); + } } } } + + if (!returnType.carrierClass().equals(void.class) && functionNode.functionParameters().stream().noneMatch(ParameterNode::returns)) { if (returnType instanceof ObjectOriginalType) { if (returnType.carrierClass().equals(String.class)) { diff --git a/annotation-processor/src/main/java/io/github/digitalsmile/functions/FunctionOptions.java b/annotation-processor/src/main/java/io/github/digitalsmile/functions/FunctionOptions.java index 011c532..e1b8086 100644 --- a/annotation-processor/src/main/java/io/github/digitalsmile/functions/FunctionOptions.java +++ b/annotation-processor/src/main/java/io/github/digitalsmile/functions/FunctionOptions.java @@ -1,4 +1,6 @@ package io.github.digitalsmile.functions; -public record FunctionOptions(String nativeFunctionName, boolean isAlreadyLoaded, boolean useErrno) { +import io.github.digitalsmile.headers.mapping.OriginalType; + +public record FunctionOptions(String nativeFunctionName, boolean isAlreadyLoaded, boolean useErrno, OriginalType nativeReturnType) { } diff --git a/annotation/src/main/java/io/github/digitalsmile/annotation/function/NativeManualFunction.java b/annotation/src/main/java/io/github/digitalsmile/annotation/function/NativeManualFunction.java index 284e8d9..b80f623 100644 --- a/annotation/src/main/java/io/github/digitalsmile/annotation/function/NativeManualFunction.java +++ b/annotation/src/main/java/io/github/digitalsmile/annotation/function/NativeManualFunction.java @@ -89,4 +89,11 @@ * @return true if use errno/strerr */ boolean useErrno() default false; + + /** + * Native return type, as described in function docs. + * + * @return native function return type + */ + Class nativeReturnType() default Void.class; } From 813d06b8898fba07af07b728d854fc05182edb27 Mon Sep 17 00:00:00 2001 From: digitalsmile Date: Thu, 27 Mar 2025 11:04:39 +0300 Subject: [PATCH 2/9] Fix build --- .github/workflows/gradle.yml | 3 ++- annotation-processor-test/gradle.properties | 2 +- .../io/github/digitalsmile/gpio/types/all/GPIOTypesAll.java | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index d236903..276c203 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -42,7 +42,8 @@ jobs: cd annotation-processor-test/src/test/resources/libvlc && git clone --depth 1 https://github.com/videolan/vlc.git - name: Getting linux header version for tests run: | - echo "headerVersion=$(uname -r)" >> "$GITHUB_ENV" + echo "linux-version=$(uname -r)" >> "$GITHUB_ENV" + echo "gcc-version=$(ls /usr/lib/gcc/x86_64-linux-gnu/)" >> "$GITHUB_ENV" - name: Change wrapper permissions run: chmod +x ./gradlew - name: Build Gradle diff --git a/annotation-processor-test/gradle.properties b/annotation-processor-test/gradle.properties index 7a91b2d..d7fdd8a 100644 --- a/annotation-processor-test/gradle.properties +++ b/annotation-processor-test/gradle.properties @@ -1,2 +1,2 @@ -systemProp.version=6.8.0-52-generic +systemProp.linux-version=6.8.0-52-generic systemProp.gcc-version=11 \ No newline at end of file diff --git a/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/types/all/GPIOTypesAll.java b/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/types/all/GPIOTypesAll.java index 7ac82f3..287acf0 100644 --- a/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/types/all/GPIOTypesAll.java +++ b/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/types/all/GPIOTypesAll.java @@ -6,7 +6,7 @@ import io.github.digitalsmile.annotation.structure.Structs; import io.github.digitalsmile.annotation.structure.Unions; -@NativeMemory(headers = "/usr/src/linux-headers-${version}/include/uapi/linux/gpio.h") +@NativeMemory(headers = "/usr/src/linux-headers-${linux-version}/include/uapi/linux/gpio.h") @NativeMemoryOptions( processRootConstants = true ) From 78cb1b1a37ea0bc0722818fe61d4be9745379961 Mon Sep 17 00:00:00 2001 From: digitalsmile Date: Thu, 27 Mar 2025 11:14:22 +0300 Subject: [PATCH 3/9] Fix build --- .github/workflows/gradle.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 276c203..4ebb665 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -42,8 +42,7 @@ jobs: cd annotation-processor-test/src/test/resources/libvlc && git clone --depth 1 https://github.com/videolan/vlc.git - name: Getting linux header version for tests run: | - echo "linux-version=$(uname -r)" >> "$GITHUB_ENV" - echo "gcc-version=$(ls /usr/lib/gcc/x86_64-linux-gnu/)" >> "$GITHUB_ENV" + echo "linux-version=$(uname -r)" >> "$GITHUB_ENV" && echo "gcc-version=$(ls /usr/lib/gcc/x86_64-linux-gnu/)" >> "$GITHUB_ENV" - name: Change wrapper permissions run: chmod +x ./gradlew - name: Build Gradle From 1118097062ad8514fc2e8d682c37f3864ee052c2 Mon Sep 17 00:00:00 2001 From: digitalsmile Date: Thu, 27 Mar 2025 11:19:33 +0300 Subject: [PATCH 4/9] Fix build --- .github/workflows/gradle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 4ebb665..0a0b927 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -42,7 +42,7 @@ jobs: cd annotation-processor-test/src/test/resources/libvlc && git clone --depth 1 https://github.com/videolan/vlc.git - name: Getting linux header version for tests run: | - echo "linux-version=$(uname -r)" >> "$GITHUB_ENV" && echo "gcc-version=$(ls /usr/lib/gcc/x86_64-linux-gnu/)" >> "$GITHUB_ENV" + echo "linux-version=$(uname -r)" >> "$GITHUB_ENV" && echo -n "gcc-version=$(ls /usr/lib/gcc/x86_64-linux-gnu/)" >> "$GITHUB_ENV" - name: Change wrapper permissions run: chmod +x ./gradlew - name: Build Gradle From d35bff56bc8946d16db7fa46cf6e664daf37cbec Mon Sep 17 00:00:00 2001 From: digitalsmile Date: Fri, 28 Mar 2025 08:51:31 +0300 Subject: [PATCH 5/9] Fix build --- .github/workflows/gradle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 0a0b927..f710277 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -42,7 +42,7 @@ jobs: cd annotation-processor-test/src/test/resources/libvlc && git clone --depth 1 https://github.com/videolan/vlc.git - name: Getting linux header version for tests run: | - echo "linux-version=$(uname -r)" >> "$GITHUB_ENV" && echo -n "gcc-version=$(ls /usr/lib/gcc/x86_64-linux-gnu/)" >> "$GITHUB_ENV" + echo "linux-version=$(uname -r)" >> "$GITHUB_ENV" && echo "gcc-version=11" >> "$GITHUB_ENV" - name: Change wrapper permissions run: chmod +x ./gradlew - name: Build Gradle From 0dbb3f82757780b4454adfcd258329264c31d53f Mon Sep 17 00:00:00 2001 From: digitalsmile Date: Fri, 28 Mar 2025 08:54:39 +0300 Subject: [PATCH 6/9] Fix build --- .github/workflows/gradle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index f710277..c9eafdd 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -47,4 +47,4 @@ jobs: run: chmod +x ./gradlew - name: Build Gradle run: | - ./gradlew build -Dversion=$headerVersion + ./gradlew build -Dlinux-version=$linux-version -Dgcc-version=$gcc-version From af603d692e51d490b91765fa6f975dd9d43019ae Mon Sep 17 00:00:00 2001 From: digitalsmile Date: Fri, 28 Mar 2025 08:56:48 +0300 Subject: [PATCH 7/9] Fix build --- .github/workflows/gradle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index c9eafdd..2032c89 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -42,7 +42,7 @@ jobs: cd annotation-processor-test/src/test/resources/libvlc && git clone --depth 1 https://github.com/videolan/vlc.git - name: Getting linux header version for tests run: | - echo "linux-version=$(uname -r)" >> "$GITHUB_ENV" && echo "gcc-version=11" >> "$GITHUB_ENV" + echo "linux-version=$(uname -r)" >> "$GITHUB_ENV" && echo "gcc-version=12" >> "$GITHUB_ENV" - name: Change wrapper permissions run: chmod +x ./gradlew - name: Build Gradle From 53f1fc98e99f627587b103951bae193cda92885b Mon Sep 17 00:00:00 2001 From: digitalsmile Date: Fri, 28 Mar 2025 09:02:01 +0300 Subject: [PATCH 8/9] Fix build --- .../java/io/github/digitalsmile/gpio/types/custom/GPIOTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/types/custom/GPIOTest.java b/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/types/custom/GPIOTest.java index dd3afc8..4523b79 100644 --- a/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/types/custom/GPIOTest.java +++ b/annotation-processor-test/src/test/java/io/github/digitalsmile/gpio/types/custom/GPIOTest.java @@ -7,7 +7,7 @@ import io.github.digitalsmile.annotation.structure.Structs; import io.github.digitalsmile.annotation.structure.Unions; -@NativeMemory(headers = "/usr/src/linux-headers-${version}/include/uapi/linux/gpio.h") +@NativeMemory(headers = "/usr/src/linux-headers-${linux-version}/include/uapi/linux/gpio.h") @NativeMemoryOptions( processRootConstants = true ) From f579eb0e7e2f2e4fe750e3ce749e6651d6af8e97 Mon Sep 17 00:00:00 2001 From: digitalsmile Date: Fri, 28 Mar 2025 09:04:17 +0300 Subject: [PATCH 9/9] Fix build --- .github/workflows/gradle.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 2032c89..e83fb3e 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -42,9 +42,9 @@ jobs: cd annotation-processor-test/src/test/resources/libvlc && git clone --depth 1 https://github.com/videolan/vlc.git - name: Getting linux header version for tests run: | - echo "linux-version=$(uname -r)" >> "$GITHUB_ENV" && echo "gcc-version=12" >> "$GITHUB_ENV" + echo "linuxVersion=$(uname -r)" >> "$GITHUB_ENV" && echo "gccVersion=12" >> "$GITHUB_ENV" - name: Change wrapper permissions run: chmod +x ./gradlew - name: Build Gradle run: | - ./gradlew build -Dlinux-version=$linux-version -Dgcc-version=$gcc-version + ./gradlew build -Dlinux-version=$linuxVersion -Dgcc-version=$gccVersion