From 9e97ef11f1550eadda85571671f23de94cedfd55 Mon Sep 17 00:00:00 2001 From: Jiri Date: Mon, 13 Sep 2021 10:59:14 +0200 Subject: [PATCH 1/3] Separated native and java profiles in pom.xml By default, both profiles are activated. (nothig == -Pjava,natives You can run -Pjava if you wish to build only java part (eg call from make) -Pnatives can not be run alone. I had left headers generation in java part for several reasons: - it is javac call - it would require duplication of maven-compile rplugin declaration (move of javc -h configuration) - once the crosscompilation is added, that would require another triplication f maven compiler plugin and duplication of java -h configuration --- pom.xml | 78 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 30 deletions(-) diff --git a/pom.xml b/pom.xml index e16c7bb..05d71a6 100644 --- a/pom.xml +++ b/pom.xml @@ -63,6 +63,52 @@ + + + natives + + true + + + + + org.codehaus.mojo + exec-maven-plugin + 3.0.0 + + + compile-cpp + + exec + + process-classes + + gcc + + -v + -shared + -fPIC + -I${java.includes}/include + -I${java.includes}/include/linux + -I/usr/lib64/ + -I/usr/include/criu + -I${project.build.directory}/native/javah + -lcriu + -o${project.build.outputDirectory}/libJigawatts.so + ${project.basedir}/src/main/cpp/com_redhat_jigawatts_Jigawatts.cpp + + + + + + + + + + java + + true + @@ -101,36 +147,6 @@ - - org.codehaus.mojo - exec-maven-plugin - 3.0.0 - - - compile-cpp - - exec - - process-classes - - gcc - - -v - -shared - -fPIC - -I${java.includes}/include - -I${java.includes}/include/linux - -I/usr/lib64/ - -I/usr/include/criu - -I${project.build.directory}/native/javah - -lcriu - -o${project.build.outputDirectory}/libJigawatts.so - ${project.basedir}/src/main/cpp/com_redhat_jigawatts_Jigawatts.cpp - - - - - org.apache.maven.plugins maven-shade-plugin @@ -173,4 +189,6 @@ + + From eb91a5944046d1dce8ae86fb1254a708a38e150b Mon Sep 17 00:00:00 2001 From: Jiri Date: Mon, 13 Sep 2021 11:06:29 +0200 Subject: [PATCH 2/3] Reformated pom.xml to acomodate profile indentation This is intentional separate chnage, otherwise the refactoring form previous commit will be unreadable --- pom.xml | 260 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 131 insertions(+), 129 deletions(-) diff --git a/pom.xml b/pom.xml index 05d71a6..d316c36 100644 --- a/pom.xml +++ b/pom.xml @@ -48,147 +48,149 @@ Jigawatts - UTF-8 - ${env.JAVA_HOME} + UTF-8 + ${env.JAVA_HOME} - + - + org.junit.jupiter junit-jupiter-engine 5.7.0 test - + - - - natives - - true - - - - - org.codehaus.mojo - exec-maven-plugin - 3.0.0 - - - compile-cpp - - exec - - process-classes + + + natives + + true + + + + + org.codehaus.mojo + exec-maven-plugin + 3.0.0 + + + compile-cpp + + exec + + process-classes + + gcc + + -v + -shared + -fPIC + -I${java.includes}/include + -I${java.includes}/include/linux + -I/usr/lib64/ + -I/usr/include/criu + -I${project.build.directory}/native/javah + -lcriu + -o${project.build.outputDirectory}/libJigawatts.so + ${project.basedir}/src/main/cpp/com_redhat_jigawatts_Jigawatts.cpp + + + + + + + + + + + java + + true + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 8 + 8 + 8 + + + + header-generation + process-sources + + compile + + + + -h + ${project.build.directory}/native/javah + + + com/redhat/jigawatts/Jigawatts.java + + + + + + + maven-surefire-plugin + 3.0.0-M5 + + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + jigawatts + package + + shade + + + jigawatts + + + + + + maven-clean-plugin + 3.1.0 - gcc - - -v - -shared - -fPIC - -I${java.includes}/include - -I${java.includes}/include/linux - -I/usr/lib64/ - -I/usr/include/criu - -I${project.build.directory}/native/javah - -lcriu - -o${project.build.outputDirectory}/libJigawatts.so - ${project.basedir}/src/main/cpp/com_redhat_jigawatts_Jigawatts.cpp - + + + src/test/resources + + jigawatts/* + 1* + + false + + - - - - - - - - java - - true - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - 8 - 8 - 8 - - - - header-generation - process-sources - - compile - - - - -h - ${project.build.directory}/native/javah - - - com/redhat/jigawatts/Jigawatts.java - - - - - - - maven-surefire-plugin - 3.0.0-M5 - - - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.2.4 - - - jigawatts - package - - shade - + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.2.0 - jigawatts - - - - - maven-clean-plugin - 3.1.0 - - - - src/test/resources - - jigawatts/* - 1* - - false - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.2.0 - - - - - - - + + + + + From 2e4feaaa114004b4c185310b9760db6b15f8ec93 Mon Sep 17 00:00:00 2001 From: Jiri Date: Mon, 13 Sep 2021 13:34:40 +0200 Subject: [PATCH 3/3] Enabled creation of portable release with crosscompiled natives Default mvn run is not changed, the mvn -Pjava,crosscompile, will create (on properly set up system, documented) crosscompiled natives for criu-able arches. Thus instead of libJigawatts.so, there appeare libJigawatts_aarch64.so, libJigawatts_ppc64le.so and libJigawatts_x86_64.so. Library loading schema was adapted toconsider this. On long run, all direct gcc calls have to be replaced by confiure and make calls for both native and crosscompile profiles. Eg: ./configure --build x86_64-pc-linux-gnu --host aarch64-linux-gnu CC=aarch64-linux-gnu-gcc LDFLAGS="-static" CFLAGS="--sysroot=/var/lib/mock/fedora-35-aarch64/root/" for aarch64c static cross compile or ./configure && make for dynamic local build The exact cross compler is necessary, otherwise configure may fallback to direct gcc *without* proper crosscompiler set up. --- pom.xml | 101 ++++++++++++++++++ .../com/redhat/jigawatts/LibraryLoader.java | 42 +++++++- .../redhat/jigawatts/LibraryLoaderTest.java | 17 ++- 3 files changed, 151 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index d316c36..a6792ad 100644 --- a/pom.xml +++ b/pom.xml @@ -105,6 +105,107 @@ + + crosscompile + + + + org.codehaus.mojo + exec-maven-plugin + 3.0.0 + + + cross-compile-cpp-aarch64 + + exec + + process-classes + + + aarch64-linux-gnu-gcc + + + -v + -shared + + + --sysroot=/var/lib/mock/fedora-35-aarch64/root/ + -fPIC + -I${java.includes}/include + -I${java.includes}/include/linux + -I/usr/lib64/ + -I/usr/include/criu + -I${project.build.directory}/native/javah + -Lcriu + -o${project.build.outputDirectory}/libJigawatts_aarch64.so + ${project.basedir}/src/main/cpp/com_redhat_jigawatts_Jigawatts.cpp + + + + + + cross-compile-cpp-ppc64le + + exec + + process-classes + + + ppc64le-linux-gnu-gcc + + + -v + -shared + + + --sysroot=/var/lib/mock/fedora-35-ppc64le/root/ + -fPIC + -I${java.includes}/include + -I${java.includes}/include/linux + -I/usr/lib64/ + -I/usr/include/criu + -I${project.build.directory}/native/javah + -Lcriu + -o${project.build.outputDirectory}/libJigawatts_ppc64le.so + ${project.basedir}/src/main/cpp/com_redhat_jigawatts_Jigawatts.cpp + + + + + + + cross-compile-cpp-x86_64 + + exec + + process-classes + + + gcc + + -v + -shared + + + --sysroot=/var/lib/mock/fedora-35-x86_64/root/ + -fPIC + -I${java.includes}/include + -I${java.includes}/include/linux + -I/usr/lib64/ + -I/usr/include/criu + -I${project.build.directory}/native/javah + -Lcriu + -o${project.build.outputDirectory}/libJigawatts_x86_64.so + ${project.basedir}/src/main/cpp/com_redhat_jigawatts_Jigawatts.cpp + + + + + + + + + java diff --git a/src/main/java/com/redhat/jigawatts/LibraryLoader.java b/src/main/java/com/redhat/jigawatts/LibraryLoader.java index 1963079..f5a4dee 100644 --- a/src/main/java/com/redhat/jigawatts/LibraryLoader.java +++ b/src/main/java/com/redhat/jigawatts/LibraryLoader.java @@ -13,7 +13,31 @@ class LibraryLoader { + private static String getInternalArchedLibrarySuffix() { + if (getPropertyOrVar(LIBRARY_ARCH_PROP, false) != null) { + return getPropertyOrVar(LIBRARY_ARCH_PROP, false); + } + final String suffixDelimiter = "_"; //intentionally here, so LIBRARY_ARCH_PROP can get rid of it + if (System.getProperty("os.arch").equals("amd64")) { + return suffixDelimiter + "x86_64"; + } else if (System.getProperty("os.arch").equals("aarch64") || System.getProperty("os.arch").startsWith("arm")) { + return suffixDelimiter + "aarch64"; + } else if (System.getProperty("os.arch").equals("ppc64le") || System.getProperty("os.arch").startsWith("ppc64")) { + return suffixDelimiter + "aarch64"; + } else { + return null; + } + } + + private static URL getInternalArchedLibrary() { + String libraryName = System.mapLibraryName("Jigawatts" + getInternalArchedLibrarySuffix()); + return Jigawatts.class.getClassLoader().getResource(libraryName); + } + private static URL getInternalLibrary() { + if (getInternalArchedLibrary() != null) { + return getInternalArchedLibrary(); + } String libraryName = System.mapLibraryName("Jigawatts"); return Jigawatts.class.getClassLoader().getResource(libraryName); } @@ -46,7 +70,7 @@ private static void jigaLog(String s) { logPath.toFile().createNewFile(); } Files.write(logPath, ("[" + new Date().toString() + "] " + s + "\n").getBytes(), StandardOpenOption.APPEND); - } catch (Exception ex){ + } catch (Exception ex) { ex.printStackTrace(); } } @@ -54,22 +78,29 @@ private static void jigaLog(String s) { } private static String getPropertyOrVar(String s) { + return getPropertyOrVar(s, true); + } + + private static String getPropertyOrVar(String s, boolean trimToNull) { String prop = System.getProperty(s); if (prop != null) { - return trimToNull(prop); + return trimToNull(prop, trimToNull); } - return trimToNull(System.getenv(propertyToVar(s))); + return trimToNull(System.getenv(propertyToVar(s)), trimToNull); } static String propertyToVar(String s) { return s.toUpperCase().replace(".", "_"); } - static String trimToNull(String s) { + static String trimToNull(String s, boolean reallyTrim) { if (s == null) { return null; } s = s.trim(); + if (!reallyTrim) { + return s; + } if (s.isEmpty()) { return null; } @@ -126,6 +157,7 @@ private static void loadSystemLib() { throw new RuntimeException(lib + " library not found on java.library.path/LD_LIBRARY_PATH!"); } + private static final String LIBRARY_ARCH_PROP = "jigawatts.library.arch"; private static final String LIBRARY_TARGETFILE_PROP = "jigawatts.library.targetfile"; private static final String LIBRARY_EXTERNAL_PROP = "jigawatts.library"; private static final String VERBOSE_PROP = "jigawatts.verbose"; @@ -163,6 +195,8 @@ static void sayHello() { System.out.println("Native library loaded!"); System.out.println("If jigawatts is packed with embedded dynamic library, it is used in advance. If it is missing, the system library is searched for."); System.out.println("To change the loading of native bits you can use following properties/variables. Property is used with priority."); + System.out.println(" * In release jar, native library for ppc64le, aarch64 and x86_64 is packed, and used with priority. You can chnage the detected arch by:"); + System.out.println(" " + PROP + LIBRARY_ARCH_PROP + "/" + VAR + propertyToVar(LIBRARY_ARCH_PROP) + " (ignored if not existing, now " + System.getProperty("os.arch") + ")"); System.out.println(" * The internal library will be unpacked and loaded from given file. If given file exists, it is not overwritten"); System.out.println(" " + PROP + LIBRARY_TARGETFILE_PROP + "/" + VAR + propertyToVar(LIBRARY_TARGETFILE_PROP) + ": " + getInternalLibraryExtractedFile()); System.out.println(" * The internal library will not be used, given file will be used"); diff --git a/src/test/java/com/redhat/jigawatts/LibraryLoaderTest.java b/src/test/java/com/redhat/jigawatts/LibraryLoaderTest.java index 4698548..4c7481e 100644 --- a/src/test/java/com/redhat/jigawatts/LibraryLoaderTest.java +++ b/src/test/java/com/redhat/jigawatts/LibraryLoaderTest.java @@ -6,11 +6,18 @@ public class LibraryLoaderTest { @Test - public void testTrimToNull(){ - Assertions.assertNull(LibraryLoader.trimToNull(null)); - Assertions.assertNull(LibraryLoader.trimToNull("")); - Assertions.assertNull(LibraryLoader.trimToNull(" ")); - Assertions.assertEquals("hi!", LibraryLoader.trimToNull(" hi! ")); + public void testTrimToNull() { + Assertions.assertNull(LibraryLoader.trimToNull(null, true)); + Assertions.assertNull(LibraryLoader.trimToNull("", true)); + Assertions.assertNull(LibraryLoader.trimToNull(" ", true)); + Assertions.assertEquals("hi!", LibraryLoader.trimToNull(" hi! ", true)); + } + + public void testTrimToWithouNUll() { + Assertions.assertNull(LibraryLoader.trimToNull(null, false)); + Assertions.assertEquals("", LibraryLoader.trimToNull("", false)); + Assertions.assertEquals("", LibraryLoader.trimToNull(" ", false)); + Assertions.assertEquals("hi!", LibraryLoader.trimToNull(" hi! ", false)); } @Test