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 bldr.Bldr.Capabilities.*; 29 30 void main(String[] argv) { 31 var pomComment = """ 32 Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. 33 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 34 35 This code is free software; you can redistribute it and/or modify it 36 under the terms of the GNU General Public License version 2 only, as 37 published by the Free Software Foundation. Oracle designates this 38 particular file as subject to the "Classpath" exception as provided 39 by Oracle in the LICENSE file that accompanied this code. 40 41 This code is distributed in the hope that it will be useful, but WITHOUT 42 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 43 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 44 version 2 for more details (a copy is included in the LICENSE file that 45 accompanied this code). 46 47 You should have received a copy of the GNU General Public License version 48 2 along with this work; if not, write to the Free Software Foundation, 49 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 50 51 Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 52 or visit www.oracle.com if you need additional information or have any 53 questions. 54 """; 55 56 var hatDir = DirEntry.current(); 57 var hatCore = hatDir.existingDir("hat"); 58 var backends = hatDir.existingDir("backends"); 59 var examples = hatDir.existingDir("examples"); 60 var extractions = hatDir.existingDir("extractions"); 61 var buildDir = hatDir.existingBuildDir("build"); 62 63 var opencl = OpenCL.of(); 64 var opengl = OpenGL.of(); 65 var cuda = CUDA.of(); 66 var hip = HIP.of(); 67 var jextract = JExtract.of(); 68 var cmake = CMake.of(); 69 70 var capabilities = Capabilities.of(opencl, opengl, cuda, hip, jextract, cmake); 71 72 if (cmake.available()) { 73 cmake.probe(buildDir, capabilities); 74 } 75 capabilities.capabilities().forEach(fw -> println((fw.available() ? "we have " : "no ") + fw.name)); 76 77 hatDir.pom(pomComment, pom -> pom 78 .comment("Auto generated by mkpoms") 79 .pom("oracle.code", "hat-root", "1.0") 80 .properties(properties -> properties 81 .property("project.build.sourceEncoding", "UTF-8") 82 .property("hat.root", "${env.PWD}") 83 .property("hat.build", "${hat.root}/build") 84 .property("hat.stage", "${hat.root}/stage") 85 .property("hat.stage.repo", "${hat.stage}/repo") 86 .property("hat.stage.jextract", "${hat.stage}/jextract") 87 .property("mac.app.frameworks", "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks") 88 .property("mac.lib.frameworks", "/System/Library/Frameworks") 89 ) 90 .modules("hat", "extractions", "backends", "examples") 91 .build(build -> build 92 .plugins(plugins -> plugins 93 .compilerPlugin(plugin -> plugin 94 .configuration(configuration -> configuration 95 .compilerArgs( 96 "--add-modules=jdk.incubator.code", 97 "--enable-preview", 98 "--add-exports=java.base/jdk.internal=ALL-UNNAMED", 99 "--add-exports=java.base/jdk.internal.vm.annotation=ALL-UNNAMED" 100 ) 101 .source("24") 102 .target("24") 103 .showDeprecation("true") 104 .failOnError("true") 105 .showWarnings("true") 106 ) 107 ) 108 ) 109 ) 110 ); 111 112 // Now hat/pom.xml 113 hatCore.pom(pomComment, pom -> pom 114 .comment("Auto generated by mkpoms") 115 .jar("oracle.code", "hat", "1.0") 116 .parent("oracle.code", "hat-root", "1.0") 117 .dependsOn("org.junit.jupiter", "junit-jupiter-engine", "5.10.0", "test") 118 .build(build -> build 119 .pluginManagement(pluginManagement -> pluginManagement 120 .plugins(plugins -> plugins 121 .surefirePlugin(plugin -> plugin 122 .configuration(configuration -> configuration 123 .argLine("-enable-preview") 124 ) 125 ) 126 ) 127 ) 128 .plugins(plugins -> plugins 129 .antPlugin(plugin -> plugin 130 .executions(executions -> executions 131 .ant("1", "install", "run", ant -> ant 132 .copy("target/${project.artifactId}-1.0.jar", "${hat.build}") 133 ) 134 ) 135 ) 136 ) 137 ) 138 ); 139 140 // Note that we filter by capability here. So we only create poms (and include modules in parent) if capability is available 141 var extractionDirs = extractions 142 .subDirs(extraction -> !extraction.matches("^.*(target)$")).filter(dir -> capabilities.capabilityIsAvailable(dir.fileName())).toList(); 143 144 extractions.pom(pomComment, pom -> pom 145 .comment("Auto generated by mkpoms") 146 .pom("oracle.code", "hat-extractions", "1.0") 147 .parent("oracle.code", "hat-root", "1.0") 148 .modules(extractionDirs.stream().map(PathHolder::fileName).toList()) 149 .build(build -> build 150 .plugins(plugins -> plugins 151 .antPlugin(plugin -> plugin 152 .executions(executions -> executions 153 .ant("createDir", "compile", "run", ant -> ant 154 .mkdir("${hat.stage.jextract}") 155 .echo("${hat.stage.jextract}/compile_flags.txt", "-F${mac.app.frameworks}") 156 ) 157 ) 158 ) 159 ) 160 161 ) 162 ); 163 164 extractionDirs.forEach(extraction -> extraction 165 .pom(pomComment, examplePom -> examplePom 166 .comment("Auto generated by mkpoms") 167 .pom("oracle.code", "hat-extraction-" + extraction.fileName(), "1.0") 168 .parent("oracle.code", "hat-extractions", "1.0") 169 .build(build -> build 170 .plugins(plugins -> plugins 171 .execPlugin(plugin -> plugin 172 .executions(execution -> execution 173 .execIdPhaseConf("2", "compile", configuration -> configuration 174 .executable("jextract") 175 .workingDirectory("${hat.stage.jextract}") 176 .arguments(arguments -> { 177 arguments 178 .argument("--output").argument("${hat.stage.jextract}") 179 .argument("-t").argument(extraction.fileName()); 180 switch (extraction.fileName()) { 181 case "opencl" -> arguments 182 .argument("-l").argument("${mac.lib.frameworks}/OpenCL.framework/OpenCL") 183 .argument("${mac.app.frameworks}/OpenCL.framework/Headers/opencl.h"); 184 case "opengl" -> arguments 185 .argument("-l").argument("${mac.lib.frameworks}/GLUT.framework/GLUT") 186 .argument("-l").argument("${mac.lib.frameworks}/OpenGL.framework/OpenGL") 187 .argument("${mac.app.frameworks}/GLUT.framework/Headers/glut.h"); 188 default -> 189 throw new IllegalStateException("Unexpected value: " + extraction.fileName()); 190 } 191 }) 192 ) 193 ) 194 ) 195 .antPlugin(plugin -> plugin 196 .executions(executions -> executions 197 .ant("1", "install", "run", ant -> ant 198 .antjar("${hat.stage.jextract}", extraction.fileName(), "${hat.build}/jextracted-" + extraction.fileName() + "-1.0.jar") 199 //.copy("target/jextracted" + extraction.fileName() + "-1.0.jar", "${hat.build}") 200 ) 201 ) 202 ) 203 ) 204 ) 205 ) 206 ); 207 208 var exampleDirs = examples.subDirs(example -> !example.matches("^.*(experiments|target|nbody|.idea)$")).toList(); 209 210 // Here we create examples/pom.xml and nested inside we create each example/*/pom.xml 211 examples.pom(pomComment, examplesPom -> examplesPom 212 .comment("Auto generated by mkpoms") 213 .pom("oracle.code", "hat-examples", "1.0") 214 .parent("oracle.code", "hat-root", "1.0") 215 .dependsOn("oracle.code", "hat", "1.0") 216 .modules(exampleDirs.stream().map(PathHolder::fileName).toList()) 217 ); 218 219 exampleDirs.forEach(example -> example 220 .pom(pomComment, examplePom -> examplePom 221 .comment("Auto generated by mkpoms") 222 .jar("oracle.code", "hat-example-" + example.fileName(), "1.0") 223 .parent("oracle.code", "hat-examples", "1.0") 224 .dependsOn("oracle.code", "hat", "1.0") 225 .build(build -> build 226 .plugins(plugins -> plugins 227 .antPlugin(plugin -> plugin 228 .executions(executions -> executions 229 .ant("1", "install", "run", ant -> ant 230 .copy("target/hat-example-" + example.fileName() + "-1.0.jar", "${hat.build}") 231 ) 232 ) 233 ) 234 ) 235 ) 236 ) 237 ); 238 var backendDirs = backends.subDirs(backend -> !backend.matches("^.*(jextracted|target|.idea)$")).toList(); 239 240 // Now backends/pom.xml and backends/*/pom.xml 241 backends.pom(pomComment, backendsPom -> backendsPom 242 .comment("Auto generated by mkpoms") 243 .pom("oracle.code", "hat-backends", "1.0") 244 .parent("oracle.code", "hat-root", "1.0") 245 .dependsOn("oracle.code", "hat", "1.0") 246 .modules("java", "ffi") 247 ); 248 249 { 250 var ffiBackend = backends.dir("ffi"); 251 252 253 var ffiBackendDirs = ffiBackend.subDirs(backend -> !backend.matches("^.*(hip|spirv|shared|openclx|target|.idea)$")).toList(); 254 255 ffiBackend.pom(pomComment, backendsPom -> backendsPom 256 .comment("Auto generated by mkpoms") 257 .pom("oracle.code", "hat-backends-ffi", "1.0") 258 .parent("oracle.code", "hat-backends", "1.0") 259 .dependsOn("oracle.code", "hat", "1.0") 260 .modules(ffiBackendDirs.stream().map(PathHolder::fileName).toList()) 261 .build(build -> build 262 .plugins(plugins -> plugins 263 .execPlugin(plugin -> plugin 264 .executions(executions -> executions 265 .cmake("1", "compile", "-DHAT_TARGET=${hat.build}", "-B", "${hat.build}/cmake-build-debug") 266 .cmake("2", "install", "--build", "${hat.build}/cmake-build-debug") 267 ) 268 ) 269 ) 270 ) 271 ); 272 273 ffiBackendDirs.forEach(backend -> backend 274 .pom(pomComment, backendPom -> backendPom 275 .comment("Auto generated by mkpoms") 276 .jar("oracle.code", "hat-backend-ffi-" + backend.fileName(), "1.0") 277 .parent("oracle.code", "hat-backends-ffi", "1.0") 278 .dependsOn("oracle.code", "hat", "1.0") 279 .build(build -> build 280 .plugins(plugins -> plugins 281 .execPlugin(plugin -> plugin 282 .configuration(configuration -> configuration 283 .skip("true") 284 ) 285 ) 286 .antPlugin(plugin -> plugin 287 .executions(executions -> executions 288 .ant("1", "install", "run", ant -> ant 289 .copy("target/hat-backend-ffi-" + backend.fileName() + "-1.0.jar", "${hat.build}") 290 ) 291 ) 292 ) 293 ) 294 ) 295 ) 296 ); 297 } 298 { 299 var javaBackend = backends.dir("java"); 300 var javaBackendDirs = javaBackend.subDirs(backend -> !backend.matches("^.*(target|.idea)$")).toList(); 301 302 javaBackend.pom(pomComment, backendsPom -> backendsPom 303 .comment("Auto generated by mkpoms") 304 .pom("oracle.code", "hat-backends-java", "1.0") 305 .parent("oracle.code", "hat-backends", "1.0") 306 .dependsOn("oracle.code", "hat", "1.0") 307 .modules(javaBackendDirs.stream().map(PathHolder::fileName).toList()) 308 ); 309 310 javaBackendDirs.forEach(backend -> backend 311 .pom(pomComment, backendPom -> backendPom 312 .comment("Auto generated by mkpoms") 313 .jar("oracle.code", "hat-backend-java-" + backend.fileName(), "1.0") 314 .parent("oracle.code", "hat-backends-java", "1.0") 315 .dependsOn("oracle.code", "hat", "1.0") 316 .build(build -> build 317 .plugins(plugins -> plugins 318 .antPlugin(plugin -> plugin 319 .executions(executions -> executions 320 .ant("1", "install", "run", ant -> ant 321 .copy("target/hat-backend-java-" + backend.fileName() + "-1.0.jar", "${hat.build}") 322 ) 323 ) 324 ) 325 ) 326 ) 327 ) 328 ); 329 } 330 331 332 var backendJExtracted = backends.dir("jextracted"); 333 334 }