1 /* vim: set ft=java: 2 * 3 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 import static bldr.Bldr.*; 28 import static java.lang.System.*; 29 30 void main(String[] args) { 31 32 /* 33 * ./ 34 * +--build/ All jars, native libs and executables 35 * | +--cmake-build-debug/ All intermediate cmake artifacts 36 * | 37 * +--stage/ 38 * | +--repo/ All downloaded maven assets 39 * | | 40 * | +--jextract/ All jextracted files 41 * | | +--opencl 42 * | | +--opengl 43 * | | +--cuda 44 * | 45 * +--hat-core * Note maven style layout 46 * | +--src/main/java 47 * | | +--hat/ 48 * | | 49 * | +--src/main/test 50 * | +--hat/ 51 * | 52 * +--backends 53 * | +--java 54 * | | +--mt (*) 55 * | | +--seq (*) 56 * | +--jextracted 57 * | | +--opencl (*) 58 * | +--ffi 59 * | | +--opencl (*) 60 * | | +--ptx (*) 61 * | | +--mock (*) 62 * | | +--spirv (*) 63 * | | +--cuda (*) 64 * | | +--hip (*) 65 * | 66 * +--examples 67 * | +--mandel (*) 68 * | +--squares (*) 69 * | +--heal (*) 70 * | +--life (*) 71 * | +--violajones (*) 72 * 73 */ 74 75 var dir = DirEntry.current(); 76 var hatCoreDir = dir.existingDir("hat-core"); 77 var backends = dir.existingDir("backends"); 78 var examples = dir.existingDir("examples"); 79 var wrapsDir = dir.existingDir("wrap"); 80 var stageDir = dir.buildDir("stage").create(); 81 var buildDir = BuildDir.of(dir.path("build")).create(); 82 var cmakeBuildDir = buildDir.cMakeBuildDir("cmake-build-debug"); 83 84 var openclCapability = Capabilities.OpenCL.of(); 85 var openglCapability = Capabilities.OpenGL.of(); 86 var cudaCapability = Capabilities.CUDA.of(); 87 var hipCapability = Capabilities.HIP.of(); 88 var jextractCapability = Capabilities.JExtract.of();// or Capability.JExtract.of(Path.of("/my/jextract-22/bin/jextract")); 89 var cmakeCapability = Capabilities.CMake.of(); 90 91 Capabilities capabilities = Capabilities.of(openclCapability, openglCapability, cudaCapability, hipCapability, jextractCapability, cmakeCapability); 92 93 if (cmakeCapability.available()) { 94 cmakeCapability.probe(buildDir, capabilities); 95 } 96 97 capabilities.capabilities().forEach(fw -> out.print( "["+fw.name + (fw.available() ? "\u2714" : "\u2715") +"]")); 98 out.println(); 99 100 var verbose = false; 101 var wrapJar= buildDir.jarFile("hat-wrap-1.0.jar"); 102 var clWrapJar= buildDir.jarFile("hat-clwrap-1.0.jar"); 103 var glWrapJar= buildDir.jarFile("hat-glwrap-1.0.jar"); 104 var cuWrapJar= buildDir.jarFile("hat-cuwrap-1.0.jar"); 105 var hatJar = buildDir.jarFile("hat-core-1.0.jar"); 106 107 var hatJavacOpts = javacBuilder($ -> $ 108 .enable_preview() 109 .add_modules("jdk.incubator.code") 110 .add_exports_to_all_unnamed("java.base", "jdk.internal", "jdk.internal.vm.annotation") 111 .current_source() 112 ); 113 114 var hatJarOptions = jarBuilder($ -> $ 115 .verbose(verbose) 116 ); 117 jar(hatJarOptions, jar -> jar 118 .jarFile(hatJar) 119 .maven_style_root(hatCoreDir) 120 .javac(hatJavacOpts, javac -> { 121 }) 122 ); 123 124 jar(jar -> jar 125 .jarFile(wrapJar) 126 .maven_style_root(wrapsDir.dir("wrap")) 127 .javac(javac -> javac.current_source()) 128 ); 129 130 if (jextractCapability.available()) { 131 if (openclCapability.available()) { 132 if (!openclCapability.jarFile(buildDir).exists()) { 133 if (!openclCapability.stage(stageDir).exists()) { 134 jextract(jextractCapability.executable, $ -> $ .verbose(verbose) .capability(openclCapability,stageDir)); 135 }else{ 136 out.println("Using previously extracted "+openclCapability.stage(buildDir).fileName()); 137 } 138 jar(jar -> jar 139 .jarFile(openclCapability.jarFile(buildDir)) 140 .javac(javac -> javac.current_source().source_path(SourceDir.of(openclCapability.stage(stageDir).path()))) 141 142 ); 143 }else{ 144 out.println("Using existing extracted "+openclCapability.jarFile(buildDir).fileName()); 145 } 146 jar(jar -> jar 147 .jarFile(clWrapJar) 148 .maven_style_root(wrapsDir.dir("clwrap")) 149 .javac(javac -> javac.current_source().class_path(wrapJar,hatJar, openclCapability.jarFile(buildDir))) 150 ); 151 } else { 152 out.println("This platform does not have OpenCL"); 153 } 154 155 if (openglCapability.available()) { 156 if (!openglCapability.jarFile(buildDir).exists()) { 157 if (!openglCapability.stage(stageDir).exists()) { 158 jextract(jextractCapability, $ -> $ .verbose(verbose) .capability(openglCapability, stageDir)); 159 }else{ 160 out.println("Using previously extracted "+openglCapability.stage(buildDir).fileName()); 161 } 162 jar(jar -> jar 163 .jarFile(openglCapability.jarFile(buildDir)) 164 .javac(javac -> javac.current_source().source_path(SourceDir.of(openglCapability.stage(stageDir).path()))) 165 ); 166 }else{ 167 out.println("Using existing extracted "+openglCapability.jarFile(buildDir).fileName()); 168 } 169 jar(jar -> jar 170 .jarFile(glWrapJar) 171 .maven_style_root(wrapsDir.dir("glwrap")) 172 .javac(javac -> javac 173 .current_source() 174 .exclude(javaSrc -> javaSrc.matches("^.*/wrap/glwrap/GLCallbackEventHandler\\.java$")) 175 //.exclude(javaSrc -> javaSrc.matches("^.*/wrap/glwrap/GLFuncEventHandler\\.java$")) 176 .class_path(wrapJar, openglCapability.jarFile(buildDir)) 177 ) 178 ); 179 } else { 180 out.println("This platform does not have OpenGL"); 181 } 182 183 184 if (cudaCapability.available()) { 185 186 } else { 187 out.println("This platform does not have CUDA"); 188 } 189 } 190 191 var backendJars = new ArrayList<bldr.Bldr.JarFile>(); 192 193 194 // Here we create all ffi-backend jars. 195 var ffiBackends = backends.existingDir("ffi"); 196 ffiBackends.subDirs() 197 .filter(backend -> backend.failsToMatch("^.*(spirv|hip|shared|target|.idea)$")) 198 .forEach(backend -> { 199 var ffiBackendJarFile = buildDir.jarFile("hat-backend-ffi-" + backend.fileName() + "-1.0.jar"); 200 backendJars.add(ffiBackendJarFile); 201 out.println(ffiBackendJarFile.fileName()); 202 jar(hatJarOptions, jar -> jar 203 .jarFile(ffiBackendJarFile) 204 .maven_style_root(backend) 205 .javac(hatJavacOpts, javac -> javac.class_path(hatJar)) 206 ); 207 }); 208 209 // Here we create jextracted-backend jars. 210 var jextractedBackends = backends.existingDir("jextracted"); 211 var jextractedBackendSharedDir = jextractedBackends.dir("shared"); 212 out.println("Shared jextracted "+jextractedBackendSharedDir.path()); 213 var jextractedSharedBackendJar=buildDir.jarFile("hat-backend-jextracted-shared-1.0.jar"); 214 backendJars.add(jextractedSharedBackendJar); 215 var jextractedBackendSharedResult = jar(hatJarOptions, jar -> jar 216 .jarFile(jextractedSharedBackendJar) 217 .maven_style_root(jextractedBackendSharedDir) 218 .javac(hatJavacOpts, javac -> javac.verbose(verbose) 219 .class_path(hatJar) 220 ) 221 ); 222 223 if (openclCapability.available()){ 224 var jextractedBackendOpenCLDir = jextractedBackends.dir("opencl"); 225 out.println("OpenCL jextracted "+jextractedBackendOpenCLDir.path()); 226 var jextractedOpenCLBackendJar = buildDir.jarFile("hat-backend-jextracted-opencl-1.0.jar"); 227 backendJars.add(jextractedOpenCLBackendJar); 228 jar(hatJarOptions, jar -> jar 229 .jarFile(jextractedOpenCLBackendJar) 230 .maven_style_root(jextractedBackendOpenCLDir) 231 .javac(hatJavacOpts, javac -> javac.verbose(verbose) 232 .class_path(hatJar, openclCapability.jarFile(buildDir), jextractedBackendSharedResult ) 233 ) 234 ); 235 } 236 237 238 // Here we create all java backend jars. 239 backends.existingDir("java") 240 .subDirs() 241 .filter(backend -> backend.failsToMatch("^.*(target|.idea)$")) 242 .forEach(backend -> { 243 var backendJavaJar = buildDir.jarFile("hat-backend-java-" + backend.fileName() + "-1.0.jar"); 244 out.println(backendJavaJar.fileName()); 245 backendJars.add(backendJavaJar); 246 jar(hatJarOptions, jar -> jar 247 .jarFile(backendJavaJar) 248 .dir_list(backend.dir("src/main/resources")) 249 ); 250 }); 251 252 backendJars.forEach(j->out.println(" backend "+j.path())); 253 254 255 // here we create the example jars 256 examples.subDirs() 257 .filter(example -> example.failsToMatch("^.*(experiments|nbody|life|target|.idea)$")) 258 .forEach(example -> { 259 var exampleJarFile = buildDir.jarFile("hat-example-" + example.fileName() + "-1.0.jar"); 260 out.println(exampleJarFile.fileName()); 261 jar(hatJarOptions, jar -> jar 262 .jarFile(exampleJarFile) 263 .maven_style_root(example) 264 .javac(hatJavacOpts, javac -> javac.class_path(hatJar)) 265 .manifest(manifest -> manifest .main_class(example.fileName() + ".Main")) 266 ); 267 }); 268 269 270 if (jextractCapability.available() && openclCapability.available()) { 271 var example = examples.dir("life"); 272 var exampleJarFile = buildDir.jarFile("hat-example-" + example.fileName() + "-1.0.jar"); 273 out.println(exampleJarFile.fileName()); 274 jar(hatJarOptions, jar -> jar 275 .jarFile(exampleJarFile) 276 .maven_style_root(example) 277 .javac(hatJavacOpts, javac -> javac 278 .class_path(hatJar, wrapJar, clWrapJar, openclCapability.jarFile(buildDir), buildDir.jarFile("hat-backend-ffi-opencl-1.0.jar")) 279 ) 280 ); 281 } 282 283 284 if (jextractCapability.available() && openclCapability.available() && openglCapability.available()) { 285 var example = examples.dir("nbody"); 286 var exampleJarFile = buildDir.jarFile("hat-example-" + example.fileName() + "-1.0.jar"); 287 out.println(exampleJarFile.fileName()); 288 jar(hatJarOptions, jar -> jar 289 .jarFile(exampleJarFile) 290 .maven_style_root(example) 291 .javac(hatJavacOpts, javac -> javac 292 .class_path( hatJar, wrapJar, clWrapJar, glWrapJar, openclCapability.jarFile(buildDir), openglCapability.jarFile(buildDir),buildDir.jarFile("hat-backend-ffi-opencl-1.0.jar")) 293 ) 294 ); 295 } 296 297 if (cmakeCapability.available()) { 298 if (!cmakeBuildDir.exists()) { 299 cmake($ -> $ 300 .verbose(verbose) 301 .source_dir(ffiBackends) 302 .build_dir(cmakeBuildDir) 303 .copy_to(buildDir) 304 ); 305 } 306 cmake($ -> $ 307 .build(cmakeBuildDir) 308 ); 309 } else { 310 out.println("No cmake available so we did not build ffi backend shared libs"); 311 } 312 313 } 314