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 29 void main(String[] args) { 30 31 /* 32 * ./ 33 * +--build/ All jars, native libs and executables 34 * | +--cmake-build-debug/ All intermediate cmake artifacts 35 * | 36 * +--stage/ 37 * | +--repo/ All downloaded maven assets 38 * | | 39 * | +--jextract/ All jextracted files 40 * | | +--opencl 41 * | | +--opengl 42 * | | +--cuda 43 * | 44 * +--hat * Note maven style layout 45 * | +--src/main/java 46 * | | +--hat/ 47 * | | 48 * | +--src/main/test 49 * | +--hat/ 50 * | 51 * +--backends 52 * | +--java 53 * | | +--mt (*) 54 * | | +--seq (*) 55 * | +--jextracted 56 * | | +--opencl (*) 57 * | +--ffi 58 * | | +--opencl (*) 59 * | | +--ptx (*) 60 * | | +--mock (*) 61 * | | +--spirv (*) 62 * | | +--cuda (*) 63 * | | +--hip (*) 64 * | 65 * +--examples 66 * | +--mandel (*) 67 * | +--squares (*) 68 * | +--heal (*) 69 * | +--life (*) 70 * | +--violajones (*) 71 * 72 */ 73 74 var hatDir = DirEntry.current(); 75 var hatCoreDir = hatDir.existingDir("hat"); 76 var backends = hatDir.existingDir("backends"); 77 var examples = hatDir.existingDir("examples"); 78 var stageDir = hatDir.buildDir("stage").create(); 79 var jextractDir = stageDir.buildDir("jextract").create(); 80 var buildDir = BuildDir.of(hatDir.path("build")).create(); 81 var cmakeBuildDir = buildDir.cMakeBuildDir("cmake-build-debug"); 82 83 var extractedOpenCLJar = buildDir.jarFile("jextracted-opencl.jar"); 84 var extractedOpenGLJar = buildDir.jarFile("jextracted-opengl.jar"); 85 86 var opencl = Capabilities.OpenCL.of(); 87 var opengl = Capabilities.OpenGL.of(); 88 var cuda = Capabilities.CUDA.of(); 89 var hip = Capabilities.HIP.of(); 90 var jextract = Capabilities.JExtract.of(); 91 var cmake = Capabilities.CMake.of(); 92 93 Capabilities capabilities = Capabilities.of(opencl, opengl, cuda, hip, jextract, cmake); 94 95 if (cmake.available()) { 96 cmake.probe(buildDir, capabilities); 97 } 98 capabilities.capabilities().forEach(fw -> println((fw.available() ? "we have " : "no ") + fw.name)); 99 var verbose = false; 100 101 102 if (jextract.available()) { 103 if (opencl.available()) { 104 if (!extractedOpenCLJar.exists()) { 105 var openclSource = jextractDir.sourceDir("opencl"); 106 if (!openclSource.exists()) { 107 jextract(jextract.executable, $ -> { 108 $ 109 .verbose(verbose) 110 .output(jextractDir) 111 .target_package(openclSource.fileName()); 112 switch (os) { 113 case OS.Mac mac -> { 114 $ 115 .compile_flag("-F" + opencl.appLibFrameworks() + "/System/library/Frameworks") 116 .library(mac.frameworkLibrary("OpenCL")) 117 //.library(Path.of(opencl.lib())) 118 .header(Path.of(opencl.includeDir()).resolve("Headers/opencl.h")); 119 } 120 case OS.Linux linux -> { 121 } 122 default -> throw new RuntimeException("Unsupported OS: " + os); 123 } 124 }); 125 } 126 jar(jar -> { 127 jar 128 .jar(extractedOpenCLJar) 129 .javac(javac -> javac.source(24).source_path(openclSource)); 130 } 131 ); 132 } 133 } else { 134 println("This platform does not have OpenCL"); 135 } 136 137 if (opengl.available()) { 138 if (!extractedOpenGLJar.exists()) { 139 var openglSource = jextractDir.sourceDir("opengl"); 140 if (!openglSource.exists()) { 141 jextract(jextract.executable, $ -> { $ 142 .verbose(verbose) 143 .output(jextractDir) 144 .target_package(openglSource.fileName()); 145 switch (os) { 146 case OS.Mac mac -> { $ 147 .compile_flag("-F" + opengl.appLibFrameworks() + "/System/library/Frameworks") 148 //.library(opengl.lib("GLUT"),opengl.lib("OpenGL")) 149 .library(mac.frameworkLibrary("GLUT"), mac.frameworkLibrary("OpenGL")) 150 .header(mac.frameworkHeader("GLUT", "glut.h")); 151 } 152 case OS.Linux linux -> { 153 } 154 default -> throw new RuntimeException("Unsupported OS: " + os); 155 } 156 }); 157 } 158 jar(jar -> jar 159 .jar(extractedOpenGLJar) 160 .javac(javac -> javac.source(24).source_path(openglSource)) 161 ); 162 } 163 } else { 164 println("This platform does not have OpenGL"); 165 } 166 167 168 if (cuda.available()) { 169 170 } else { 171 println("This platform does not have CUDA"); 172 } 173 } 174 var hatJavacOpts = javacBuilder(javacBuilder -> {javacBuilder 175 .enable_preview() 176 .add_modules("jdk.incubator.code") 177 .add_exports( 178 "java.base", 179 List.of( 180 "jdk.internal", 181 "jdk.internal.vm.annotation" 182 ), 183 "ALL-UNNAMED" 184 ) 185 .source(24); 186 }); 187 188 var hatJarOptions = jarBuilder(jarBuilder -> jarBuilder 189 .verbose(verbose) 190 ); 191 var hatJarFile = buildDir.jarFile("hat-1.0.jar"); 192 jar(jar -> jar 193 .copy(hatJarOptions) 194 .jar(hatJarFile) 195 .maven_style_root(hatCoreDir) 196 .javac(javac -> javac.copy(hatJavacOpts)) 197 ); 198 199 200 // Here we create all backend jars. 201 var ffiBackends = backends.existingDir("ffi"); 202 ffiBackends 203 .subDirs(backend -> !backend.matches("^.*(spirv|hip|shared|target|.idea)$")) 204 .forEach(backend -> { 205 var jarFile = buildDir.jarFile("hat-backend-ffi-" + backend.fileName() + "-1.0.jar"); 206 println(jarFile.fileName()); 207 jar(jar -> jar.copy(hatJarOptions) 208 .jar(jarFile) 209 .maven_style_root(backend) 210 .javac(javac -> javac.copy(hatJavacOpts).class_path(hatJarFile)) 211 ); 212 }); 213 214 // Here we create all java backend jars. 215 var javaBackends = backends.existingDir("java"); 216 javaBackends 217 .subDirs(backend -> !backend.matches("^.*(target|.idea)$")) 218 .forEach(backend -> { 219 var jarFile = buildDir.jarFile("hat-backend-java-" + backend.fileName() + "-1.0.jar"); 220 println(jarFile.fileName()); 221 jar(jar -> jar 222 .copy(hatJarOptions) 223 .jar(jarFile) 224 .dir_list(backend.dir("src/main/resources")) 225 //.maven_style_root(backend) 226 ); 227 }); 228 229 230 // here we create the example jars 231 examples 232 .subDirs(example -> !example.matches("^.*(experiments|nbody|target|.idea)$")) 233 .forEach(example -> { 234 var jarFile = buildDir.jarFile("hat-example-" + example.fileName() + "-1.0.jar"); 235 println(jarFile.fileName()); 236 jar(jar -> jar.copy(hatJarOptions) 237 .jar(jarFile) 238 .maven_style_root(example) 239 .javac(javac -> javac.copy(hatJavacOpts).class_path(hatJarFile)) 240 .manifest(manifest -> manifest 241 .main_class(example.fileName() + ".Main") 242 ) 243 ); 244 }); 245 246 if (jextract.available() && opencl.available() && opengl.available()) { 247 var example = examples.dir("nbody"); 248 var jarFile = buildDir.jarFile("hat-example-" + example.fileName() + "-1.0.jar"); 249 println(jarFile.fileName()); 250 jar(jar -> jar.copy(hatJarOptions) 251 .jar(jarFile) 252 .maven_style_root(example) 253 .javac(javac -> javac.copy(hatJavacOpts).class_path(hatJarFile, extractedOpenCLJar, extractedOpenGLJar)) 254 ); 255 } 256 257 if (cmake.available()) { 258 if (!cmakeBuildDir.exists()) { 259 cmake($ -> $ 260 .source_dir(ffiBackends) 261 .build_dir(cmakeBuildDir) 262 .copy_to(buildDir) 263 ); 264 } 265 cmake($ -> $ 266 .build(cmakeBuildDir) 267 ); 268 } else { 269 println("No cmake available so we did not build ffi backend shared libs"); 270 } 271 272 273 } 274