diff --git a/hat/bld b/hat/bld deleted file mode 100644 index 2e5b051760f..00000000000 --- a/hat/bld +++ /dev/null @@ -1,329 +0,0 @@ -/* vim: set ft=java: - * - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import static bldr.Bldr.*; -import static java.lang.System.*; - -void main(String[] args) { - - /* - * ./ - * +--build/ All jars, native libs and executables - * | +--cmake-build-debug/ All intermediate cmake artifacts - * | - * +--stage/ - * | +--repo/ All downloaded maven assets (if any) - * | | - * | +--jextract/ All jextracted files - * | | +--opencl - * | | +--opengl - * | | +--cuda - * | - * +--wrap/ - * | +--wrap/ All downloaded maven assets - * | | +--wrap/ (*) - * | | +--clwrap/ (*) - * | | +--glwrap/ (*) - * | | +--cuwrap/ (*) - * | | - * | - * +--extractions/ - * | +--opencl/ - * | +--opengl/ - * | +--cuda/ - * | - * +--hat-core * Note maven style layout - * | +--src/main/java - * | | +--hat/ - * | | - * | +--src/main/test - * | +--hat/ - * | - * +--backends - * | +--java - * | | +--mt (*) - * | | +--seq (*) - * | +--jextracted - * | | +--opencl (*) - * | +--ffi - * | +--opencl (*) - * | +--ptx (*) - * | +--mock (*) - * | +--spirv (*) - * | +--cuda (*) - * | +--hip (*) - * | - * +--examples - * | +--mandel (*) - * | +--squares (*) - * | +--heal (*) - * | +--life (*) - * | +--nbody (*) - * | +--experiments (*) - * | +--violajones (*) - * - */ - - var dir = DirEntry.current(); - var hatCoreDir = dir.existingDir("hat-core"); - var backends = dir.existingDir("backends"); - var examples = dir.existingDir("examples"); - var wrapsDir = dir.existingDir("wrap"); - var stageDir = dir.buildDir("stage").create(); - var buildDir = BuildDir.of(dir.path("build")).create(); - var cmakeBuildDir = buildDir.cMakeBuildDir("cmake-build-debug"); - - var openclCapability = Capabilities.OpenCL.of(); - var openglCapability = Capabilities.OpenGL.of(); - var cudaCapability = Capabilities.CUDA.of(); - var hipCapability = Capabilities.HIP.of(); - var jextractCapability = Capabilities.JExtract.of();// or Capability.JExtract.of(Path.of("/my/jextract-22/bin/jextract")); - var cmakeCapability = Capabilities.CMake.of(); - - Capabilities capabilities = Capabilities.of(openclCapability, openglCapability, cudaCapability, hipCapability, jextractCapability, cmakeCapability); - - if (cmakeCapability.available()) { - cmakeCapability.probe(buildDir, capabilities); - } - - capabilities.capabilities().forEach(fw -> out.print( "["+fw.name + (fw.available() ? "\u2714" : "\u2715") +"]")); - out.println(); - - var verbose = false; - var wrapJar= buildDir.jarFile("hat-wrap-1.0.jar"); - var clWrapJar= buildDir.jarFile("hat-clwrap-1.0.jar"); - var glWrapJar= buildDir.jarFile("hat-glwrap-1.0.jar"); - var cuWrapJar= buildDir.jarFile("hat-cuwrap-1.0.jar"); - var hatJar = buildDir.jarFile("hat-core-1.0.jar"); - - var hatJavacOpts = javacBuilder($ -> $ - .enable_preview() - .add_modules("jdk.incubator.code") - // .add_exports_to_all_unnamed("java.base", "jdk.internal", "jdk.internal.vm.annotation") - .current_source() - ); - - var hatJarOptions = jarBuilder($ -> $ - .verbose(verbose) - ); - jar(hatJarOptions, jar -> jar - .jarFile(hatJar) - .maven_style_root(hatCoreDir) - .javac(hatJavacOpts, javac -> { - }) - ); - - jar(jar -> jar - .jarFile(wrapJar) - .maven_style_root(wrapsDir.dir("wrap")) - .javac(javac -> javac.current_source()) - ); - - if (jextractCapability.available()) { - if (openclCapability.available()) { - if (!openclCapability.jarFile(buildDir).exists()) { - if (!openclCapability.stage(stageDir).exists()) { - jextract(jextractCapability.executable, $ -> $ .verbose(verbose) .capability(openclCapability,stageDir)); - }else{ - out.println("Using previously extracted "+openclCapability.stage(buildDir).fileName()); - } - jar(jar -> jar - .jarFile(openclCapability.jarFile(buildDir)) - .javac(javac -> javac.current_source().source_path(SourceDir.of(openclCapability.stage(stageDir).path()))) - - ); - }else{ - out.println("Using existing extracted "+openclCapability.jarFile(buildDir).fileName()); - } - jar(jar -> jar - .jarFile(clWrapJar) - .maven_style_root(wrapsDir.dir("clwrap")) - .javac(javac -> javac.current_source().class_path(wrapJar,hatJar, openclCapability.jarFile(buildDir))) - ); - } else { - out.println("This platform does not have OpenCL"); - } - - if (openglCapability.available()) { - if (!openglCapability.jarFile(buildDir).exists()) { - if (!openglCapability.stage(stageDir).exists()) { - jextract(jextractCapability, $ -> $ .verbose(verbose) .capability(openglCapability, stageDir)); - }else{ - out.println("Using previously extracted "+openglCapability.stage(buildDir).fileName()); - } - jar(jar -> jar - .jarFile(openglCapability.jarFile(buildDir)) - .javac(javac -> javac.current_source().source_path(SourceDir.of(openglCapability.stage(stageDir).path()))) - ); - }else{ - out.println("Using existing extracted "+openglCapability.jarFile(buildDir).fileName()); - } - jar(jar -> jar - .jarFile(glWrapJar) - .maven_style_root(wrapsDir.dir("glwrap")) - .javac(javac -> javac - .current_source() - .exclude(javaSrc -> javaSrc.matches("^.*/wrap/glwrap/GLCallbackEventHandler\\.java$")) - //.exclude(javaSrc -> javaSrc.matches("^.*/wrap/glwrap/GLFuncEventHandler\\.java$")) - .class_path(wrapJar, openglCapability.jarFile(buildDir)) - ) - ); - } else { - out.println("This platform does not have OpenGL"); - } - - - if (cudaCapability.available()) { - - } else { - out.println("This platform does not have CUDA"); - } - } - - var backendJars = new ArrayList<bldr.Bldr.JarFile>(); - - - // Here we create all ffi-backend jars. - var ffiBackends = backends.existingDir("ffi"); - ffiBackends.subDirs() - .filter(backend -> backend.failsToMatch("^.*(spirv|hip|shared|target|.idea)$")) - .forEach(backend -> { - var ffiBackendJarFile = buildDir.jarFile("hat-backend-ffi-" + backend.fileName() + "-1.0.jar"); - backendJars.add(ffiBackendJarFile); - out.println(ffiBackendJarFile.fileName()); - jar(hatJarOptions, jar -> jar - .jarFile(ffiBackendJarFile) - .maven_style_root(backend) - .javac(hatJavacOpts, javac -> javac.class_path(hatJar)) - ); - }); - - // Here we create jextracted-backend jars. - var jextractedBackends = backends.existingDir("jextracted"); - var jextractedBackendSharedDir = jextractedBackends.dir("shared"); - out.println("Shared jextracted "+jextractedBackendSharedDir.path()); - var jextractedSharedBackendJar=buildDir.jarFile("hat-backend-jextracted-shared-1.0.jar"); - backendJars.add(jextractedSharedBackendJar); - var jextractedBackendSharedResult = jar(hatJarOptions, jar -> jar - .jarFile(jextractedSharedBackendJar) - .maven_style_root(jextractedBackendSharedDir) - .javac(hatJavacOpts, javac -> javac.verbose(verbose) - .class_path(hatJar) - ) - ); - - if (openclCapability.available()){ - var jextractedBackendOpenCLDir = jextractedBackends.dir("opencl"); - out.println("OpenCL jextracted "+jextractedBackendOpenCLDir.path()); - var jextractedOpenCLBackendJar = buildDir.jarFile("hat-backend-jextracted-opencl-1.0.jar"); - backendJars.add(jextractedOpenCLBackendJar); - jar(hatJarOptions, jar -> jar - .jarFile(jextractedOpenCLBackendJar) - .maven_style_root(jextractedBackendOpenCLDir) - .javac(hatJavacOpts, javac -> javac.verbose(verbose) - .class_path(hatJar, openclCapability.jarFile(buildDir), jextractedBackendSharedResult ) - ) - ); - } - - - // Here we create all java backend jars. - backends.existingDir("java") - .subDirs() - .filter(backend -> backend.failsToMatch("^.*(target|.idea)$")) - .forEach(backend -> { - var backendJavaJar = buildDir.jarFile("hat-backend-java-" + backend.fileName() + "-1.0.jar"); - out.println(backendJavaJar.fileName()); - backendJars.add(backendJavaJar); - jar(hatJarOptions, jar -> jar - .jarFile(backendJavaJar) - .dir_list(backend.dir("src/main/resources")) - ); - }); - - backendJars.forEach(j->out.println(" backend "+j.path())); - - - // here we create the example jars - examples.subDirs() - .filter(example -> example.failsToMatch("^.*(experiments|nbody|life|target|.idea)$")) - .forEach(example -> { - var exampleJarFile = buildDir.jarFile("hat-example-" + example.fileName() + "-1.0.jar"); - out.println(exampleJarFile.fileName()); - jar(hatJarOptions, jar -> jar - .jarFile(exampleJarFile) - .maven_style_root(example) - .javac(hatJavacOpts, javac -> javac.class_path(hatJar)) - .manifest(manifest -> manifest .main_class(example.fileName() + ".Main")) - ); - }); - - - if (jextractCapability.available() && openclCapability.available()) { - var example = examples.dir("life"); - var exampleJarFile = buildDir.jarFile("hat-example-" + example.fileName() + "-1.0.jar"); - out.println(exampleJarFile.fileName()); - jar(hatJarOptions, jar -> jar - .jarFile(exampleJarFile) - .maven_style_root(example) - .javac(hatJavacOpts, javac -> javac - .class_path(hatJar, wrapJar, clWrapJar, openclCapability.jarFile(buildDir), buildDir.jarFile("hat-backend-ffi-opencl-1.0.jar")) - ) - ); - } - - - if (jextractCapability.available() && openclCapability.available() && openglCapability.available()) { - var example = examples.dir("nbody"); - var exampleJarFile = buildDir.jarFile("hat-example-" + example.fileName() + "-1.0.jar"); - out.println(exampleJarFile.fileName()); - jar(hatJarOptions, jar -> jar - .jarFile(exampleJarFile) - .maven_style_root(example) - .javac(hatJavacOpts, javac -> javac - .class_path( hatJar, wrapJar, clWrapJar, glWrapJar, openclCapability.jarFile(buildDir), openglCapability.jarFile(buildDir),buildDir.jarFile("hat-backend-ffi-opencl-1.0.jar")) - ) - ); - } - - if (cmakeCapability.available()) { - if (!cmakeBuildDir.exists()) { - cmake($ -> $ - .verbose(verbose) - .source_dir(ffiBackends) - .build_dir(cmakeBuildDir) - .copy_to(buildDir) - ); - } - cmake($ -> $ - .build(cmakeBuildDir) - ); - } else { - out.println("No cmake available so we did not build ffi backend shared libs"); - } - -} - diff --git a/hat/bldr/.gitignore b/hat/bldr/.gitignore deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/hat/bldr/Bldr.java b/hat/bldr/Bldr.java deleted file mode 100644 index 861e0bd73e2..00000000000 --- a/hat/bldr/Bldr.java +++ /dev/null @@ -1,4487 +0,0 @@ -/* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package bldr; - -import com.sun.source.util.JavacTask; -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -import javax.tools.Diagnostic; -import javax.tools.DiagnosticListener; -import javax.tools.JavaCompiler; -import javax.tools.JavaFileObject; -import javax.tools.SimpleJavaFileObject; -import javax.tools.ToolProvider; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.jar.JarEntry; -import java.util.jar.JarOutputStream; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Stream; -import java.util.zip.ZipFile; - -import static java.io.IO.print; -import static java.io.IO.println; - -public class Bldr { - public sealed interface PathHolder permits ClassPathEntry, DirPathHolder, FilePathHolder, SourcePathEntry { - default Path path(String subdir) { - return path().resolve(subdir); - } - - default String fileName() { - return path().getFileName().toString(); - } - - default Matcher pathMatcher(Pattern pattern) { - return pattern.matcher(path().toString()); - } - - default boolean matches(Pattern pattern) { - return pathMatcher(pattern).matches(); - } - - default boolean matches(String pattern) { - return pathMatcher(Pattern.compile(pattern)).matches(); - } - default boolean failsToMatch(String pattern) { - return !pathMatcher(Pattern.compile(pattern)).matches(); - } - - boolean exists(); - - Path path(); - } - - public sealed interface DirPathHolder<T extends DirPathHolder<T>> extends PathHolder - permits BuildDirHolder, DirEntry, SourceDir { - - default Stream<Path> find() { - try { - return Files.walk(path()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - default Stream<Path> find(Predicate<Path> predicate) { - return find().filter(predicate); - } - - default Stream<Path> findFiles() { - return find(Files::isRegularFile); - } - - default Stream<Path> findDirs() { - return find(Files::isDirectory); - } - - default Stream<Path> findFiles(Predicate<Path> predicate) { - return findFiles().filter(predicate); - } - - default Stream<Path> findFilesBySuffix(String suffix) { - return findFiles(p -> p.toString().endsWith(suffix)); - } - - default Stream<SearchableTextFile> findTextFiles(String... suffixes) { - return findFiles() - .map(SearchableTextFile::new) - .filter(searchableTextFile -> searchableTextFile.hasSuffix(suffixes)); - } - - default Stream<Path> findDirs(Predicate<Path> predicate) { - return find(Files::isDirectory).filter(predicate); - } - - default boolean exists() { - return Files.isDirectory(path()); - } - - default BuildDir buildDir(String name) { - return BuildDir.of(path().resolve(name)); - } - - default SourceDir sourceDir(String s) { - return SourceDir.of(path().resolve(s)); - } - - default CppSourceFile cppSourceFile(String s) { - return CppSourceFile.of(path().resolve(s)); - } - - default XMLFile xmlFile(String s) { - return XMLFile.of(path().resolve(s)); - } - - default TestNGSuiteFile testNGSuiteFile(String s) { - return TestNGSuiteFile.of(path().resolve(s)); - } - } - - public sealed interface FilePathHolder extends PathHolder { - default boolean exists() { - return Files.isRegularFile(path()); - } - } - - public sealed interface Executable extends FilePathHolder { - default boolean exists() { - return Files.exists(path()) && Files.isRegularFile(path()) && Files.isExecutable(path()); - } - } - - - public interface ClassPathEntryProvider { - List<ClassPathEntry> classPathEntries(); - } - - public sealed interface ClassPathEntry extends PathHolder, ClassPathEntryProvider { - } - - interface PathHolderList<T extends PathHolder> { - List<T> entries(); - - default String charSeparated() { - StringBuilder sb = new StringBuilder(); - entries().forEach(pathHolder -> { - if (!sb.isEmpty()) { - sb.append(File.pathSeparatorChar); - } - sb.append(pathHolder.path()); - }); - return sb.toString(); - } - } - - public record ClassPath(List<ClassPathEntry> classPathEntries) - implements PathHolderList<ClassPathEntry>, ClassPathEntryProvider { - public static ClassPath of() { - return new ClassPath(new ArrayList<>()); - } - - public static ClassPath ofOrUse(ClassPath classPath) { - return classPath == null ? of() : classPath; - } - - public ClassPath add(List<ClassPathEntryProvider> classPathEntryProviders) { - classPathEntryProviders.forEach( - classPathEntryProvider -> - this.classPathEntries.addAll(classPathEntryProvider.classPathEntries())); - return this; - } - - public ClassPath add(ClassPathEntryProvider... classPathEntryProviders) { - return add(List.of(classPathEntryProviders)); - } - - @Override - public String toString() { - return charSeparated(); - } - - @Override - public List<ClassPathEntry> classPathEntries() { - return this.classPathEntries; - } - - @Override - public List<ClassPathEntry> entries() { - return this.classPathEntries; - } - } - - public record SourcePath(List<SourceDir> entries) - implements PathHolderList<SourceDir> { - public static SourcePath of() { - return new SourcePath(new ArrayList<>()); - } - - public static SourcePath ofOrUse(SourcePath sourcePath) { - return sourcePath == null ? of() : sourcePath; - } - - public SourcePath add(List<SourceDir> sourcePathEntries) { - entries.addAll(sourcePathEntries); - return this; - } - - public SourcePath add(SourceDir... sourcePathEntries) { - add(Arrays.asList(sourcePathEntries)); - return this; - } - - public SourcePath add(SourcePath... sourcePaths) { - List.of(sourcePaths).forEach(sourcePath -> add(sourcePath.entries)); - return this; - } - - @Override - public String toString() { - return charSeparated(); - } - - public Stream<Path> javaFiles() { - List<Path> javaFiles = new ArrayList<>(); - entries.forEach(entry -> entry.javaFiles().forEach(javaFiles::add)); - return javaFiles.stream(); - } - } - - public record DirPath(List<DirPathHolder<?>> entries) - implements PathHolderList<DirPathHolder<?>> { - public static DirPath of() { - return new DirPath(new ArrayList<>()); - } - - public static DirPath ofOrUse(DirPath dirPath) { - return dirPath == null ? of() : dirPath; - } - - public DirPath add(List<DirPathHolder<?>> dirPathHolders) { - entries.addAll(dirPathHolders); - return this; - } - - public DirPath add(DirPathHolder<?>... dirPathHolders) { - add(Arrays.asList(dirPathHolders)); - return this; - } - - public DirPath add(DirPath... dirPaths) { - List.of(dirPaths).forEach(dirPath -> add(dirPath.entries)); - return this; - } - - @Override - public String toString() { - return charSeparated(); - } - } - - public record CMakeBuildDir(Path path) implements BuildDirHolder<CMakeBuildDir> { - public static CMakeBuildDir of(Path path) { - return new CMakeBuildDir(path); - } - - @Override - public CMakeBuildDir create() { - return CMakeBuildDir.of(mkdir(path())); - } - - @Override - public CMakeBuildDir remove() { - return CMakeBuildDir.of(rmdir(path())); - } - } - - public sealed interface BuildDirHolder<T extends BuildDirHolder<T>> extends DirPathHolder<T> { - T create(); - - T remove(); - - default T clean() { - remove(); - return create(); - } - - default Path mkdir(Path path) { - try { - return Files.createDirectories(path); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - default Path rmdir(Path path) { - try { - if (Files.exists(path)) { - Files.walk(path) - .sorted(Comparator.reverseOrder()) - .map(Path::toFile) - .forEach(File::delete); - } - } catch (IOException ioe) { - System.out.println(ioe); - } - return path; - } - } - - - public record ClassDir(Path path) implements ClassPathEntry, BuildDirHolder<ClassDir> { - public static ClassDir of(Path path) { - return new ClassDir(path); - } - - public static ClassDir temp() { - try { - return of(Files.createTempDirectory("javacClasses")); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public ClassDir create() { - return ClassDir.of(mkdir(path())); - } - - @Override - public ClassDir remove() { - return ClassDir.of(rmdir(path())); - } - - @Override - public List<ClassPathEntry> classPathEntries() { - return List.of(this); - } - } - - public record RepoDir(Path path) implements BuildDirHolder<RepoDir> { - public static RepoDir of(Path path) { - return new RepoDir(path); - } - - @Override - public RepoDir create() { - return RepoDir.of(mkdir(path())); - } - - @Override - public RepoDir remove() { - return RepoDir.of(rmdir(path())); - } - - public JarFile jarFile(String name) { - return JarFile.of(path().resolve(name)); - } - - public ClassPathEntryProvider classPathEntries(String... specs) { - var repo = new MavenStyleRepository(this); - return repo.classPathEntries(specs); - } - } - - public record DirEntry(Path path) implements DirPathHolder<DirEntry> { - public static DirEntry of(Path path) { - return new DirEntry(path); - } - - public static DirEntry of(String string) { - return of(Path.of(string)); - } - - public static DirEntry ofExisting(String string) { - return of(assertExists(Path.of(string))); - } - - public static DirEntry current() { - return of(Path.of(System.getProperty("user.dir"))); - } - - public DirEntry parent() { - return of(path().getParent()); - } - - public DirEntry dir(String subdir) { - return DirEntry.of(path(subdir)); - } - - public FileEntry file(String fileName) { - return FileEntry.of(path(fileName)); - } - - public DirEntry existingDir(String subdir) { - return assertExists(DirEntry.of(path(subdir))); - } - - public Stream<DirEntry> subDirs() { - return Stream.of(Objects.requireNonNull(path().toFile().listFiles(File::isDirectory))) - .map(d -> DirEntry.of(d.getPath())); - } - - // public Stream<DirEntry> subDirs(Predicate<DirEntry> predicate) { - // return subDirs().filter(predicate); - // } - - public XMLFile pom( - String comment, Consumer<XMLNode.PomXmlBuilder> pomXmlBuilderConsumer) { - XMLFile xmlFile = xmlFile("pom.xml"); - XMLNode.createPom(comment, pomXmlBuilderConsumer).write(xmlFile); - return xmlFile; - } - - public BuildDir existingBuildDir(String subdir) { - return assertExists(BuildDir.of(path(subdir))); - } - } - - public interface SourcePathEntryProvider { - List<SourcePathEntry> sourcePathEntries(); - } - - public sealed interface SourcePathEntry extends PathHolder, SourcePathEntryProvider { - } - - public record SourceDir(Path path) implements SourcePathEntry, DirPathHolder<SourceDir> { - public static SourceDir of(Path path) { - return new SourceDir(path); - } - - public Stream<Path> javaFiles() { - return findFilesBySuffix(".java"); - } - - @Override - public List<SourcePathEntry> sourcePathEntries() { - return List.of(this); - } - } - - public record RootDirAndSubPath(DirPathHolder<?> root, Path path) { - Path relativize() { - return root().path().relativize(path()); - } - } - - public record BuildDir(Path path) implements ClassPathEntry, BuildDirHolder<BuildDir> { - public static BuildDir of(Path path) { - return new BuildDir(path); - } - - public JarFile jarFile(String name) { - return JarFile.of(path().resolve(name)); - } - - public ClassPathEntryProvider jarFiles(String... names) { - var classPath = ClassPath.of(); - Stream.of(names).forEach(name -> classPath.add(JarFile.of(path().resolve(name)))); - return classPath; - } - - - public CMakeBuildDir cMakeBuildDir(String name) { - return CMakeBuildDir.of(path().resolve(name)); - } - - public ClassDir classDir(String name) { - return ClassDir.of(path().resolve(name)); - } - - public RepoDir repoDir(String name) { - return RepoDir.of(path().resolve(name)); - } - - @Override - public BuildDir create() { - return BuildDir.of(mkdir(path())); - } - - - @Override - public BuildDir remove() { - return BuildDir.of(rmdir(path())); - } - - public BuildDir dir(String subdir) { - return BuildDir.of(path(subdir)); - } - - public ObjectFile objectFile(String name) { - return ObjectFile.of(path().resolve(name)); - } - - public ExecutableFile executableFile(String name) { - return ExecutableFile.of(path().resolve(name)); - } - - public SharedLibraryFile sharedLibraryFile(String name) { - return SharedLibraryFile.of(path().resolve(name)); - } - - @Override - public List<ClassPathEntry> classPathEntries() { - return List.of(this); - } - - public SearchableTextFile textFile(String file, List<String> strings) { - SearchableTextFile textFile = SearchableTextFile.of(path().resolve(file)); - try { - PrintWriter pw = new PrintWriter(Files.newOutputStream(textFile.path(), StandardOpenOption.CREATE)); - strings.forEach(pw::print); - pw.close(); - return textFile; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public SearchableTextFile textFile(String file, Consumer<StringBuilder> stringBuilderConsumer) { - SearchableTextFile textFile = SearchableTextFile.of(path().resolve(file)); - var sb = new StringBuilder(); - stringBuilderConsumer.accept(sb); - try { - Files.writeString(textFile.path, sb.toString()); - return textFile; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - - public CMakeLists cmakeLists(Consumer<StringBuilder> stringBuilderConsumer) { - var sb = new StringBuilder(); - stringBuilderConsumer.accept(sb); - var ret = CMakeLists.of(path().resolve("CMakeLists.txt")); - try { - Files.writeString(ret.path, sb.toString()); - return ret; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - - public record FileEntry(Path path) implements FilePathHolder { - public static FileEntry of(Path path) { - return new FileEntry(path); - } - } - - public record JarFile(Path path) implements ClassPathEntry, FilePathHolder { - public static JarFile of(Path path) { - return new JarFile(path); - } - - @Override - public List<ClassPathEntry> classPathEntries() { - return List.of(this); - } - } - - public sealed interface TextFile extends FilePathHolder { - - static Path tempContaining(String suffix, String text) { - try { - var path = Files.createTempFile(Files.createTempDirectory("bldr"), "data", suffix); - Files.newOutputStream(path).write(text.getBytes()); - return path; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - - - public sealed interface SourceFile extends TextFile { - } - - public static final class CMakeLists implements SourceFile { - Path path; - - CMakeLists(Path path) { - this.path = path; - } - - public static CMakeLists of(Path path) { - return new CMakeLists(path); - } - - @Override - public Path path() { - return path; - } - } - - public static final class JavaSourceFile extends SimpleJavaFileObject implements SourceFile { - Path path; - - public CharSequence getCharContent(boolean ignoreEncodingErrors) { - try { - return Files.readString(Path.of(toUri())); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - JavaSourceFile(Path path) { - super(path.toUri(), Kind.SOURCE); - this.path = path; - } - - @Override - public Path path() { - return path; - } - } - - public record JExtractExecutable(Path path) implements Executable { - public static JExtractExecutable of(Path path) { - return new JExtractExecutable(path); - } - } - - - public record ObjectFile(Path path) implements FilePathHolder { - public static ObjectFile of(Path path) { - return new ObjectFile(path); - } - } - - public record ExecutableFile(Path path) implements FilePathHolder { - public static ExecutableFile of(Path path) { - return new ExecutableFile(path); - } - } - - public record SharedLibraryFile(Path path) implements FilePathHolder { - public static SharedLibraryFile of(Path path) { - return new SharedLibraryFile(path); - } - } - - public record CppSourceFile(Path path) implements SourceFile { - public static CppSourceFile of(Path path) { - return new CppSourceFile(path); - } - } - - public record CppHeaderSourceFile(Path path) implements SourceFile { - } - - public record XMLFile(Path path) implements TextFile { - public static XMLFile of(Path path) { - return new XMLFile(path); - } - - public static XMLFile containing(String text) { - return XMLFile.of(TextFile.tempContaining("xml", text)); - } - } - - public record TestNGSuiteFile(Path path) implements TextFile { - public static TestNGSuiteFile of(Path path) { - return new TestNGSuiteFile(path); - } - - public static TestNGSuiteFile containing(String text) { - return TestNGSuiteFile.of(TextFile.tempContaining("xml", text)); - } - } - - public interface OS { - String arch(); - - String name(); - - String version(); - - String MacName = "Mac OS X"; - String LinuxName = "Linux"; - - record Linux(String arch, String name, String version) implements OS { - } - - record Mac(String arch, String name, String version) implements OS { - public Path appLibFrameworks() { - return Path.of( - "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/" - + "MacOSX.sdk/System/Library/Frameworks"); - } - - public Path frameworkHeader(String frameworkName, String headerFileName) { - return appLibFrameworks().resolve(frameworkName + ".framework/Headers/" + headerFileName); - } - - public Path libFrameworks() { - return Path.of("/System/Library/Frameworks"); - } - - public Path frameworkLibrary(String frameworkName) { - return libFrameworks().resolve(frameworkName + ".framework/" + frameworkName); - } - } - - static OS get() { - String arch = System.getProperty("os.arch"); - String name = System.getProperty("os.name"); - String version = System.getProperty("os.version"); - return switch (name) { - case "Mac OS X" -> new Mac(arch, name, version); - case "Linux" -> new Linux(arch, name, version); - default -> throw new IllegalStateException("No os mapping for " + name); - }; - } - } - - public static OS os = OS.get(); - - public record Java(String version, DirEntry home, int specVersion) { - } - - public static Java java = - new Java( - System.getProperty("java.version"), - DirEntry.of(System.getProperty("java.home")), - Integer.parseInt(System.getProperty("java.specification.version")) - ); - - public record User(DirEntry home, DirEntry pwd) { - } - - public static User user = - new User(DirEntry.of(System.getProperty("user.home")), DirEntry.of(System.getProperty("user.dir"))); - - - public abstract sealed static class Builder<T extends Builder<T>> permits CMakeBuilder, FormatBuilder, JExtractBuilder, JarBuilder, JarBuilder.ManifestBuilder, JavaOpts, TestNGBuilder { - public Builder<?> parent; - public boolean verbose; - public boolean quiet; - - @SuppressWarnings("unchecked") - T self() { - return (T) this; - } - - protected T dontCallThisCopy(T other) { - this.verbose = other.verbose; - this.quiet = other.quiet; - return self(); - } - - public T quiet(boolean quiet) { - this.quiet = quiet; - return self(); - } - - public T quiet() { - quiet(true); - return self(); - } - - public T verbose(boolean verbose) { - this.verbose = verbose; - return self(); - } - - public T verbose() { - verbose(true); - return self(); - } - - public T when(boolean condition, Consumer<T> consumer) { - if (condition) { - consumer.accept(self()); - } - return self(); - } - - public <P extends PathHolder> T whenExists(P pathHolder, Consumer<T> consumer) { - if (Files.exists(pathHolder.path())) { - consumer.accept(self()); - } - return self(); - } - - public <P extends PathHolder> T whenExists(P pathHolder, BiConsumer<P, T> consumer) { - if (Files.exists(pathHolder.path())) { - consumer.accept(pathHolder, self()); - } - return self(); - } - - public T either(boolean condition, Consumer<T> trueConsumer, Consumer<T> falseConsumer) { - if (condition) { - trueConsumer.accept(self()); - } else { - falseConsumer.accept(self()); - } - return self(); - } - - Builder(Builder<?> parent) { - this.parent = parent; - } - - Builder() { - this(null); - } - - public T mac(Consumer<OS.Mac> macConsumer) { - if (Bldr.os instanceof OS.Mac mac) { - macConsumer.accept(mac); - } - return self(); - } - - public T linux(Consumer<OS.Linux> linuxConsumer) { - if (Bldr.os instanceof OS.Linux linux) { - linuxConsumer.accept(linux); - } - return self(); - } - - public T os(Consumer<OS.Mac> macConsumer, Consumer<OS.Linux> linuxConsumer) { - switch (Bldr.os) { - case OS.Linux linux -> linuxConsumer.accept(linux); - case OS.Mac mac -> macConsumer.accept(mac); - default -> throw new IllegalStateException("Unexpected value: " + Bldr.os); - } - ; - return self(); - } - } - - public abstract static sealed class Result<T extends Builder<T>> permits JExtractResult, JarResult, JavaResult, JavacResult { - public boolean ok; - public T builder; - - Result(T builder) { - this.builder = builder; - } - } - - public static class Strings { - public List<String> strings = new ArrayList<>(); - - Strings() { - } - - Strings(Strings strings) { - add(strings); - } - - Strings(List<String> strings) { - add(strings); - } - - Strings(String... strings) { - add(strings); - } - - public Strings add(List<String> strings) { - this.strings.addAll(strings); - return this; - } - - public Strings add(String... strings) { - add(Arrays.asList(strings)); - return this; - } - - public Strings add(Strings strings) { - add(strings.strings); - return this; - } - - public String spaceSeparated() { - StringBuilder stringBuilder = new StringBuilder(); - strings.forEach(opt -> stringBuilder.append(stringBuilder.isEmpty() ? "" : " ").append(opt)); - return stringBuilder.toString(); - } - } - - - public static sealed class JavaOpts<T extends JavaOpts<T>> extends Builder<T> { - public DirEntry jdk = java.home; - public Boolean enablePreview; - public Strings modules; - - record FromModulePackageToModule(String fromModule, String pkg, String toModule) { - } - - List<FromModulePackageToModule> exports; - - protected T dontCallThisCopy(T other) { - super.dontCallThisCopy(other); - if (other.jdk != null) { - this.jdk = other.jdk; - } - if (other.enablePreview != null) { - this.enablePreview = other.enablePreview; - } - if (other.modules != null) { - this.modules = new Strings(other.modules); - } - if (other.exports != null) { - this.exports = new ArrayList<>(other.exports); - } - - return self(); - } - - public JavaOpts(Builder<?> parent) { - super(parent); - } - - public JavaOpts() { - super(); - } - - static public JavaOpts<?> of() { - return new JavaOpts<>(); - } - - public T jdk(DirEntry jdk) { - this.jdk = jdk; - return self(); - } - - public T add_exports(String fromModule, String pkg, String toModule) { - if (this.exports == null) { - this.exports = new ArrayList<>(); - } - exports.add(new FromModulePackageToModule(fromModule, pkg, toModule)); - return self(); - } - - public T add_modules(String... modules) { - if (this.modules == null) { - this.modules = new Strings(); - } - this.modules.add(modules); - - return self(); - } - - public T add_exports(String fromModule, List<String> packages, String toModule) { - - packages.forEach(p -> add_exports(fromModule, p, toModule)); - return self(); - } - - public T add_exports(String fromModule, String[] packages, String toModule) { - return add_exports(fromModule, Arrays.asList(packages), toModule); - } - - public T add_exports_to_all_unnamed(String fromModule, String... packages) { - return add_exports(fromModule, Arrays.asList(packages), "ALL-UNNAMED"); - } - - public T enable_preview() { - this.enablePreview = true; - return self(); - } - - - } - - public abstract sealed static class JavaToolBuilder<T extends JavaToolBuilder<T>> extends JavaOpts<T> permits JavacBuilder, JavaBuilder { - public ClassPath classPath; - - protected T dontCallThisCopy(T other) { - super.dontCallThisCopy(other); - if (other.classPath != null) { - this.classPath = ClassPath.of().add(other.classPath); - } - return self(); - } - - public JavaToolBuilder(Builder<?> parent) { - super(parent); - } - - public JavaToolBuilder() { - super(); - } - - public T class_path(List<ClassPathEntryProvider> classPathEntryProviders) { - this.classPath = ClassPath.ofOrUse(this.classPath).add(classPathEntryProviders); - return self(); - } - - public T class_path(ClassPathEntryProvider... classPathEntryProviders) { - return class_path(List.of(classPathEntryProviders)); - } - } - - public static final class JavacBuilder extends JavaToolBuilder<JavacBuilder> { - public DirEntry mavenStyleRoot; - public ClassDir classDir; - public SourcePath sourcePath; - public ClassPath modulePath; - public SourcePath moduleSourcePath; - public Integer source; - public List<Predicate<JavaSourceFile>> exclusionFilters; - - protected JavacBuilder dontCallThisCopy(JavacBuilder other) { - super.dontCallThisCopy(other); - if (other.mavenStyleRoot != null) { - throw new RuntimeException("You are copying a JavacBuilder which is already bound to maven style dir"); - } - if (other.sourcePath != null) { - throw new RuntimeException("You are copying a JavacBuilder which is already bound to a SourcePath"); - } - if (other.moduleSourcePath != null) { - throw new RuntimeException("You are copying a JavacBuilder which is already bound to a ModuleSourcePath"); - } - - if (other.source != null) { - this.source = other.source; - } - - if (other.classPath != null) { - ClassPath.ofOrUse(this.classPath).add(other.classPath); - } - return this; - } - - public JavacBuilder source(int version) { - this.source = version; - return self(); - } - - public JavacBuilder current_source() { - return source(Bldr.java.specVersion); - } - - public JavacBuilder maven_style_root(DirEntry mavenStyleRoot) { - this.mavenStyleRoot = mavenStyleRoot; - return this; - } - - public JavacBuilder class_dir(Path classDir) { - this.classDir = ClassDir.of(classDir); - return this; - } - - public JavacBuilder class_dir(ClassDir classDir) { - this.classDir = classDir; - return this; - } - - public JavacBuilder d(ClassDir classDir) { - this.classDir = classDir; - return this; - } - - public JavacBuilder source_path(List<SourceDir> sourcePaths) { - this.sourcePath = SourcePath.ofOrUse(this.sourcePath).add(sourcePaths); - return this; - } - - public JavacBuilder source_path(SourceDir... sourcePathEntries) { - return source_path(List.of(sourcePathEntries)); - } - - public JavacBuilder source_path(SourcePath sourcePath) { - return source_path(sourcePath.entries); - } - - public JavacBuilder module_source_path(List<SourceDir> moduleSourcePathEntries) { - this.moduleSourcePath = SourcePath.ofOrUse(this.moduleSourcePath).add(moduleSourcePathEntries); - return this; - } - - public JavacBuilder module_source_path(SourceDir... moduleSourcePathEntries) { - return module_source_path(List.of(moduleSourcePathEntries)); - } - - public JavacBuilder module_source_path(SourcePath moduleSourcePath) { - return module_source_path(moduleSourcePath.entries()); - } - - public JavacBuilder() { - super(); - } - - public JavacBuilder(JarBuilder jarBuilder) { - super(jarBuilder); - } - - public JavacBuilder exclude(Predicate<JavaSourceFile> javaSourceFileFilter) { - this.exclusionFilters = (this.exclusionFilters == null ? new ArrayList<>() : this.exclusionFilters); - this.exclusionFilters.add(javaSourceFileFilter); - return self(); - } - } - - public static final class JavacResult extends Result<JavacBuilder> { - Strings opts = new Strings(); - List<JavaSourceFile> sourceFiles = new ArrayList<>(); - List<JavaFileObject> classes = new ArrayList<>(); - public ClassDir classDir; - - JavacResult(JavacBuilder builder) { - super(builder); - } - } - - public static JavacResult javac(JavacBuilder javacBuilder) { - JavacResult result = new JavacResult(javacBuilder); - - try { - if (javacBuilder.source != null) { - result.opts.add("--source", javacBuilder.source.toString()); - } - - if (javacBuilder.enablePreview != null && javacBuilder.enablePreview) { - result.opts.add("--enable-preview"); - } - if (javacBuilder.modules != null) { - javacBuilder.modules.strings.forEach(module -> - result.opts.add("--add-modules", module) - ); - } - - if (javacBuilder.exports != null) { - javacBuilder.exports.forEach(fpt -> { - result.opts.add("--add-exports=" + fpt.fromModule + "/" + fpt.pkg + "=" + fpt.toModule); - }); - } - - result.classDir = javacBuilder.classDir == null ? ClassDir.temp() : javacBuilder.classDir; - result.opts.add("-d", result.classDir.path().toString()); - if (javacBuilder.classPath != null) { - result.opts.add("--class-path", javacBuilder.classPath.charSeparated()); - } else if (javacBuilder.modulePath != null) { - //https://dev.java/learn/modules/building/ - result.opts.add("--module-path", javacBuilder.modulePath.charSeparated()); - } else { - // println("Warning no class path or module path "); - //throw new RuntimeException("No class path or module path provided"); - } - var mavenStyleRoot = - ((javacBuilder.parent instanceof JarBuilder jarBuilder) && jarBuilder.mavenStyleRoot instanceof DirEntry fromJarBuilder) - ? fromJarBuilder - : javacBuilder.mavenStyleRoot; - - - if (mavenStyleRoot == null) { - if (javacBuilder.sourcePath != null && !javacBuilder.sourcePath.entries.isEmpty()) { - result.opts.add("--source-path", javacBuilder.sourcePath.charSeparated()); - result.sourceFiles.addAll(javacBuilder.sourcePath.javaFiles().map(JavaSourceFile::new).toList()); - } else if (javacBuilder.moduleSourcePath != null && !javacBuilder.moduleSourcePath.entries.isEmpty()) { - result.opts.add("--module-source-path", javacBuilder.moduleSourcePath.charSeparated()); - result.sourceFiles.addAll(javacBuilder.moduleSourcePath.javaFiles().map(JavaSourceFile::new).toList()); - } else { - throw new RuntimeException("No source path or module source path specified"); - } - } else { - var sourcePath = SourcePath.of().add(SourceDir.of(mavenStyleRoot.path.resolve("src/main/java"))); - result.sourceFiles.addAll(sourcePath.javaFiles().map(JavaSourceFile::new).toList()); - if (result.sourceFiles.isEmpty()) { - throw new RuntimeException("No sources"); - } - result.opts.add("--source-path", sourcePath.charSeparated()); - - if (javacBuilder.sourcePath != null && !javacBuilder.sourcePath.entries.isEmpty()) { - throw new RuntimeException("You have specified --source-path AND provided maven_style_root "); - } - } - boolean[] failed = {false}; - - DiagnosticListener<JavaFileObject> diagnosticListener = - (diagnostic) -> { - if (diagnostic.getKind().equals(Diagnostic.Kind.ERROR)) { - failed[0] = true; - } - if (!diagnostic.getKind().equals(Diagnostic.Kind.NOTE)) { - System.out.println("javac " - + diagnostic.getKind() - + " " - + ((JavaSourceFile) (diagnostic.getSource())).path().toString() - + " " - + diagnostic.getLineNumber() - + ":" - + diagnostic.getColumnNumber() - + " " - + diagnostic.getMessage(null)); - } - }; - - JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); - if (javacBuilder.exclusionFilters != null) { - javacBuilder.exclusionFilters.forEach(p -> { - result.sourceFiles = result.sourceFiles.stream().filter( - javaSourceFile -> { - var kill = p.test(javaSourceFile); - if (kill) { - println("Excluded " + javaSourceFile); - } - return !kill; - } - ).toList(); - }); - } - if (javacBuilder.verbose || javacBuilder.parent instanceof JarBuilder jarBuilder && jarBuilder.verbose) { - print("javac " + result.opts.spaceSeparated()); - result.sourceFiles.forEach(s -> print(s + " ")); - println(""); - } - JavaCompiler.CompilationTask compilationTask = - (javac.getTask( - new PrintWriter(System.err), - javac.getStandardFileManager(diagnosticListener, null, null), - diagnosticListener, - result.opts.strings, - null, - result.sourceFiles - )); - JavacTask javacTask = (JavacTask) compilationTask; - - javacTask.generate().forEach(javaFileObject -> { - result.classes.add(javaFileObject); - }); - if (failed[0]) { - throw new RuntimeException("javac failed"); - } - return result; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public static JavacBuilder javacBuilder(Consumer<JavacBuilder> javacBuilderConsumer) { - JavacBuilder javacBuilder = new JavacBuilder(); - javacBuilderConsumer.accept(javacBuilder); - return javacBuilder; - } - - public static JavacResult javac(Consumer<JavacBuilder> javacBuilderConsumer) { - return javac(javacBuilder(javacBuilderConsumer)); - } - - public static final class JavaBuilder extends JavaToolBuilder<JavaBuilder> { - public String mainClass; - public DirPath libraryPath; - public boolean startOnFirstThread; - public Strings args = new Strings(); - public Strings nativeAccessModules = new Strings(); - private boolean headless; - - public JavaBuilder enable_native_access(String module) { - nativeAccessModules.add(module); - return self(); - } - - public JavaBuilder enable_native_access_to_all_unnamed() { - return enable_native_access("ALL-UNNAMED"); - } - - public JavaBuilder args(List<String> args) { - this.args.add(args); - return self(); - } - - public JavaBuilder args(String... args) { - args(Arrays.asList(args)); - return self(); - } - - public JavaBuilder main_class(String mainClass) { - this.mainClass = mainClass; - return this; - } - - public JavaBuilder library_path(List<DirPathHolder<?>> libraryPathEntries) { - this.libraryPath = DirPath.ofOrUse(this.libraryPath).add(libraryPathEntries); - return this; - } - - public JavaBuilder library_path(DirPath libraryPathEntries) { - this.libraryPath = DirPath.ofOrUse(this.libraryPath).add(libraryPathEntries); - return this; - } - - public JavaBuilder library_path(DirPathHolder<?>... libraryPathEntries) { - return this.library_path(List.of(libraryPathEntries)); - } - - public JavaBuilder start_on_first_thread() { - this.startOnFirstThread = true; - return this; - } - - public void headless() { - this.headless = true; - } - } - - public static final class JavaResult extends Result<JavaBuilder> { - Strings opts = new Strings(); - - JavaResult(JavaBuilder javaBuilder) { - super(javaBuilder); - } - } - - public static JavaBuilder java(JavaBuilder javaBuilder) { - JavaResult result = new JavaResult(javaBuilder); - result.opts.add(javaBuilder.jdk.path().resolve("bin/java").toString()); - if (javaBuilder.enablePreview != null && javaBuilder.enablePreview) { - result.opts.add("--enable-preview"); - } - if (javaBuilder.modules != null) { - javaBuilder.modules.strings.forEach(module -> - result.opts.add("--add-modules", module) - ); - } - - if (javaBuilder.exports != null) { - javaBuilder.exports.forEach(fpt -> { - result.opts.add("--add-exports=" + fpt.fromModule + "/" + fpt.pkg + "=" + fpt.toModule); - }); - } - if (javaBuilder.headless) { - result.opts.add("-Dheadless=true"); - } - if (javaBuilder.startOnFirstThread) { - result.opts.add("-XstartOnFirstThread"); - } - - javaBuilder.nativeAccessModules.strings.forEach(module -> - result.opts.add("--enable-native-access=" + module) - ); - - if (javaBuilder.classPath != null) { - result.opts.add("--class-path", javaBuilder.classPath.charSeparated()); - } - if (javaBuilder.libraryPath != null) { - result.opts.add("-Djava.library.path=" + javaBuilder.libraryPath.charSeparated()); - } - result.opts.add(javaBuilder.mainClass); - result.opts.add(javaBuilder.args.strings); - - try { - var processBuilder = new ProcessBuilder().inheritIO().command(result.opts.strings); - var process = processBuilder.start(); - if (javaBuilder.verbose) { - println(result.opts.spaceSeparated()); - } - process.waitFor(); - } catch (InterruptedException | IOException ie) { - System.out.println(ie); - } - - return javaBuilder; - } - - public static JavaBuilder java(Consumer<JavaBuilder> javaBuilderConsumer) { - JavaBuilder javaBuilder = new JavaBuilder(); - javaBuilderConsumer.accept(javaBuilder); - return java(javaBuilder); - } - - public static JavaBuilder javaBuilder() { - return new JavaBuilder(); - } - - public static final class FormatBuilder extends Builder<FormatBuilder> { - public SourcePath sourcePath; - - public FormatBuilder source_path(List<SourceDir> sourcePaths) { - this.sourcePath = SourcePath.ofOrUse(this.sourcePath).add(sourcePaths); - return this; - } - - public FormatBuilder source_path(SourceDir... sourcePaths) { - return source_path(List.of(sourcePaths)); - } - } - - public static void format(RepoDir repoDir, Consumer<FormatBuilder> formatBuilderConsumer) { - var formatBuilder = new FormatBuilder(); - formatBuilderConsumer.accept(formatBuilder); - var classPathEntries = repoDir.classPathEntries("com.google.googlejavaformat/google-java-format"); - - java($ -> $ - .verbose() - .enable_preview() - .enable_native_access("ALL-UNNAMED") - .add_exports("java.base", "jdk.internal", "ALL-UNNAMED") - .add_exports( - "jdk.compiler", - List.of( - "com.sun.tools.javac.api", - "com.sun.tools.javac.code", - "com.sun.tools.javac.file", - "com.sun.tools.javac.main", - "com.sun.tools.javac.parser", - "com.sun.tools.javac.tree", - "com.sun.tools.javac.util"), - "ALL-UNNAMED") - .class_path(classPathEntries) - .main_class("com.google.googlejavaformat.java.Main") - .args("-r") - .args(formatBuilder.sourcePath.javaFiles().map(Path::toString).toList())); - } - - public static final class TestNGBuilder extends Builder<TestNGBuilder> { - public SourcePath sourcePath; - public ClassPath classPath; - private SuiteBuilder suiteBuilder; - private JarFile testJar; - - public TestNGBuilder class_path(List<ClassPathEntryProvider> classPathEntryProviders) { - this.classPath = ClassPath.ofOrUse(this.classPath).add(classPathEntryProviders); - return this; - } - - public TestNGBuilder class_path(ClassPathEntryProvider... classPathEntryProviders) { - class_path(List.of(classPathEntryProviders)); - return this; - } - - public TestNGBuilder source_path(List<SourceDir> sourcePathEntries) { - this.sourcePath = SourcePath.ofOrUse(this.sourcePath).add(sourcePathEntries); - return this; - } - - public TestNGBuilder source_path(SourceDir... sourcePathEntries) { - return source_path(List.of(sourcePathEntries)); - } - - public TestNGBuilder testJar(JarFile testJar) { - this.testJar = testJar; - return self(); - } - - public static class SuiteBuilder { - String name; - - SuiteBuilder name(String name) { - this.name = name; - return this; - } - - List<TestBuilder> testBuilders = new ArrayList<>(); - - public static class TestBuilder { - String name; - List<String> classNames; - - TestBuilder name(String name) { - this.name = name; - return this; - } - - public TestBuilder classes(List<String> classNames) { - this.classNames = this.classNames == null ? new ArrayList<>() : this.classNames; - this.classNames.addAll(classNames); - return this; - } - - public TestBuilder classes(String... classNames) { - return classes(List.of(classNames)); - } - } - - public void test(String testName, Consumer<TestBuilder> testBuilderConsumer) { - TestBuilder testBuilder = new TestBuilder(); - testBuilder.name(testName); - testBuilderConsumer.accept(testBuilder); - testBuilders.add(testBuilder); - } - } - - public TestNGBuilder suite(String suiteName, Consumer<SuiteBuilder> suiteBuilderConsumer) { - this.suiteBuilder = new SuiteBuilder(); - suiteBuilder.name(suiteName); - suiteBuilderConsumer.accept(suiteBuilder); - return self(); - } - } - - public static void testng(RepoDir repoDir, Consumer<TestNGBuilder> testNGBuilderConsumer) { - var testNGBuilder = new TestNGBuilder(); - testNGBuilderConsumer.accept(testNGBuilder); - - var text = - XMLNode.create( - "suite", - $ -> { - $.attr("name", testNGBuilder.suiteBuilder.name); - testNGBuilder.suiteBuilder.testBuilders.forEach( - tb -> { - $.element( - "test", - $$ -> - $$.attr("name", tb.name) - .element( - "classes", - $$$ -> - tb.classNames.forEach( - className -> - $$$.element( - "class", - $$$$ -> $$$$.attr("name", className))))); - }); - }) - .toString(); - - println(text); - - TestNGSuiteFile testNGSuiteFile = TestNGSuiteFile.containing(text); - var mavenJars = repoDir.classPathEntries("org.testng/testng", "org.slf4j/slf4j-api"); - - - var testJarResult = - jar(jar -> jar - .jarFile(testNGBuilder.testJar) - .javac(javac -> javac - .source(24) - .enable_preview() - .class_path(testNGBuilder.classPath, mavenJars) - .source_path(testNGBuilder.sourcePath) - ) - ); - - java( - $ -> - $.enable_preview() - .add_exports_to_all_unnamed("java.base", "jdk.internal") - .enable_native_access("ALL-UNNAMED") - .class_path(testNGBuilder.classPath, mavenJars, testJarResult) - .main_class("org.testng.TestNG") - .args(testNGSuiteFile.path().toString())); - } - - public static final class JarBuilder extends Builder<JarBuilder> { - public static class Manifest { - public String mainClass; - public String[] classPath; - public String version; - public String createdBy; - public String buildBy; - - public void writeTo(JarOutputStream jarStream) { - PrintWriter printWriter = new PrintWriter(jarStream); - if (version != null) { - printWriter.println("Manifest-Version: " + version); - } - if (mainClass != null) { - printWriter.println("Main-Class: " + mainClass); - } - if (classPath != null) { - printWriter.print("Class-Path:"); - for (String s : classPath) { - printWriter.print(" "); - printWriter.print(s); - } - printWriter.println(); - } - printWriter.flush(); - } - } - - public static final class ManifestBuilder extends Builder<ManifestBuilder> { - - Manifest manifest; - - public ManifestBuilder main_class(String mainClass) { - this.manifest.mainClass = mainClass; - return self(); - } - - public ManifestBuilder version(String version) { - this.manifest.version = version; - return self(); - } - - public ManifestBuilder created_by(String createdBy) { - this.manifest.createdBy = createdBy; - return self(); - } - - public ManifestBuilder build_by(String buildBy) { - this.manifest.buildBy = buildBy; - return self(); - } - - public ManifestBuilder class_path(String... classPath) { - this.manifest.classPath = classPath; - return self(); - } - - public ManifestBuilder class_path(ClassPathEntry... classPathEntries) { - this.manifest.classPath = Stream.of(classPathEntries).map(classPathEntry -> classPathEntry.path().getFileName().toString()).toArray(String[]::new); - return self(); - } - - ManifestBuilder(Manifest manifest) { - this.manifest = manifest; - } - } - - public DirEntry mavenStyleRoot; - public JarFile jar; - public JavacResult javacResult; - public DirPath dirList; - // public String mainClass; - public Manifest manifest; - - public JarBuilder jarFile(JarFile jar) { - this.jar = jar; - return self(); - } - - public JarBuilder maven_style_root(DirEntry mavenStyleRoot) { - this.mavenStyleRoot = mavenStyleRoot; - return this; - } - - public JarBuilder manifest(Consumer<ManifestBuilder> manifestBuilderConsumer) { - this.manifest = this.manifest == null ? new Manifest() : this.manifest; - var manifestBuilder = new ManifestBuilder(manifest); - manifestBuilderConsumer.accept(manifestBuilder); - return self(); - } - - private JarBuilder javac(JavacBuilder javacBuilder) { - this.javacResult = Bldr.javac(javacBuilder); - - this.dirList = - (this.dirList == null) - ? DirPath.of().add(this.javacResult.classDir) - : this.dirList.add(this.javacResult.classDir); - if (mavenStyleRoot != null) { - var resources = mavenStyleRoot.dir("src/main/resources"); - if (resources.exists()) { - this.dirList.add(resources); - } - } - return self(); - } - - public JavacBuilder javacBuilder(Consumer<JavacBuilder> javacBuilderConsumer) { - JavacBuilder javacBuilder = new JavacBuilder(this); - javacBuilderConsumer.accept(javacBuilder); - return javacBuilder; - } - - public JavacBuilder javacBuilder(JavacBuilder copyMe, Consumer<JavacBuilder> javacBuilderConsumer) { - JavacBuilder javacBuilder = new JavacBuilder(this); - javacBuilder.dontCallThisCopy(copyMe); - javacBuilderConsumer.accept(javacBuilder); - return javacBuilder; - } - - public JarBuilder javac(Consumer<JavacBuilder> javacBuilderConsumer) { - return javac(javacBuilder(javacBuilderConsumer)); - } - - public JarBuilder javac(JavacBuilder copyMe, Consumer<JavacBuilder> javacBuilderConsumer) { - return javac(javacBuilder(copyMe, javacBuilderConsumer)); - } - - @SuppressWarnings("unchecked") - public <P extends DirPathHolder<P>> JarBuilder dir_list(P... holders) { - Arrays.asList(holders).forEach(holder -> - this.dirList = DirPath.ofOrUse(this.dirList).add(holder) - ); - return self(); - } - - @SuppressWarnings("unchecked") - public <P extends DirPathHolder<P>> JarBuilder add(P... holders) { - Arrays.asList(holders).forEach(holder -> - this.dirList = DirPath.ofOrUse(this.dirList).add(holder) - ); - return self(); - } - } - - public static final class JarResult extends Result<JarBuilder> implements ClassPathEntryProvider { - public Strings opts = new Strings(); - public List<RootDirAndSubPath> pathsToJar = new ArrayList<>(); - public List<Path> paths = new ArrayList<>(); - public JarFile jarFile; - - - public JarResult(JarBuilder jarBuilder) { - super(jarBuilder); - this.jarFile = jarBuilder.jar; - } - - @Override - public List<ClassPathEntry> classPathEntries() { - return List.of(jarFile); - } - - @Override - public String toString() { - return jarFile.path.toString(); - } - } - - public static JarResult jar(JarBuilder jarBuilder) { - - JarResult result = new JarResult(jarBuilder); - try { - - var jarStream = new JarOutputStream(Files.newOutputStream(jarBuilder.jar.path())); - if (jarBuilder.dirList == null) { - throw new RuntimeException("Nothing to jar "); - } - if (jarBuilder.manifest != null) { - // We must add manifest - var entry = new JarEntry("META-INF/MANIFEST.MF"); - // entry.setTime(Files.getLastModifiedTime(rootAndPath.path()).toMillis()); - - jarStream.putNextEntry(entry); - jarBuilder.manifest.writeTo(jarStream); - jarStream.closeEntry(); - - } - jarBuilder.dirList.entries.forEach( - root -> - root.findFiles() - .map(path -> new RootDirAndSubPath(root, path)) - .forEach(result.pathsToJar::add)); - result.pathsToJar.stream() - .sorted(Comparator.comparing(RootDirAndSubPath::path)) - .forEach( - rootAndPath -> { - try { - result.paths.add(rootAndPath.path); - var entry = new JarEntry(rootAndPath.relativize().toString()); - entry.setTime(Files.getLastModifiedTime(rootAndPath.path()).toMillis()); - jarStream.putNextEntry(entry); - Files.newInputStream(rootAndPath.path()).transferTo(jarStream); - jarStream.closeEntry(); - if (jarBuilder.verbose) { - println("INFO: adding " + rootAndPath.relativize().toString()); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - }); - jarStream.finish(); - jarStream.close(); - if (jarBuilder.verbose) { - println("INFO: created " + jarBuilder.jar.path.toString()); - } - return result; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public static JarBuilder jarBuilder(Consumer<JarBuilder> jarBuilderConsumer) { - JarBuilder jarBuilder = new JarBuilder(); - jarBuilderConsumer.accept(jarBuilder); - return jarBuilder; - } - - public static JarBuilder jarBuilder(JarBuilder copyMe, Consumer<JarBuilder> jarBuilderConsumer) { - JarBuilder jarBuilder = new JarBuilder(); - jarBuilder.dontCallThisCopy(copyMe); - jarBuilderConsumer.accept(jarBuilder); - return jarBuilder; - } - - public static JarResult jar(Consumer<JarBuilder> jarBuilderConsumer) { - return jar(jarBuilder(jarBuilderConsumer)); - } - - public static JarResult jar(JarBuilder copyMe, Consumer<JarBuilder> jarBuilderConsumer) { - return jar(jarBuilder(copyMe, jarBuilderConsumer)); - } - - public static final class CMakeBuilder extends Builder<CMakeBuilder> { - public List<String> libraries = new ArrayList<>(); - public CMakeBuildDir cmakeBuildDir; - public DirEntry sourceDir; - private Path output; - public BuildDir copyToDir; - public List<String> opts = new ArrayList<>(); - - public CMakeBuilder opts(List<String> opts) { - this.opts.addAll(opts); - return self(); - } - - public CMakeBuilder opts(String... opts) { - opts(Arrays.asList(opts)); - return self(); - } - - public CMakeBuilder() { - opts.add("cmake"); - } - - public CMakeBuilder build_dir(CMakeBuildDir cmakeBuildDir) { - this.cmakeBuildDir = cmakeBuildDir; - opts("-B", cmakeBuildDir.path.toString()); - return this; - } - - public CMakeBuilder copy_to(BuildDir copyToDir) { - this.copyToDir = copyToDir; - opts("-DHAT_TARGET=" + this.copyToDir.path().toString()); - return this; - } - - public CMakeBuilder source_dir(DirEntry sourceDir) { - this.sourceDir = sourceDir; - opts("-S", sourceDir.path().toString()); - return this; - } - - public CMakeBuilder build(CMakeBuildDir cmakeBuildDir) { - this.cmakeBuildDir = cmakeBuildDir; - opts("--build", cmakeBuildDir.path().toString()); - return this; - } - } - - public static void cmake(Consumer<CMakeBuilder> cmakeBuilderConsumer) { - CMakeBuilder cmakeBuilder = new CMakeBuilder(); - cmakeBuilderConsumer.accept(cmakeBuilder); - cmakeBuilder.cmakeBuildDir.create(); - try { - var processBuilder = new ProcessBuilder().inheritIO().command(cmakeBuilder.opts); - var process = processBuilder.start(); - if (cmakeBuilder.verbose) { - print(cmakeBuilder.opts); - } - process.waitFor(); - } catch (InterruptedException | IOException ie) { - System.out.println(ie); - } - } - - static Path unzip(Path in, Path dir) { - try { - Files.createDirectories(dir); - ZipFile zip = new ZipFile(in.toFile()); - zip.entries() - .asIterator() - .forEachRemaining( - entry -> { - try { - String currentEntry = entry.getName(); - - Path destFile = dir.resolve(currentEntry); - // destFile = new File(newPath, destFile.getName()); - Path destinationParent = destFile.getParent(); - Files.createDirectories(destinationParent); - // create the parent directory structure if needed - - if (!entry.isDirectory()) { - zip.getInputStream(entry).transferTo(Files.newOutputStream(destFile)); - } - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } - }); - zip.close(); - - } catch (IOException e) { - throw new RuntimeException(e); - } - return dir; - } - - - public static final class JExtractBuilder extends Builder<JExtractBuilder> { - public Strings compileFlags = new Strings(); - public List<Path> libraries = new ArrayList<>(); - public List<Path> headers = new ArrayList<>(); - private String targetPackage; - private String headerClassName; - private BuildDir output; - - protected JExtractBuilder dontCallThisCopy(JExtractBuilder other) { - this.compileFlags = new Strings(other.compileFlags); - if (other.targetPackage != null) { - throw new RuntimeException("You are copying jextract builder already bound to a target package"); - } - if (other.output != null) { - throw new RuntimeException("You are copying jextract builder already bound to output directory"); - } - if (!other.libraries.isEmpty()) { - throw new RuntimeException("You are copying jextract builder already bound to library(ies)"); - } - if (!other.headers.isEmpty()) { - throw new RuntimeException("You are copying jextract builder already bound to headers library(ies)"); - } - return self(); - } - - public JExtractBuilder target_package(String targetPackage) { - this.targetPackage = targetPackage; - return self(); - } - - public JExtractBuilder header_class_name(String headerClassName) { - this.headerClassName = headerClassName; - return self(); - } - - public JExtractBuilder output(BuildDir output) { - this.output = output; - return self(); - } - - public JExtractBuilder library(Path... libraries) { - this.libraries.addAll(Arrays.asList(libraries)); - return self(); - } - - public JExtractBuilder compile_flag(String... compileFlags) { - this.compileFlags.add(compileFlags); - return self(); - } - - public JExtractBuilder header(Path header) { - this.headers.add(header); - return self(); - } - - public JExtractBuilder capability(Capabilities.Jextractable jextractable, BuildDir stageDir) { - output(jextractable.stage(stageDir)) - .target_package(jextractable.packageName()) - .header_class_name(jextractable.headerClassName()); - jextractable.inversionOfControl(this); - return self(); - } - } - - public static final class JExtractResult extends Result<JExtractBuilder> { - public Strings opts = new Strings(); - - JExtractResult(JExtractBuilder builder) { - super(builder); - } - } - - public static JExtractResult jextract(Capabilities.JExtract jextract, Consumer<JExtractBuilder> jextractBuilderConsumer) { - return jextract(JExtractExecutable.of(jextract.path()),jextractBuilderConsumer); - } - - - public static JExtractResult jextract(JExtractExecutable executable, Consumer<JExtractBuilder> jextractBuilderConsumer) { - - var exePath = executable.path; - var homePath = exePath.getParent().getParent(); - - JExtractBuilder jExtractBuilder = new JExtractBuilder(); - JExtractResult result = new JExtractResult(jExtractBuilder); - jextractBuilderConsumer.accept(jExtractBuilder); - result.opts.add(executable.path().toString()); - - if (jExtractBuilder.targetPackage != null) { - result.opts.add("--target-package", jExtractBuilder.targetPackage); - } - if (jExtractBuilder.output != null) { - jExtractBuilder.output.create(); - result.opts.add("--output", jExtractBuilder.output.path().toString()); - } - for (Path library : jExtractBuilder.libraries) { - result.opts.add("--library", ":" + library); - } - - - if (jExtractBuilder.headers.isEmpty()) { - throw new RuntimeException("No headers specified"); - } - for (Path header : jExtractBuilder.headers) { - if (jExtractBuilder.headerClassName != null) { - result.opts.add("--header-class-name", jExtractBuilder.headerClassName); - System.out.println("header and class name: " + header.toString() + " with " + jExtractBuilder.headerClassName); - } else { - System.out.println("header: " + header.toString() + " no header className"); - } - result.opts.add(header.toString()); - } - - - if (jExtractBuilder.compileFlags != null && !jExtractBuilder.compileFlags.strings.isEmpty()) { - jExtractBuilder.output.textFile("compile_flags.txt", jExtractBuilder.compileFlags.strings); - } - - if (jExtractBuilder.verbose) { - println(result.opts.spaceSeparated()); - } - var processBuilder = new ProcessBuilder(); - if (jExtractBuilder.output != null) { - processBuilder.directory(jExtractBuilder.output.path().toFile()); - } - processBuilder.inheritIO().command(result.opts.strings); - try { - processBuilder.start().waitFor(); - } catch (InterruptedException | IOException ie) { - throw new RuntimeException(ie); - } - return result; - } - - public record SearchableTextFile(Path path) implements TextFile { - static SearchableTextFile of(Path path) { - return new SearchableTextFile(path); - } - - public Stream<Line> lines() { - try { - int num[] = new int[]{1}; - return Files.readAllLines(path(), StandardCharsets.UTF_8).stream() - .map(line -> new Line(line, num[0]++)); - } catch (IOException ioe) { - System.out.println(ioe); - return new ArrayList<Line>().stream(); - } - } - - public boolean grep(Pattern pattern) { - return lines().anyMatch(line -> pattern.matcher(line.line).matches()); - } - - public boolean hasSuffix(String... suffixes) { - var suffixSet = Set.of(suffixes); - int dotIndex = path().toString().lastIndexOf('.'); - return dotIndex == -1 || suffixSet.contains(path().toString().substring(dotIndex + 1)); - } - } - - public record Line(String line, int num) { - public boolean grep(Pattern pattern) { - return pattern.matcher(line()).matches(); - } - } - - public static Path curl(URL url, Path file) { - try { - println("Downloading " + url + "->" + file); - url.openStream().transferTo(Files.newOutputStream(file)); - } catch (IOException e) { - throw new RuntimeException(e); - } - return file; - } - - public static Optional<Path> which(String execName) { - // which and whereis had issues. - return Arrays.asList(System.getenv("PATH").split(File.pathSeparator)).stream() - .map(dirName -> Path.of(dirName).resolve(execName).normalize()) - .filter(Files::isExecutable) - .findFirst(); - } - - public static boolean canExecute(String execName) { - return which(execName).isPresent(); - } - - public static Path untar(Path tarFile, Path dir) { - try { - new ProcessBuilder() - .inheritIO() - .command("tar", "xvf", tarFile.toString(), "--directory", tarFile.getParent().toString()) - .start() - .waitFor(); - return dir; - } catch ( - InterruptedException - e) { // We get IOException if the executable not found, at least on Mac so interuppted - // means it exists - return null; - } catch (IOException e) { // We get IOException if the executable not found, at least on Mac - // throw new RuntimeException(e); - return null; - } - } - - public static Optional<Path> fromPATH(String name) { - return Arrays.stream(System.getenv("PATH").split(File.pathSeparator)) - .map(dirName -> Path.of(dirName).resolve(name).normalize()) - .filter(Files::isExecutable).findFirst(); - } - - - public static <T extends PathHolder> T assertExists(T testme) { - if (Files.exists(testme.path())) { - return testme; - } else { - throw new IllegalStateException("FAILED: " + testme.path() + " does not exist"); - } - } - - public static <T extends Path> T assertExists(T path) { - if (Files.exists(path)) { - return path; - } else { - throw new IllegalStateException("FAILED: " + path + " does not exist"); - } - } - - public static class CMakeProbe implements Capabilities.Probe { - public interface CMakeVar<T> { - String name(); - - T value(); - } - - public record CMakeTypedVar(String name, String type, String value, String comment) - implements CMakeVar<String> { - static final Regex regex = Regex.of("^_*(?:CMAKE_)?([A-Za-z0-9_]+):([^=]*)=(.*)$"); - - CMakeTypedVar(Matcher matcher, String comment) { - this( - "CMAKE_" + matcher.group(1).trim(), - matcher.group(2).trim(), - matcher.group(3).trim(), - comment.substring(2).trim()); - } - - static boolean onMatch(String line, String comment, Consumer<CMakeTypedVar> consumer) { - return regex.matches(line, matcher -> consumer.accept(new CMakeTypedVar(matcher, comment))); - } - } - - public record CMakeSimpleVar(String name, String value) implements CMakeVar { - static final Regex regex = Regex.of("^_*(?:CMAKE_)?([A-Za-z0-9_]+)=\\{<\\{(.*)\\}>\\}$"); - - CMakeSimpleVar(Matcher matcher) { - this( - "CMAKE_" + matcher.group(1).trim(), - (matcher.group(2).isEmpty()) ? "" : matcher.group(2).trim()); - } - - static boolean onMatch(String line, String comment, Consumer<CMakeSimpleVar> consumer) { - return regex.matches(line, matcher -> consumer.accept(new CMakeSimpleVar(matcher))); - } - } - - public record CMakeDirVar(String name, DirPathHolder value) implements CMakeVar { - static final Regex regex = Regex.of("^_*(?:CMAKE_)?([A-Za-z0-9_]+)=\\{<\\{(.*)\\}>\\}$"); - - static boolean onMatch(String line, String comment, Consumer<CMakeSimpleVar> consumer) { - return regex.matches(line, matcher -> consumer.accept(new CMakeSimpleVar(matcher))); - } - } - - public record CMakeContentVar(String name, String value) implements CMakeVar { - static final Regex startRegex = Regex.of("^_*(?:CMAKE_)?([A-Za-z0-9_]+)=\\{<\\{(.*)$"); - static final Regex endRegex = Regex.of("^(.*)\\}>\\}$"); - } - - public record CMakeRecipeVar(String name, String value) implements CMakeVar<String> { - static final Regex varPattern = Regex.of("<([^>]*)>"); - static final Regex regex = Regex.of("^_*(?:CMAKE_)?([A-Za-z0-9_]+)=\\{<\\{<(.*)>\\}>\\}$"); - - CMakeRecipeVar(Matcher matcher) { - this( - "CMAKE_" + matcher.group(1).trim(), - "<" + ((matcher.group(2).isEmpty()) ? "" : matcher.group(2).trim()) + ">"); - } - - public String expandRecursively(Map<String, CMakeVar<?>> varMap, String value) { // recurse - String result = value; - if (varPattern.pattern().matcher(value) instanceof Matcher matcher && matcher.find()) { - var v = matcher.group(1); - if (varMap.containsKey(v)) { - String replacement = varMap.get(v).value().toString(); - result = - expandRecursively( - varMap, - value.substring(0, matcher.start()) - + replacement - + value.substring(matcher.end())); - } - } - return result; - } - - public String expand(Map<String, CMakeVar<?>> vars) { - return expandRecursively(vars, value()); - } - - static boolean onMatch(String line, String comment, Consumer<CMakeRecipeVar> consumer) { - return regex.matches(line, matcher -> consumer.accept(new CMakeRecipeVar(matcher))); - } - } - - BuildDir dir; - - Map<String, CMakeVar<?>> varMap = new HashMap<>(); - - public CMakeProbe(BuildDir dir, Capabilities capabilities) { - this.dir = BuildDir.of(dir.path("cmakeprobe")); - this.dir.clean(); - - try { - this.dir.cmakeLists(cmakeLists -> { - cmakeLists.append( - """ - cmake_minimum_required(VERSION 3.21) - project(cmakeprobe) - set(CMAKE_CXX_STANDARD 14) - """ - ); - - capabilities.capabilities() - .filter(capability -> capability instanceof Capabilities.CMakeProbeable) - .map(capability -> (Capabilities.CMakeProbeable) capability) - .forEach(p -> - cmakeLists.append(p.cmakeStanza()).append("\n") - ); - cmakeLists.append( - """ - get_cmake_property(_variableNames VARIABLES ${VarNames}) - foreach(VarName ${_variableNames}) - message("${VarName}={<{${${VarName}}}>}") - endforeach() - """ - ); - }); - - var cmakeProcessBuilder = - new ProcessBuilder() - .directory(this.dir.path().toFile()) - .redirectErrorStream(true) - .command("cmake", "-LAH") - .start(); - List<String> stdinlines = - new BufferedReader(new InputStreamReader(cmakeProcessBuilder.getInputStream())) - .lines() - .toList(); - cmakeProcessBuilder.waitFor(); - this.dir.textFile("rawlines", sb -> { - stdinlines.forEach(line -> sb.append(line).append("\n")); - // stderrlines.forEach(line-> sb.append("ERR").append(line).append("\n")); - }); - - String comment = null; - String contentName = null; - StringBuilder content = null; - - for (String line : stdinlines) { - if (line.startsWith("//")) { - comment = line; - content = null; - - } else if (comment != null) { - if (CMakeTypedVar.onMatch( - line, - comment, - v -> { - if (varMap.containsKey(v.name())) { - var theVar = varMap.get(v.name()); - if (theVar.value().equals(v.value())) { - /* println( - "replacing duplicate variable with typed variant with the name same value" - + v - + theVar);*/ - } else { - throw new IllegalStateException( - "Duplicate variable name different value: " + v + theVar); - } - varMap.put(v.name(), v); - } else { - varMap.put(v.name(), v); - } - })) { - } else { - println("failed to parse " + line); - } - comment = null; - content = null; - contentName = null; - } else if (!line.isEmpty()) { - if (content != null) { - if (CMakeContentVar.endRegex.pattern().matcher(line) instanceof Matcher matcher - && matcher.matches()) { - content.append("\n").append(matcher.group(1)); - var v = new CMakeContentVar(contentName, content.toString()); - contentName = null; - content = null; - varMap.put(v.name(), v); - } else { - content.append("\n").append(line); - } - } else if (!line.endsWith("}>}") - && CMakeContentVar.startRegex.pattern().matcher(line) instanceof Matcher matcher - && matcher.matches()) { - contentName = "CMAKE_" + matcher.group(1); - content = new StringBuilder(matcher.group(2)); - } else if (CMakeRecipeVar.regex.pattern().matcher(line) instanceof Matcher matcher - && matcher.matches()) { - CMakeVar<String> v = new CMakeRecipeVar(matcher); - if (varMap.containsKey(v.name())) { - var theVar = varMap.get(v.name()); - if (theVar.value().equals(v.value())) { - // println("Skipping duplicate variable name different value: " + v + theVar); - } else { - throw new IllegalStateException( - "Duplicate variable name different value: " + v + theVar); - } - varMap.put(v.name(), v); - } else { - varMap.put(v.name(), v); - } - } else if (CMakeSimpleVar.regex.pattern().matcher(line) instanceof Matcher matcher - && matcher.matches()) { - var v = new CMakeSimpleVar(matcher); - if (varMap.containsKey(v.name())) { - var theVar = varMap.get(v.name()); - if (theVar.value().equals(v.value())) { - // println("Skipping duplicate variable name different value: " + v + theVar); - } else { - //throw new IllegalStateException( - // "Duplicate variable name different vars: " + v + theVar); - } - // note we don't replace a Typed with a Simple - } else { - varMap.put(v.name(), v); - } - } else { - // println("Skipping " + line); - } - } - } - - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - this.dir.textFile("vars", sb -> { - varMap.values().forEach(v -> sb.append(v.name()).append("<{<").append(v.value().toString()).append(">}>").append("\n")); - }); - - capabilities - .capabilities() - .filter(capability -> capability instanceof Capabilities.CMakeProbeable) - .map(capability -> (Capabilities.CMakeProbeable) capability) - .forEach(capability -> capability.accept(this)); - - } - - ObjectFile cxxCompileObject( - ObjectFile target, CppSourceFile source, List<String> frameworks) { - CMakeRecipeVar compileObject = (CMakeRecipeVar) varMap.get("CMAKE_CXX_COMPILE_OBJECT"); - Map<String, CMakeVar<?>> localVars = new HashMap<>(varMap); - localVars.put("DEFINES", new CMakeSimpleVar("DEFINES", "")); - localVars.put("INCLUDES", new CMakeSimpleVar("INCLUDES", "")); - localVars.put("FLAGS", new CMakeSimpleVar("FLAGS", "")); - localVars.put("OBJECT", new CMakeSimpleVar("OBJECT", target.path().toString())); - localVars.put("SOURCE", new CMakeSimpleVar("SOURCE", source.path().toString())); - String executable = compileObject.expand(localVars); - println(executable); - return target; - } - - ExecutableFile cxxLinkExecutable( - ExecutableFile target, List<ObjectFile> objFiles, List<String> frameworks) { - CMakeRecipeVar linkExecutable = (CMakeRecipeVar) varMap.get("CMAKE_CXX_LINK_EXECUTABLE"); - Map<String, CMakeVar<?>> localVars = new HashMap<>(varMap); - String executable = linkExecutable.expand(localVars); - println(executable); - return target; - } - - SharedLibraryFile cxxCreateSharedLibrary( - SharedLibraryFile target, List<ObjectFile> objFiles, List<String> frameworks) { - CMakeRecipeVar createSharedLibrary = - (CMakeRecipeVar) varMap.get("CMAKE_CXX_CREATE_SHARED_LIBRARY"); - Map<String, CMakeVar<?>> localVars = new HashMap<>(varMap); - String executable = createSharedLibrary.expand(localVars); - println(executable); - return target; - } - - - public String value(String key) { - var v = varMap.get(key); - return v.value().toString(); - } - - public boolean hasKey(String includeDirKey) { - return varMap.containsKey(includeDirKey); - } - - } - - public interface CapabilityHolder { - Capabilities.Capability capability(); - } - - public static class Capabilities { - - interface Probe { - - } - - public static abstract class Capability implements CapabilityHolder { - final public String name; - - protected Capability(String name) { - this.name = name; - } - - public String name() { - return name; - } - - public abstract boolean available(); - - @Override - public Capability capability() { - return this; - } - } - - public interface CMakeProbeable extends Consumer<Bldr.CMakeProbe> { - - // void setCmakeProbe(Bldr.CMakeProbe cmakeProbe); - String cmakeStanza(); - } - - public interface Jextractable { - - - String name(); - - - default BuildDir stage(BuildDir stage) { - return stage.buildDir(packageName() + "_jextracted"); - } - - - default String packageName() { - return name().toLowerCase(); - } - - - default String headerClassName() { - return packageName() + "_h"; - } - - default JarFile jarFile(BuildDir buildDir) { - return buildDir.jarFile("hat-jextracted-"+packageName() + "-1.0.jar"); - } - - void inversionOfControl(JExtractBuilder jextractBuilder); - } - - public Map<String, Capability> capabilityMap = new HashMap<>(); - - public static Capabilities of(CapabilityHolder... capabilityHolders) { - return new Capabilities(capabilityHolders); - } - - public Stream<Capability> capabilities() { - return capabilityMap.values().stream(); - } - - public Stream<Capability> capabilities(Predicate<Capability> filter) { - return capabilities().filter(filter); - } - - public boolean capabilityIsAvailable(String name) { - return capabilities().anyMatch(c -> c.name.equalsIgnoreCase(name)); - } - - private Capabilities(CapabilityHolder... capabilityHolders) { - List.of(capabilityHolders).forEach(capabilityHolder -> - capabilityMap.put(capabilityHolder.capability().name, capabilityHolder.capability()) - ); - - } - - public static final class OpenCL extends Capability implements CMakeProbeable, Jextractable { - public static String includeDirKey = "CMAKE_OpenCL_INCLUDE_DIR"; - public static String libKey = "CMAKE_OpenCL_LIBRARY"; - public static String foundKey = "CMAKE_OPENCL_FOUND"; - public static String osxSysroot = "CMAKE_OSX_SYSROOT"; - - public OpenCL() { - super("OpenCL"); - } - - public static OpenCL of() { - return new OpenCL(); - } - - @Override - public String cmakeStanza() { - return - """ - find_package(OpenCL) - if(OPENCL_FOUND) - if (APPLE) - set(OPENCL_INCLUDE_DIR "-framework OpenCL") - set(OPENCL_LIBRARY_DIR "-framework OpenCL") - else() - set(OPENCL_LIB "OpenCL") - endif() - endif() - """; - } - - public String appLibFrameworks() { - return cmakeProbe.value(osxSysroot); - } - - @Override - public boolean available() { - return cmakeProbe.hasKey(foundKey) && cmakeProbe.value(foundKey).equals("TRUE"); - } - - public String lib() { - return cmakeProbe.value(libKey); - } - - public String includeDir() { - return cmakeProbe.value(includeDirKey); - } - - public Bldr.CMakeProbe cmakeProbe; - - @Override - public void accept(Bldr.CMakeProbe cmakeProbe) { - this.cmakeProbe = cmakeProbe; - } - - - @Override - public void inversionOfControl(JExtractBuilder jextractBuilder) { - jextractBuilder.os(mac -> jextractBuilder - .compile_flag("-F" - + appLibFrameworks() + "/System/library/Frameworks") - .library(mac.frameworkLibrary("OpenCL")) - .header(Path.of(includeDir()).resolve("Headers/opencl.h")), - linux -> { - throw new IllegalStateException("Linux not handled yet"); - }); - } - } - - public static final class OpenGL extends Capability implements CMakeProbeable, Jextractable { - public static String glutIncludeDirKey = "CMAKE_GLUT_INCLUDE_DIR"; - public static String openGLIncludeDirKey = "CMAKE_OPENGL_INCLUDE_DIR"; - public static String libKey = "CMAKE_OPENGL_LIBRARY"; - public static String osxSysroot = "CMAKE_OSX_SYSROOT"; - - public OpenGL() { - super("OpenGL"); - } - - public static OpenGL of() { - return new OpenGL(); - } - - @Override - public boolean available() { - return cmakeProbe.hasKey(openGLIncludeDirKey); - } - - public DirEntry openglIncludeDir() { - return DirEntry.of(Path.of(cmakeProbe.value(openGLIncludeDirKey)) + "/Headers"); - } - - public DirEntry glutIncludeDir() { - return DirEntry.of(cmakeProbe.value(osxSysroot)+"/System/Library/Frameworks/GLUT.framework/Headers"); - } - - public String appLibFrameworks() { - return cmakeProbe.value(osxSysroot); - } - - public String lib() { - return cmakeProbe.value(libKey); - } - - public Path lib(String frameworkName) { - return Path.of(cmakeProbe.value(libKey).split(";")[0]).resolve(frameworkName + ".framework/" + frameworkName); - } - - @Override - public String cmakeStanza() { - return - """ - find_package(OpenGL) - if(OPENGL_FOUND) - if (APPLE) - set(OPENGL_FRAMEWORK "-framework OpenGL") - else() - set(OPENCL_LIB "OpenCL") - endif() - else() - message("NO OPENGL FOUND") - endif() - """; - } - - public Bldr.CMakeProbe cmakeProbe; - - @Override - public void accept(Bldr.CMakeProbe cmakeProbe) { - - this.cmakeProbe = cmakeProbe; -/* - cmakeProbe.varMap.forEach((k, v) -> { - if (k.toUpperCase().contains("OPENGL")) { - println(k); - } - if (k.toUpperCase().contains("GLUT")) { - println(k); - } - }); */ - - } - @Override public void inversionOfControl(JExtractBuilder jextractBuilder){ - jextractBuilder - .os(mac -> jextractBuilder - .compile_flag("-F" - + appLibFrameworks() + "/System/library/Frameworks") - .library(mac.frameworkLibrary("OpenGL")) - .library(mac.frameworkLibrary("GLUT")) - .header(glutIncludeDir().dir("glut.h").path()), - linux -> { - throw new IllegalStateException("Linux not handled yet"); - } - ); - } - } - - public static final class HIP extends Capability implements CMakeProbeable, Jextractable { - public HIP() { - super("HIP"); - } - - public static HIP of() { - return new HIP(); - } - - @Override - public boolean available() { - return false; - } - - @Override - public String cmakeStanza() { - return - """ - find_package(HIP) - if(HIP_FOUND) - - else() - message("NO HIP FOUND") - endif() - """; - } - - public Bldr.CMakeProbe cmakeProbe; - - @Override - public void accept(Bldr.CMakeProbe cmakeProbe) { - - this.cmakeProbe = cmakeProbe; - } - - @Override - public void inversionOfControl(JExtractBuilder jextractBuilder) { - - } - } - - public static final class CUDA extends Capability implements CMakeProbeable, Jextractable { - public static String sdkRootDirKey = "CMAKE_CUDA_SDK_ROOT_DIR"; - public static String sdkRootDirNotFoundValue = "CUDA_SDK_ROOT_DIR-NOTFOUND"; - - public CUDA() { - super("CUDA"); - } - - public static CUDA of() { - return new CUDA(); - } - - @Override - public boolean available() { - return cmakeProbe.hasKey(sdkRootDirKey) && !cmakeProbe.value(sdkRootDirKey).equals(sdkRootDirNotFoundValue); - } - - @Override - public String cmakeStanza() { - return - """ - find_package(CUDAToolkit) - if(CUDAToolkit_FOUND) - set(CUDA_FOUND true) - set(CUDA_INCLUDE_DIR ${CUDAToolkit_INCLUDE_DIR}) - set(CUDA_LIBRARY_DIR ${CUDAToolkit_LIBRARY_DIR}) - set(CUDA_LIBRARIES "-lcudart -lcuda") - else() - message("NO CUDA FOUND") - endif() - """; - } - - public Bldr.CMakeProbe cmakeProbe; - - @Override - public void accept(Bldr.CMakeProbe cmakeProbe) { - this.cmakeProbe = cmakeProbe; - } - - @Override - public void inversionOfControl(JExtractBuilder jextractBuilder) { - - } - } - - public static final class JExtract extends Capability implements Executable { - public JExtractExecutable executable; - - JExtract() { - super("JExtract"); - var optionalExe = fromPATH("jextract"); - if (optionalExe.isEmpty()) { - // println("jextract not in path"); - } else { - executable = JExtractExecutable.of(optionalExe.get()); - } - - } - - JExtract(Path executable) { - super("JExtract"); - this.executable = JExtractExecutable.of(executable); - } - - @Override - public boolean available() { - return executable != null && executable.exists(); - } - - public static JExtract of() { - return new JExtract(); - } - - public static JExtract of(Path executable) { - return new JExtract(executable); - } - - - @Override - public Path path() { - return executable.path; - } - } - - public static final class CMake extends Capability implements Executable { - public JExtractExecutable executable; - public Bldr.CMakeProbe cmakeProbe; - - CMake() { - super("CMake"); - var optionalExe = fromPATH("cmake"); - if (optionalExe.isEmpty()) { - println("cmake not in path"); - } else { - executable = JExtractExecutable.of(optionalExe.get()); - } - } - - @Override - public boolean available() { - return executable != null && executable.exists(); - } - - public static CMake of() { - return new CMake(); - } - - public void probe(BuildDir buildDir, Capabilities capabilities) { - this.cmakeProbe = new Bldr.CMakeProbe(buildDir, capabilities); - } - - @Override - public Path path() { - return executable.path(); - } - } - - } - - public record Regex(Pattern pattern) { - Regex(String regex) { - this(Pattern.compile(regex)); - } - - public static Regex of(String regexString) { - return new Regex(regexString); - } - - boolean matches(String text, Consumer<Matcher> matcherConsumer) { - if (pattern().matcher(text) instanceof Matcher matcher && matcher.matches()) { - matcherConsumer.accept(matcher); - return true; - } else { - return false; - } - } - } - - public static class XMLNode { - Element element; - List<XMLNode> children = new ArrayList<>(); - Map<String, String> attrMap = new HashMap<>(); - - public static class AbstractXMLBuilder<T extends AbstractXMLBuilder<T>> { - final public Element element; - - @SuppressWarnings("unchecked") - public T self() { - return (T) this; - } - - public T attr(String name, String value) { - element.setAttribute(name, value); - return self(); - } - - public T attr(URI uri, String name, String value) { - element.setAttributeNS(uri.toString(), name, value); - return self(); - } - - public T element(String name, Function<Element, T> factory, Consumer<T> xmlBuilderConsumer) { - var node = element.getOwnerDocument().createElement(name); - element.appendChild(node); - var builder = factory.apply(node); - xmlBuilderConsumer.accept(builder); - return self(); - } - - public T element( - URI uri, String name, Function<Element, T> factory, Consumer<T> xmlBuilderConsumer) { - var node = element.getOwnerDocument().createElementNS(uri.toString(), name); - element.appendChild(node); - var builder = factory.apply(node); - xmlBuilderConsumer.accept(builder); - return self(); - } - - AbstractXMLBuilder(Element element) { - this.element = element; - } - - public T text(String thisText) { - var node = element.getOwnerDocument().createTextNode(thisText); - element.appendChild(node); - return self(); - } - - public T comment(String thisComment) { - var node = element.getOwnerDocument().createComment(thisComment); - element.appendChild(node); - return self(); - } - - <L> T forEach(List<L> list, BiConsumer<T, L> biConsumer) { - list.forEach(l -> biConsumer.accept(self(), l)); - return self(); - } - - <L> T forEach(Stream<L> stream, BiConsumer<T, L> biConsumer) { - stream.forEach(l -> biConsumer.accept(self(), l)); - return self(); - } - - <L> T forEach(Stream<L> stream, Consumer<L> consumer) { - stream.forEach(consumer); - return self(); - } - - protected T then(Consumer<T> xmlBuilderConsumer) { - xmlBuilderConsumer.accept(self()); - return self(); - } - } - - public static class PomXmlBuilder extends AbstractXMLBuilder<PomXmlBuilder> { - PomXmlBuilder(Element element) { - super(element); - } - - public PomXmlBuilder element(String name, Consumer<PomXmlBuilder> xmlBuilderConsumer) { - return element(name, PomXmlBuilder::new, xmlBuilderConsumer); - } - - public PomXmlBuilder element(URI uri, String name, Consumer<PomXmlBuilder> xmlBuilderConsumer) { - return element(uri, name, PomXmlBuilder::new, xmlBuilderConsumer); - } - - public PomXmlBuilder modelVersion(String s) { - return element("modelVersion", $ -> $.text(s)); - } - - public PomXmlBuilder pom(String groupId, String artifactId, String version) { - return modelVersion("4.0.0").packaging("pom").ref(groupId, artifactId, version); - } - - public PomXmlBuilder jar(String groupId, String artifactId, String version) { - return modelVersion("4.0.0").packaging("jar").ref(groupId, artifactId, version); - } - - public PomXmlBuilder groupId(String s) { - return element("groupId", $ -> $.text(s)); - } - - public PomXmlBuilder artifactId(String s) { - return element("artifactId", $ -> $.text(s)); - } - - public PomXmlBuilder packaging(String s) { - return element("packaging", $ -> $.text(s)); - } - - public PomXmlBuilder version(String s) { - return element("version", $ -> $.text(s)); - } - - public PomXmlBuilder build(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("build", pomXmlBuilderConsumer); - } - - public PomXmlBuilder plugins(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("plugins", pomXmlBuilderConsumer); - } - - public PomXmlBuilder plugin( - String groupId, - String artifactId, - String version, - Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element( - "plugin", $ -> $.ref(groupId, artifactId, version).then(pomXmlBuilderConsumer)); - } - - public PomXmlBuilder antPlugin(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return plugin( - "org.apache.maven.plugins", - "maven-antrun-plugin", - "1.8", - pomXmlBuilderConsumer); - } - - public PomXmlBuilder surefirePlugin(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return plugin( - "org.apache.maven.plugins", - "maven-surefire-plugin", - "3.1.2", - pomXmlBuilderConsumer); - } - - public PomXmlBuilder compilerPlugin( - Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return plugin( - "org.apache.maven.plugins", - "maven-compiler-plugin", - "3.11.0", pomXmlBuilderConsumer - ); - } - - public PomXmlBuilder execPlugin(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return plugin("org.codehaus.mojo", "exec-maven-plugin", "3.1.0", pomXmlBuilderConsumer); - } - - - public PomXmlBuilder plugin( - String groupId, String artifactId, Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("plugin", $ -> $.groupIdArtifactId(groupId, artifactId).then(pomXmlBuilderConsumer)); - } - - public PomXmlBuilder plugin(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("plugin", pomXmlBuilderConsumer); - } - - public PomXmlBuilder parent(String groupId, String artifactId, String version) { - return parent(parent -> parent.ref(groupId, artifactId, version)); - } - - public PomXmlBuilder parent(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("parent", pomXmlBuilderConsumer); - } - - public PomXmlBuilder pluginManagement(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("pluginManagement", pomXmlBuilderConsumer); - } - - public PomXmlBuilder file(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("file", pomXmlBuilderConsumer); - } - - public PomXmlBuilder activation(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("activation", pomXmlBuilderConsumer); - } - - public PomXmlBuilder profiles(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("profiles", pomXmlBuilderConsumer); - } - - public PomXmlBuilder profile(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("profile", pomXmlBuilderConsumer); - } - - public PomXmlBuilder arguments(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("arguments", pomXmlBuilderConsumer); - } - - public PomXmlBuilder executions(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("executions", pomXmlBuilderConsumer); - } - - public PomXmlBuilder execution(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("execution", pomXmlBuilderConsumer); - } - - public PomXmlBuilder execIdPhaseConf( - String id, String phase, Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return execution(execution -> execution.id(id).phase(phase).goals(gs -> gs.goal("exec")).configuration(pomXmlBuilderConsumer)); - } - - public PomXmlBuilder exec( - String phase, String executable, Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return execIdPhaseConf( - executable + "-" + phase, - phase, - conf -> conf.executable(executable).arguments(pomXmlBuilderConsumer)); - } - - public PomXmlBuilder cmake( - String id, String phase, Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return execIdPhaseConf( - id, phase, conf -> conf.executable("cmake").arguments(pomXmlBuilderConsumer)); - } - - public PomXmlBuilder cmake(String id, String phase, String... args) { - return execIdPhaseConf( - id, - phase, - conf -> - conf.executable("cmake") - .arguments(arguments -> arguments.forEach(Stream.of(args), arguments::argument))); - } - - public PomXmlBuilder jextract(String id, String phase, String... args) { - return execIdPhaseConf( - id, - phase, - conf -> - conf.executable("jextract") - .arguments(arguments -> arguments.forEach(Stream.of(args), arguments::argument))); - } - - public PomXmlBuilder ant( - String id, String phase, String goal, Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return execution(execution -> execution - .id(id) - .phase(phase) - .goals(gs -> gs.goal(goal)) - .configuration(configuration -> configuration.target(pomXmlBuilderConsumer))); - } - - public PomXmlBuilder goals(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("goals", pomXmlBuilderConsumer); - } - - public PomXmlBuilder target(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("target", pomXmlBuilderConsumer); - } - - public PomXmlBuilder configuration(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("configuration", pomXmlBuilderConsumer); - } - - public PomXmlBuilder compilerArgs(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("compilerArgs", pomXmlBuilderConsumer); - } - - public PomXmlBuilder compilerArgs(String... args) { - return element("compilerArgs", $ -> $.forEach(Stream.of(args), $::arg)); - } - - public PomXmlBuilder properties(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("properties", pomXmlBuilderConsumer); - } - - public PomXmlBuilder dependencies(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("dependencies", pomXmlBuilderConsumer); - } - - public PomXmlBuilder dependsOn(String groupId, String artifactId, String version) { - return element("dependencies", $ -> $.dependency(groupId, artifactId, version)); - } - - public PomXmlBuilder dependsOn(String groupId, String artifactId, String version, String phase) { - return element("dependencies", $ -> $.dependency(groupId, artifactId, version, phase)); - } - - public PomXmlBuilder dependency(String groupId, String artifactId, String version) { - return dependency($ -> $.ref(groupId, artifactId, version)); - } - - public PomXmlBuilder dependency( - String groupId, String artifactId, String version, String scope) { - return dependency($ -> $.ref(groupId, artifactId, version).scope(scope)); - } - - public PomXmlBuilder dependency(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("dependency", pomXmlBuilderConsumer); - } - - public PomXmlBuilder modules(Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - return element("modules", pomXmlBuilderConsumer); - } - - public PomXmlBuilder modules(List<String> modules) { - return element("modules", $ -> $.forEach(modules.stream(), $::module)); - } - - public PomXmlBuilder modules(String... modules) { - return modules(List.of(modules)); - } - - public PomXmlBuilder module(String name) { - return element("module", $ -> $.text(name)); - } - - public PomXmlBuilder property(String name, String value) { - return element(name, $ -> $.text(value)); - } - - public PomXmlBuilder antproperty(String name, String value) { - return element("property", $ -> $.attr("name", name).attr("value", value)); - } - - public PomXmlBuilder scope(String s) { - return element("scope", $ -> $.text(s)); - } - - public PomXmlBuilder phase(String s) { - return element("phase", $ -> $.text(s)); - } - - public PomXmlBuilder argument(String s) { - return element("argument", $ -> $.text(s)); - } - - public PomXmlBuilder goal(String s) { - return element("goal", $ -> $.text(s)); - } - - public PomXmlBuilder copy(String file, String toDir) { - return element("copy", $ -> $.attr("file", file).attr("toDir", toDir)); - } - - public PomXmlBuilder antjar(String basedir, String include, String destfile) { - return element("jar", $ -> $.attr("basedir", basedir).attr("includes", include + "/**").attr("destfile", destfile)); - } - - public PomXmlBuilder echo(String message) { - return element("echo", $ -> $.attr("message", message)); - } - - public PomXmlBuilder echo(String filename, String message) { - return element("echo", $ -> $.attr("message", message).attr("file", filename)); - } - - public PomXmlBuilder mkdir(String dirName) { - return element("mkdir", $ -> $.attr("dir", dirName)); - } - - public PomXmlBuilder groupIdArtifactId(String groupId, String artifactId) { - return groupId(groupId).artifactId(artifactId); - } - - public PomXmlBuilder ref(String groupId, String artifactId, String version) { - return groupIdArtifactId(groupId, artifactId).version(version); - } - - public PomXmlBuilder skip(String string) { - return element("skip", $ -> $.text(string)); - } - - public PomXmlBuilder id(String s) { - return element("id", $ -> $.text(s)); - } - - public PomXmlBuilder arg(String s) { - return element("arg", $ -> $.text(s)); - } - - public PomXmlBuilder argLine(String s) { - return element("argLine", $ -> $.text(s)); - } - - public PomXmlBuilder source(String s) { - return element("source", $ -> $.text(s)); - } - - public PomXmlBuilder target(String s) { - return element("target", $ -> $.text(s)); - } - - public PomXmlBuilder showWarnings(String s) { - return element("showWarnings", $ -> $.text(s)); - } - - public PomXmlBuilder showDeprecation(String s) { - return element("showDeprecation", $ -> $.text(s)); - } - - public PomXmlBuilder failOnError(String s) { - return element("failOnError", $ -> $.text(s)); - } - - public PomXmlBuilder exists(String s) { - return element("exists", $ -> $.text(s)); - } - - public PomXmlBuilder activeByDefault(String s) { - return element("activeByDefault", $ -> $.text(s)); - } - - public PomXmlBuilder executable(String s) { - return element("executable", $ -> $.text(s)); - } - - public PomXmlBuilder workingDirectory(String s) { - return element("workingDirectory", $ -> $.text(s)); - } - } - - public static class ImlBuilder extends AbstractXMLBuilder<ImlBuilder> { - - ImlBuilder(Element element) { - super(element); - } - - public ImlBuilder element(String name, Consumer<ImlBuilder> xmlBuilderConsumer) { - return element(name, ImlBuilder::new, xmlBuilderConsumer); - } - - public ImlBuilder element(URI uri, String name, Consumer<ImlBuilder> xmlBuilderConsumer) { - return element(uri, name, ImlBuilder::new, xmlBuilderConsumer); - } - - public ImlBuilder modelVersion(String s) { - return element("modelVersion", $ -> $.text(s)); - } - - public ImlBuilder groupId(String s) { - return element("groupId", $ -> $.text(s)); - } - - public ImlBuilder artifactId(String s) { - return element("artifactId", $ -> $.text(s)); - } - - public ImlBuilder packaging(String s) { - return element("packaging", $ -> $.text(s)); - } - - public ImlBuilder version(String s) { - return element("version", $ -> $.text(s)); - } - - public ImlBuilder build(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("build", pomXmlBuilderConsumer); - } - - public ImlBuilder plugins(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("plugins", pomXmlBuilderConsumer); - } - - public ImlBuilder plugin( - String groupId, - String artifactId, - String version, - Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element( - "plugin", - $ -> - $.groupIdArtifactIdVersion(groupId, artifactId, version).then(pomXmlBuilderConsumer)); - } - - public ImlBuilder plugin( - String groupId, String artifactId, Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element( - "plugin", $ -> $.groupIdArtifactId(groupId, artifactId).then(pomXmlBuilderConsumer)); - } - - public ImlBuilder plugin(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("plugin", pomXmlBuilderConsumer); - } - - public ImlBuilder parent(String groupId, String artifactId, String version) { - return parent(parent -> parent.groupIdArtifactIdVersion(groupId, artifactId, version)); - } - - public ImlBuilder parent(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("parent", pomXmlBuilderConsumer); - } - - public ImlBuilder pluginManagement(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("pluginManagement", pomXmlBuilderConsumer); - } - - public ImlBuilder file(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("file", pomXmlBuilderConsumer); - } - - public ImlBuilder activation(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("activation", pomXmlBuilderConsumer); - } - - public ImlBuilder profiles(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("profiles", pomXmlBuilderConsumer); - } - - public ImlBuilder profile(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("profile", pomXmlBuilderConsumer); - } - - public ImlBuilder arguments(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("arguments", pomXmlBuilderConsumer); - } - - public ImlBuilder executions(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("executions", pomXmlBuilderConsumer); - } - - public ImlBuilder execution(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("execution", pomXmlBuilderConsumer); - } - - public ImlBuilder goals(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("goals", pomXmlBuilderConsumer); - } - - public ImlBuilder target(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("target", pomXmlBuilderConsumer); - } - - public ImlBuilder configuration(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("configuration", pomXmlBuilderConsumer); - } - - public ImlBuilder compilerArgs(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("compilerArgs", pomXmlBuilderConsumer); - } - - public ImlBuilder properties(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("properties", pomXmlBuilderConsumer); - } - - public ImlBuilder dependencies(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("dependencies", pomXmlBuilderConsumer); - } - - public ImlBuilder dependency(String groupId, String artifactId, String version) { - return dependency($ -> $.groupIdArtifactIdVersion(groupId, artifactId, version)); - } - - public ImlBuilder dependency(String groupId, String artifactId, String version, String scope) { - return dependency($ -> $.groupIdArtifactIdVersion(groupId, artifactId, version).scope(scope)); - } - - public ImlBuilder dependency(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("dependency", pomXmlBuilderConsumer); - } - - public ImlBuilder modules(Consumer<ImlBuilder> pomXmlBuilderConsumer) { - return element("modules", pomXmlBuilderConsumer); - } - - public ImlBuilder module(String name) { - return element("module", $ -> $.text(name)); - } - - public ImlBuilder property(String name, String value) { - return element(name, $ -> $.text(value)); - } - - public ImlBuilder scope(String s) { - return element("scope", $ -> $.text(s)); - } - - public ImlBuilder phase(String s) { - return element("phase", $ -> $.text(s)); - } - - public ImlBuilder argument(String s) { - return element("argument", $ -> $.text(s)); - } - - public ImlBuilder goal(String s) { - return element("goal", $ -> $.text(s)); - } - - public ImlBuilder copy(String file, String toDir) { - return element("copy", $ -> $.attr("file", file).attr("toDir", toDir)); - } - - public ImlBuilder groupIdArtifactId(String groupId, String artifactId) { - return groupId(groupId).artifactId(artifactId); - } - - public ImlBuilder groupIdArtifactIdVersion(String groupId, String artifactId, String version) { - return groupIdArtifactId(groupId, artifactId).version(version); - } - - public ImlBuilder skip(String string) { - return element("skip", $ -> $.text(string)); - } - - public ImlBuilder id(String s) { - return element("id", $ -> $.text(s)); - } - - public ImlBuilder arg(String s) { - return element("arg", $ -> $.text(s)); - } - - public ImlBuilder argLine(String s) { - return element("argLine", $ -> $.text(s)); - } - - public ImlBuilder source(String s) { - return element("source", $ -> $.text(s)); - } - - public ImlBuilder target(String s) { - return element("target", $ -> $.text(s)); - } - - public ImlBuilder showWarnings(String s) { - return element("showWarnings", $ -> $.text(s)); - } - - public ImlBuilder showDeprecation(String s) { - return element("showDeprecation", $ -> $.text(s)); - } - - public ImlBuilder failOnError(String s) { - return element("failOnError", $ -> $.text(s)); - } - - public ImlBuilder exists(String s) { - return element("exists", $ -> $.text(s)); - } - - public ImlBuilder activeByDefault(String s) { - return element("activeByDefault", $ -> $.text(s)); - } - - public ImlBuilder executable(String s) { - return element("executable", $ -> $.text(s)); - } - } - - public static class XMLBuilder extends AbstractXMLBuilder<XMLBuilder> { - XMLBuilder(Element element) { - super(element); - } - - public XMLBuilder element(String name, Consumer<XMLBuilder> xmlBuilderConsumer) { - return element(name, XMLBuilder::new, xmlBuilderConsumer); - } - - public XMLBuilder element(URI uri, String name, Consumer<XMLBuilder> xmlBuilderConsumer) { - return element(uri, name, XMLBuilder::new, xmlBuilderConsumer); - } - } - - static XMLNode create(String nodeName, Consumer<XMLBuilder> xmlBuilderConsumer) { - - try { - var doc = - DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); - var element = doc.createElement(nodeName); - doc.appendChild(element); - XMLBuilder xmlBuilder = new XMLBuilder(element); - xmlBuilderConsumer.accept(xmlBuilder); - return new XMLNode(element); - } catch (ParserConfigurationException e) { - throw new RuntimeException(e); - } - } - - static XMLNode createIml(String commentText, Consumer<ImlBuilder> imlBuilderConsumer) { - try { - var doc = - DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); - var uri1 = URI.create("http://maven.apache.org/POM/4.0.0"); - var uri2 = URI.create("http://www.w3.org/2001/XMLSchema-instance"); - var uri3 = URI.create("http://maven.apache.org/xsd/maven-4.0.0.xsd"); - var comment = doc.createComment(commentText); - doc.appendChild(comment); - var element = doc.createElementNS(uri1.toString(), "project"); - doc.appendChild(element); - element.setAttributeNS(uri2.toString(), "xsi:schemaLocation", uri1 + " " + uri3); - ImlBuilder imlBuilder = new ImlBuilder(element); - imlBuilderConsumer.accept(imlBuilder); - return new XMLNode(element); - } catch (ParserConfigurationException e) { - throw new RuntimeException(e); - } - } - - public static XMLNode createPom( - String commentText, Consumer<PomXmlBuilder> pomXmlBuilderConsumer) { - try { - var doc = - DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); - - var uri1 = URI.create("http://maven.apache.org/POM/4.0.0"); - var uri2 = URI.create("http://www.w3.org/2001/XMLSchema-instance"); - var uri3 = URI.create("http://maven.apache.org/xsd/maven-4.0.0.xsd"); - var comment = doc.createComment(commentText); - doc.appendChild(comment); - var element = doc.createElementNS(uri1.toString(), "project"); - doc.appendChild(element); - element.setAttributeNS(uri2.toString(), "xsi:schemaLocation", uri1 + " " + uri3); - PomXmlBuilder pomXmlBuilder = new PomXmlBuilder(element); - pomXmlBuilderConsumer.accept(pomXmlBuilder); - return new XMLNode(element); - } catch (ParserConfigurationException e) { - throw new RuntimeException(e); - } - } - - static XMLNode create(URI uri, String nodeName, Consumer<XMLBuilder> xmlBuilderConsumer) { - try { - var doc = - DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); - var element = doc.createElementNS(uri.toString(), nodeName); - doc.appendChild(element); - XMLBuilder xmlBuilder = new XMLBuilder(element); - xmlBuilderConsumer.accept(xmlBuilder); - return new XMLNode(element); - } catch (ParserConfigurationException e) { - throw new RuntimeException(e); - } - } - - XMLNode(Element element) { - this.element = element; - this.element.normalize(); - NodeList nodeList = element.getChildNodes(); - for (int i = 0; i < nodeList.getLength(); i++) { - if (nodeList.item(i) instanceof Element e) { - this.children.add(new XMLNode(e)); - } - } - for (int i = 0; i < element.getAttributes().getLength(); i++) { - if (element.getAttributes().item(i) instanceof Attr attr) { - this.attrMap.put(attr.getName(), attr.getValue()); - } - } - } - - public boolean hasAttr(String name) { - return attrMap.containsKey(name); - } - - public String attr(String name) { - return attrMap.get(name); - } - - static Document parse(InputStream is) { - try { - return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is); - } catch (ParserConfigurationException | SAXException | IOException e) { - throw new RuntimeException(e); - } - } - - static Document parse(Path path) { - try { - return parse(Files.newInputStream(path)); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - XMLNode(Path path) { - this(parse(path).getDocumentElement()); - } - - XMLNode(File file) { - this(parse(file.toPath()).getDocumentElement()); - } - - XMLNode(URL url) throws Throwable { - this(parse(url.openStream()).getDocumentElement()); - } - - void write(StreamResult streamResult) throws Throwable { - var transformer = TransformerFactory.newInstance().newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty(OutputKeys.METHOD, "xml"); - transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); - transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); - transformer.transform(new DOMSource(element.getOwnerDocument()), streamResult); - } - - void write(File file) { - try { - write(new StreamResult(file)); - } catch (Throwable t) { - throw new RuntimeException(t); - } - } - - public void write(XMLFile xmlFile) { - try { - write(new StreamResult(xmlFile.path().toFile())); - } catch (Throwable t) { - throw new RuntimeException(t); - } - } - - @Override - public String toString() { - var stringWriter = new StringWriter(); - try { - var transformer = TransformerFactory.newInstance().newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty(OutputKeys.METHOD, "xml"); - transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); - transformer.transform(new DOMSource(element), new StreamResult(stringWriter)); - return stringWriter.toString(); - } catch (Throwable e) { - throw new RuntimeException(e); - } - } - - XPathExpression xpath(String expression) { - XPath xpath = XPathFactory.newInstance().newXPath(); - try { - return xpath.compile(expression); - } catch (XPathExpressionException e) { - throw new RuntimeException(e); - } - } - - Node node(XPathExpression xPathExpression) { - try { - return (Node) xPathExpression.evaluate(this.element, XPathConstants.NODE); - } catch (XPathExpressionException e) { - throw new RuntimeException(e); - } - } - - Optional<Node> optionalNode(XPathExpression xPathExpression) { - var nodes = nodes(xPathExpression).toList(); - return switch (nodes.size()) { - case 0 -> Optional.empty(); - case 1 -> Optional.of(nodes.getFirst()); - default -> throw new IllegalStateException("Expected 0 or 1 but got more"); - }; - } - - String str(XPathExpression xPathExpression) { - try { - return (String) xPathExpression.evaluate(this.element, XPathConstants.STRING); - } catch (XPathExpressionException e) { - throw new RuntimeException(e); - } - } - - String xpathQueryString(String xpathString) { - try { - return (String) xpath(xpathString).evaluate(this.element, XPathConstants.STRING); - } catch (XPathExpressionException e) { - throw new RuntimeException(e); - } - } - - NodeList nodeList(XPathExpression xPathExpression) { - try { - return (NodeList) xPathExpression.evaluate(this.element, XPathConstants.NODESET); - } catch (XPathExpressionException e) { - throw new RuntimeException(e); - } - } - - Stream<Node> nodes(XPathExpression xPathExpression) { - var nodeList = nodeList(xPathExpression); - List<Node> nodes = new ArrayList<>(); - for (int i = 0; i < nodeList.getLength(); i++) { - nodes.add(nodeList.item(i)); - } - return nodes.stream(); - } - - Stream<Element> elements(XPathExpression xPathExpression) { - return nodes(xPathExpression) - .filter(n -> n instanceof Element) - .map(n -> (Element) n); - } - - Stream<XMLNode> xmlNodes(XPathExpression xPathExpression) { - return elements(xPathExpression).map(e -> new XMLNode(e)); - } - } - - public static class MavenStyleRepository { - private final String repoBase = "https://repo1.maven.org/maven2/"; - private final String searchBase = "https://search.maven.org/solrsearch/"; - public RepoDir dir; - - JarFile jarFile(Id id) { - return dir.jarFile(id.artifactAndVersion() + ".jar"); - } - - XMLFile pomFile(Id id) { - return dir.xmlFile(id.artifactAndVersion() + ".pom"); - } - - public enum Scope { - TEST, - COMPILE, - PROVIDED, - RUNTIME, - SYSTEM; - - static Scope of(String name) { - return switch (name.toLowerCase()) { - case "test" -> TEST; - case "compile" -> COMPILE; - case "provided" -> PROVIDED; - case "runtime" -> RUNTIME; - case "system" -> SYSTEM; - default -> COMPILE; - }; - } - } - - public record GroupAndArtifactId(GroupId groupId, ArtifactId artifactId) { - - public static GroupAndArtifactId of(String groupAndArtifactId) { - int idx = groupAndArtifactId.indexOf('/'); - return of(groupAndArtifactId.substring(0, idx), groupAndArtifactId.substring(idx + 1)); - } - - public static GroupAndArtifactId of(GroupId groupId, ArtifactId artifactId) { - return new GroupAndArtifactId(groupId, artifactId); - } - - public static GroupAndArtifactId of(String groupId, String artifactId) { - return of(GroupId.of(groupId), ArtifactId.of(artifactId)); - } - - String location() { - return groupId().string().replace('.', '/') + "/" + artifactId().string(); - } - - @Override - public String toString() { - return groupId() + "/" + artifactId(); - } - } - - public sealed interface Id permits DependencyId, MetaDataId { - MavenStyleRepository mavenStyleRepository(); - - GroupAndArtifactId groupAndArtifactId(); - - VersionId versionId(); - - default String artifactAndVersion() { - return groupAndArtifactId().artifactId().string() + '-' + versionId(); - } - - default String location() { - return mavenStyleRepository().repoBase + groupAndArtifactId().location() + "/" + versionId(); - } - - default URL url(String suffix) { - try { - return new URI(location() + "/" + artifactAndVersion() + "." + suffix).toURL(); - } catch (MalformedURLException | URISyntaxException e) { - throw new RuntimeException(e); - } - } - } - - public record DependencyId( - MavenStyleRepository mavenStyleRepository, - GroupAndArtifactId groupAndArtifactId, - VersionId versionId, - Scope scope, - boolean required) - implements Id { - @Override - public String toString() { - return groupAndArtifactId().toString() - + "/" - + versionId() - + ":" - + scope.toString() - + ":" - + (required ? "Required" : "Optiona"); - } - } - - public record Pom(MetaDataId metaDataId, XMLNode xmlNode) { - JarFile getJar() { - var jarFile = metaDataId.mavenStyleRepository().jarFile(metaDataId); // ; - metaDataId.mavenStyleRepository.queryAndCache(metaDataId.jarURL(), jarFile); - return jarFile; - } - - String description() { - return xmlNode().xpathQueryString("/project/description/text()"); - } - - Stream<DependencyId> dependencies() { - return xmlNode() - .nodes(xmlNode.xpath("/project/dependencies/dependency")) - .map(node -> new XMLNode((Element) node)) - .map( - dependency -> - new DependencyId( - metaDataId().mavenStyleRepository(), - GroupAndArtifactId.of( - GroupId.of(dependency.xpathQueryString("groupId/text()")), - ArtifactId.of(dependency.xpathQueryString("artifactId/text()"))), - VersionId.of(dependency.xpathQueryString("version/text()")), - Scope.of(dependency.xpathQueryString("scope/text()")), - !Boolean.parseBoolean(dependency.xpathQueryString("optional/text()")))); - } - - Stream<DependencyId> requiredDependencies() { - return dependencies().filter(DependencyId::required); - } - } - - public Optional<Pom> pom(Id id) { - return switch (id) { - case MetaDataId metaDataId -> { - if (metaDataId.versionId() == VersionId.UNSPECIFIED) { - // println("what to do when the version is unspecified"); - yield Optional.empty(); - } - try { - yield Optional.of( - new Pom( - metaDataId, - queryAndCache( - metaDataId.pomURL(), metaDataId.mavenStyleRepository.pomFile(metaDataId)))); - } catch (Throwable e) { - throw new RuntimeException(e); - } - } - case DependencyId dependencyId -> { - if (metaData( - id.groupAndArtifactId().groupId().string(), - id.groupAndArtifactId().artifactId().string()) - instanceof Optional<MetaData> optionalMetaData - && optionalMetaData.isPresent()) { - if (optionalMetaData - .get() - .metaDataIds() - .filter(metaDataId -> metaDataId.versionId().equals(id.versionId())) - .findFirst() - instanceof Optional<MetaDataId> metaId - && metaId.isPresent()) { - yield pom(metaId.get()); - } else { - yield Optional.empty(); - } - } else { - yield Optional.empty(); - } - } - - }; - } - - public Optional<Pom> pom(GroupAndArtifactId groupAndArtifactId) { - var metaData = metaData(groupAndArtifactId).orElseThrow(); - var metaDataId = metaData.latestMetaDataId().orElseThrow(); - return pom(metaDataId); - } - - record IdVersions(GroupAndArtifactId groupAndArtifactId, Set<Id> versions) { - static IdVersions of(GroupAndArtifactId groupAndArtifactId) { - return new IdVersions(groupAndArtifactId, new HashSet<>()); - } - } - - public static class Dag implements ClassPathEntryProvider { - private final MavenStyleRepository repo; - private final List<GroupAndArtifactId> rootGroupAndArtifactIds; - Map<GroupAndArtifactId, IdVersions> nodes = new HashMap<>(); - Map<IdVersions, List<IdVersions>> edges = new HashMap<>(); - - Dag add(Id from, Id to) { - var fromNode = - nodes.computeIfAbsent( - from.groupAndArtifactId(), _ -> IdVersions.of(from.groupAndArtifactId())); - fromNode.versions().add(from); - var toNode = - nodes.computeIfAbsent( - to.groupAndArtifactId(), _ -> IdVersions.of(to.groupAndArtifactId())); - toNode.versions().add(to); - edges.computeIfAbsent(fromNode, k -> new ArrayList<>()).add(toNode); - return this; - } - - void removeUNSPECIFIED() { - nodes - .values() - .forEach( - idversions -> { - if (idversions.versions().size() > 1) { - List<Id> versions = new ArrayList<>(idversions.versions()); - idversions.versions().clear(); - idversions - .versions() - .addAll( - versions.stream() - .filter(v -> !v.versionId().equals(VersionId.UNSPECIFIED)) - .toList()); - println(idversions); - } - if (idversions.versions().size() > 1) { - throw new IllegalStateException("more than one version"); - } - }); - } - - Dag(MavenStyleRepository repo, List<GroupAndArtifactId> rootGroupAndArtifactIds) { - this.repo = repo; - this.rootGroupAndArtifactIds = rootGroupAndArtifactIds; - - Set<Id> unresolved = new HashSet<>(); - rootGroupAndArtifactIds.forEach( - rootGroupAndArtifactId -> { - var metaData = repo.metaData(rootGroupAndArtifactId).orElseThrow(); - var metaDataId = metaData.latestMetaDataId().orElseThrow(); - var optionalPom = repo.pom(rootGroupAndArtifactId); - - if (optionalPom.isPresent() && optionalPom.get() instanceof Pom pom) { - pom.requiredDependencies() - .filter(dependencyId -> !dependencyId.scope.equals(Scope.TEST)) - .forEach( - dependencyId -> { - add(metaDataId, dependencyId); - unresolved.add(dependencyId); - }); - } - }); - - while (!unresolved.isEmpty()) { - var resolveSet = new HashSet<>(unresolved); - unresolved.clear(); - resolveSet.forEach(id -> { - if (repo.pom(id) instanceof Optional<Pom> p && p.isPresent()) { - p.get() - .requiredDependencies() - .filter(dependencyId -> !dependencyId.scope.equals(Scope.TEST)) - .forEach( - dependencyId -> { - unresolved.add(dependencyId); - add(id, dependencyId); - }); - } - }); - } - removeUNSPECIFIED(); - } - - @Override - public List<ClassPathEntry> classPathEntries() { - return classPath().classPathEntries(); - } - - ClassPath classPath() { - - ClassPath jars = ClassPath.of(); - nodes - .keySet() - .forEach( - id -> { - Optional<Pom> optionalPom = repo.pom(id); - if (optionalPom.isPresent() && optionalPom.get() instanceof Pom pom) { - jars.add(pom.getJar()); - } else { - throw new RuntimeException("No pom for " + id + " needed by " + id); - } - }); - return jars; - } - } - - public ClassPathEntryProvider classPathEntries(String... rootGroupAndArtifactIds) { - return classPathEntries(Stream.of(rootGroupAndArtifactIds).map(GroupAndArtifactId::of).toList()); - } - - public ClassPathEntryProvider classPathEntries(GroupAndArtifactId... rootGroupAndArtifactIds) { - return classPathEntries(List.of(rootGroupAndArtifactIds)); - } - - public ClassPathEntryProvider classPathEntries(List<GroupAndArtifactId> rootGroupAndArtifactIds) { - StringBuilder sb = new StringBuilder(); - rootGroupAndArtifactIds.forEach(groupAndArtifactId -> sb.append(sb.isEmpty() ? "" : "-").append(groupAndArtifactId.groupId + "-" + groupAndArtifactId.artifactId)); - System.out.println(sb); - ClassPathEntryProvider classPathEntries = null; - var pathFileName = sb + "-path.xml"; - var pathFile = dir.xmlFile(pathFileName); - if (pathFile.exists()) { - System.out.println(pathFileName + " exists " + pathFile.path().toString()); - XMLNode path = new XMLNode(pathFile.path()); - ClassPath classPath = ClassPath.of(); - path.nodes(path.xpath("/path/jar/text()")).forEach(e -> - classPath.add(dir.jarFile(e.getNodeValue())) - ); - classPathEntries = classPath; - } else { - var finalClassPathEntries = new Dag(this, rootGroupAndArtifactIds); - XMLNode.create("path", xml -> { - finalClassPathEntries.classPathEntries().forEach(cpe -> - xml.element("jar", jar -> jar.text(dir.path().relativize(cpe.path()).toString())) - ); - }).write(pathFile); - System.out.println("created " + pathFile.path()); - classPathEntries = finalClassPathEntries; - } - return classPathEntries; - } - - public record VersionId(Integer maj, Integer min, Integer point, String classifier) - implements Comparable<VersionId> { - static Integer integerOrNull(String s) { - return (s == null || s.isEmpty()) ? null : Integer.parseInt(s); - } - - public static Pattern pattern = Pattern.compile("^(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)(.*))?)?$"); - static VersionId UNSPECIFIED = new VersionId(null, null, null, null); - - static VersionId of(String version) { - Matcher matcher = pattern.matcher(version); - if (matcher.matches()) { - return new VersionId( - integerOrNull(matcher.group(1)), - integerOrNull(matcher.group(2)), - integerOrNull(matcher.group(3)), - matcher.group(4)); - } else { - return UNSPECIFIED; - } - } - - int cmp(Integer v1, Integer v2) { - if (v1 == null && v2 == null) { - return 0; - } - if (v1 == null) { - return -v2; - } else if (v2 == null) { - return v1; - } else { - return v1 - v2; - } - } - - @Override - public int compareTo(VersionId o) { - if (cmp(maj(), o.maj()) == 0) { - if (cmp(min(), o.min()) == 0) { - if (cmp(point(), o.point()) == 0) { - return classifier().compareTo(o.classifier()); - } else { - return cmp(point(), o.point()); - } - } else { - return cmp(min(), o.min()); - } - } else { - return cmp(maj(), o.maj()); - } - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - if (maj() != null) { - sb.append(maj()); - if (min() != null) { - sb.append(".").append(min()); - if (point() != null) { - sb.append(".").append(point()); - if (classifier() != null) { - sb.append(classifier()); - } - } - } - } else { - sb.append("UNSPECIFIED"); - } - return sb.toString(); - } - } - - public record GroupId(String string) { - public static GroupId of(String s) { - return new GroupId(s); - } - - @Override - public String toString() { - return string; - } - } - - public record ArtifactId(String string) { - static ArtifactId of(String string) { - return new ArtifactId(string); - } - - @Override - public String toString() { - return string; - } - } - - public record MetaDataId( - MavenStyleRepository mavenStyleRepository, - GroupAndArtifactId groupAndArtifactId, - VersionId versionId, - Set<String> downloadables, - Set<String> tags) - implements Id { - - public URL pomURL() { - return url("pom"); - } - - public URL jarURL() { - return url("jar"); - } - - public XMLNode getPom() { - if (downloadables.contains(".pom")) { - return mavenStyleRepository.queryAndCache( - url("pom"), mavenStyleRepository.dir.xmlFile(artifactAndVersion() + ".pom")); - } else { - throw new IllegalStateException("no pom"); - } - } - - @Override - public String toString() { - return groupAndArtifactId().toString() + "." + versionId(); - } - } - - public MavenStyleRepository(RepoDir dir) { - this.dir = dir.create(); - } - - JarFile queryAndCache(URL query, JarFile jarFile) { - try { - if (!jarFile.exists()) { - print("Querying and caching " + jarFile.fileName()); - println(" downloading " + query); - curl(query, jarFile.path()); - } else { - // println("Using cached " + jarFile.fileName()); - - } - } catch (Throwable e) { - throw new RuntimeException(e); - } - return jarFile; - } - - XMLNode queryAndCache(URL query, XMLFile xmlFile) { - XMLNode xmlNode = null; - try { - if (!xmlFile.exists()) { - print("Querying and caching " + xmlFile.fileName()); - println(" downloading " + query); - xmlNode = new XMLNode(query); - xmlNode.write(xmlFile.path().toFile()); - } else { - // println("Using cached " + xmlFile.fileName()); - xmlNode = new XMLNode(xmlFile.path()); - } - } catch (Throwable e) { - throw new RuntimeException(e); - } - return xmlNode; - } - - public record MetaData( - MavenStyleRepository mavenStyleRepository, - GroupAndArtifactId groupAndArtifactId, - XMLNode xmlNode) { - - public Stream<MetaDataId> metaDataIds() { - return xmlNode - .xmlNodes(xmlNode.xpath("/response/result/doc")) - .map( - xmln -> - new MetaDataId( - this.mavenStyleRepository, - GroupAndArtifactId.of( - GroupId.of(xmln.xpathQueryString("str[@name='g']/text()")), - ArtifactId.of(xmln.xpathQueryString("str[@name='a']/text()"))), - VersionId.of(xmln.xpathQueryString("str[@name='v']/text()")), - new HashSet<>( - xmln.nodes(xmln.xpath("arr[@name='ec']/str/text()")) - .map(Node::getNodeValue) - .toList()), - new HashSet<>( - xmln.nodes(xmln.xpath("arr[@name='tags']/str/text()")) - .map(Node::getNodeValue) - .toList()))); - } - - public Stream<MetaDataId> sortedMetaDataIds() { - return metaDataIds().sorted(Comparator.comparing(MetaDataId::versionId)); - } - - public Optional<MetaDataId> latestMetaDataId() { - return metaDataIds().max(Comparator.comparing(MetaDataId::versionId)); - } - - public Optional<MetaDataId> getMetaDataId(VersionId versionId) { - return metaDataIds().filter(id -> versionId.compareTo(id.versionId()) == 0).findFirst(); - } - } - - public Optional<MetaData> metaData(String groupId, String artifactId) { - return metaData(GroupAndArtifactId.of(groupId, artifactId)); - } - - public Optional<MetaData> metaData(GroupAndArtifactId groupAndArtifactId) { - try { - var query = "g:" + groupAndArtifactId.groupId() + " AND a:" + groupAndArtifactId.artifactId(); - URL rowQueryUrl = - new URI( - searchBase - + "select?q=" - + URLEncoder.encode(query, StandardCharsets.UTF_8) - + "&core=gav&wt=xml&rows=0") - .toURL(); - var rowQueryResponse = new XMLNode(rowQueryUrl); - var numFound = rowQueryResponse.xpathQueryString("/response/result/@numFound"); - - URL url = - new URI( - searchBase - + "select?q=" - + URLEncoder.encode(query, StandardCharsets.UTF_8) - + "&core=gav&wt=xml&rows=" - + numFound) - .toURL(); - try { - // println(url); - var xmlNode = - queryAndCache(url, dir.xmlFile(groupAndArtifactId.artifactId() + ".meta.xml")); - if (numFound.isEmpty() || numFound.equals("0")) { - return Optional.empty(); - } else { - return Optional.of(new MetaData(this, groupAndArtifactId, xmlNode)); - } - } catch (Throwable e) { - throw new RuntimeException(e); - } - } catch (Throwable e) { - throw new RuntimeException(e); - } - } - } - - public static class IntelliJ { - public static class IntellijArtifact { - DirEntry projectDir; - XMLNode root; - - Stream<XMLNode> query(String xpath) { - return root.nodes(root.xpath(xpath)).map(e -> new XMLNode((Element) e)); - } - - IntellijArtifact(DirEntry projectDir, XMLNode root) { - this.projectDir = projectDir; - this.root = root; - } - } - - public static class Workspace extends IntellijArtifact { - - record Application(XMLNode xmlNode) { - } - - List<Application> applications; - - Workspace(DirEntry projectDir, XMLNode root) { - super(projectDir, root); - this.applications = - query("/project/component[@name='RunManager']/configuration") - .map(Application::new) - .toList(); - } - } - - public static class Compiler extends IntellijArtifact { - public record JavacSettings(XMLNode xmlNode) { - public String getAdditionalOptions() { - return xmlNode.xpathQueryString("option[@name='ADDITIONAL_OPTIONS_STRING']/@value"); - } - } - - public JavacSettings javacSettings; - - Compiler(DirEntry projectDir, XMLNode root) { - super(projectDir, root); - this.javacSettings = - new JavacSettings(query("/project/component[@name='JavacSettings']").findFirst().get()); - } - } - - public static class ImlGraph extends IntellijArtifact { - public record Module(Path imlPath, XMLNode xmlNode) { - @Override - public String toString() { - return name(); - } - - public String name() { - return imlPath.getFileName().toString(); - } - - public SourcePath getSourcePath() { - return null; - } - - Stream<XMLNode> query(String xpath) { - return xmlNode.nodes(xmlNode.xpath(xpath)).map(e -> new XMLNode((Element) e)); - } - } - - Stream<XMLNode> query(String xpath) { - return root.nodes(root.xpath(xpath)).map(e -> new XMLNode((Element) e)); - } - - Set<Module> modules = new HashSet<>(); - public Map<Module, List<Module>> fromToDependencies = new HashMap<>(); - Map<Module, List<Module>> toFromDependencies = new HashMap<>(); - - ImlGraph(DirEntry projectDir, XMLNode root) { - super(projectDir, root); - Map<String, Module> nameToModule = new HashMap<>(); - query("/project/component[@name='ProjectModuleManager']/modules/module") - .map( - xmlNode -> - Path.of( - xmlNode - .attrMap - .get("filepath") - .replace("$PROJECT_DIR$", projectDir.path().toString()))) - .map(path -> new Module(path, new XMLNode(path))) - .forEach( - module -> { - modules.add(module); - nameToModule.put(module.name(), module); - }); - modules.forEach( - module -> - module - .xmlNode - .nodes(root.xpath("/module/component/orderEntry[@type='module']")) - .map(e -> new XMLNode((Element) e)) - .forEach( - e -> { - var dep = nameToModule.get(e.attrMap.get("module-name") + ".iml"); - fromToDependencies.computeIfAbsent(module, _ -> new ArrayList<>()).add(dep); - toFromDependencies.computeIfAbsent(dep, _ -> new ArrayList<>()).add(module); - })); - } - } - - public static class Project { - public DirEntry intellijDir; - public ImlGraph imlGraph; - public Workspace workSpace; - public Compiler compiler; - - public Project(DirEntry intellijDir) { - this.intellijDir = intellijDir; - var ideaDir = intellijDir.existingDir(".idea"); - imlGraph = new ImlGraph(intellijDir, new XMLNode(ideaDir.xmlFile("modules.xml").path())); - workSpace = new Workspace(intellijDir, new XMLNode(ideaDir.xmlFile("workspace.xml").path())); - compiler = new Compiler(intellijDir, new XMLNode(ideaDir.xmlFile("compiler.xml").path())); - } - } - } -} diff --git a/hat/bldr/args b/hat/bldr/args deleted file mode 100644 index bd1f02376fb..00000000000 --- a/hat/bldr/args +++ /dev/null @@ -1 +0,0 @@ ---add-modules jdk.incubator.code --enable-preview --source 24 diff --git a/hat/bldr/bld b/hat/bldr/bld deleted file mode 100644 index a59b10066b7..00000000000 --- a/hat/bldr/bld +++ /dev/null @@ -1 +0,0 @@ ---enable-preview --source 24 bld diff --git a/hat/bldr/clean b/hat/bldr/clean deleted file mode 100644 index ae9fcfadb2b..00000000000 --- a/hat/bldr/clean +++ /dev/null @@ -1 +0,0 @@ ---enable-preview --source 24 clean diff --git a/hat/bldr/hatlessrun b/hat/bldr/hatlessrun deleted file mode 100644 index 6ec1f304e39..00000000000 --- a/hat/bldr/hatlessrun +++ /dev/null @@ -1 +0,0 @@ ---enable-preview --source 24 hatlessrun diff --git a/hat/bldr/hatrun b/hat/bldr/hatrun deleted file mode 100644 index 4f2ad45898b..00000000000 --- a/hat/bldr/hatrun +++ /dev/null @@ -1 +0,0 @@ ---enable-preview --source 24 hatrun diff --git a/hat/bldr/java b/hat/bldr/java deleted file mode 100644 index c86af5b50a6..00000000000 --- a/hat/bldr/java +++ /dev/null @@ -1 +0,0 @@ ---enable-preview --source 24 hatrun java diff --git a/hat/bldr/mkpoms b/hat/bldr/mkpoms deleted file mode 100644 index 45a800b76cc..00000000000 --- a/hat/bldr/mkpoms +++ /dev/null @@ -1 +0,0 @@ ---enable-preview --source 24 mkpoms diff --git a/hat/bldr/opencl b/hat/bldr/opencl deleted file mode 100644 index 671fb7a28c6..00000000000 --- a/hat/bldr/opencl +++ /dev/null @@ -1 +0,0 @@ ---enable-preview --source 24 hatrun opencl diff --git a/hat/bldr/sanity b/hat/bldr/sanity deleted file mode 100644 index b16e725d869..00000000000 --- a/hat/bldr/sanity +++ /dev/null @@ -1 +0,0 @@ ---enable-preview --source 24 sanity diff --git a/hat/bldr/scriptformat.xml b/hat/bldr/scriptformat.xml deleted file mode 100644 index bd550c34190..00000000000 --- a/hat/bldr/scriptformat.xml +++ /dev/null @@ -1,26 +0,0 @@ -<code_scheme name="scriptformat" version="173"> - <!-- - ~/Applications/IntelliJ\ IDEA\ Ultimate.app/Contents/bin/format.sh -s bldr/scriptformat.xml bld.java - --> - <JavaCodeStyleSettings> - <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" /> - <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" /> - <option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND"> - <value /> - </option> - </JavaCodeStyleSettings> - <codeStyleSettings language="JAVA"> - <option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" /> - <option name="PREFER_PARAMETERS_WRAP" value="true" /> - <option name="CALL_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" /> - <option name="CALL_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" /> - <option name="KEEP_SIMPLE_LAMBDAS_IN_ONE_LINE" value="true" /> - <option name="DOWHILE_BRACE_FORCE" value="3" /> - <option name="WHILE_BRACE_FORCE" value="3" /> - <indentOptions> - <option name="INDENT_SIZE" value="2" /> - <option name="CONTINUATION_INDENT_SIZE" value="2" /> - <option name="TAB_SIZE" value="2" /> - </indentOptions> - </codeStyleSettings> -</code_scheme> diff --git a/hat/bldr/tst b/hat/bldr/tst deleted file mode 100644 index 97e59db9c42..00000000000 --- a/hat/bldr/tst +++ /dev/null @@ -1,5 +0,0 @@ ---add-modules jdk.incubator.code ---enable-preview --cp build/hat-core-1.0.jar:build/hat-backend-ffi-opencl-1.0.jar ---enable-native-access=ALL-UNNAMED --Djava.library.path=build diff --git a/hat/clean b/hat/clean deleted file mode 100644 index 59fbdc47f69..00000000000 --- a/hat/clean +++ /dev/null @@ -1,33 +0,0 @@ -/* vim: set ft=java: - * - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import static bldr.Bldr.*; - -void main(String[] args) { - var hatDir = DirEntry.current(); - hatDir.buildDir("build").remove(); - hatDir.buildDir("stage").remove(); -} diff --git a/hat/hat/mkpoms.java b/hat/hat/mkpoms.java index 1dbc4f7bc8d..23e23f38a1a 100644 --- a/hat/hat/mkpoms.java +++ b/hat/hat/mkpoms.java @@ -1,4 +1,4 @@ -/* vim: set ft=java: +/* * * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,8 +24,6 @@ * questions. */ -import static bldr.Bldr.*; -import static bldr.Bldr.Capabilities.*; void main(String[] argv) { var pomComment = """ @@ -50,24 +48,24 @@ void main(String[] argv) { Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA or visit www.oracle.com if you need additional information or have any - questions. + questions. """; - var hatDir = DirEntry.current(); + var hatDir = Script.DirEntry.current(); var hatCore = hatDir.existingDir("hat-core"); var backends = hatDir.existingDir("backends"); var examples = hatDir.existingDir("examples"); var extractions = hatDir.existingDir("extractions"); var buildDir = hatDir.existingBuildDir("build"); - var opencl = OpenCL.of(); - var opengl = OpenGL.of(); - var cuda = CUDA.of(); - var hip = HIP.of(); - var jextract = JExtract.of(); - var cmake = CMake.of(); + var opencl = Script.Capabilities.OpenCL.of(); + var opengl = Script.Capabilities.OpenGL.of(); + var cuda = Script.Capabilities.CUDA.of(); + var hip = Script.Capabilities.HIP.of(); + var jextract = Script.Capabilities.JExtract.of(); + var cmake = Script.Capabilities.CMake.of(); - var capabilities = Capabilities.of(opencl, opengl, cuda, hip, jextract, cmake); + var capabilities = Script.Capabilities.of(opencl, opengl, cuda, hip, jextract, cmake); if (cmake.available()) { cmake.probe(buildDir, capabilities); diff --git a/hat/hatrun b/hat/hatrun deleted file mode 100644 index f6927514e72..00000000000 --- a/hat/hatrun +++ /dev/null @@ -1,100 +0,0 @@ -/* vim: set ft=java: - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import static bldr.Bldr.*; - - -void main(String[] argv) { - var usage =""" - usage: - java @bldr/args hatrun [headless] backend package args ... - [headless] : Optional passes -Dheadless=true to app - backend : opencl|cuda|spirv|ptx|mock - package : the examples package (and dirname under hat/examples) - - class name is assumed to be package.Main (i.e. mandel.main) - - examples: - java @bldr/args ffi-opencl mandel - java @bldr/args java-opencl mandel - java @bldr/args headless ffi-opencl mandel - java @bldr/args ffi-opencl life - java @bldr/args java-opencl life - """; - - var hatDir = DirEntry.current(); - var backends = hatDir.existingDir("backends"); - var examples = hatDir.dir("examples"); - var buildDir = hatDir.existingBuildDir("build"); - var jextractedOpenCLJar = buildDir.jarFile("hat-jextracted-opencl-1.0.jar"); - var jextractedOpenGLJar = buildDir.jarFile("hat-jextracted-opengl-1.0.jar"); - var wrapJar = buildDir.jarFile("hat-wrap-1.0.jar"); - var clwrapJar = buildDir.jarFile("hat-clwrap-1.0.jar"); - var glwrapJar = buildDir.jarFile("hat-glwrap-1.0.jar"); - var verbose = false; - - var args = new ArrayList<>(List.of(argv)); - java(java -> java - .enable_preview() - .verbose(verbose) - //.add_exports("java.base", "jdk.internal", "ALL-UNNAMED") - .enable_native_access("ALL-UNNAMED") - .library_path(buildDir) - .class_path(buildDir.jarFile("hat-core-1.0.jar")) - .when((!args.isEmpty() && args.getFirst().equals("headless")), ifHeadless -> { - ifHeadless.headless(); - args.removeFirst(); - }) - .either(!args.isEmpty(), haveBackend -> { - var backendName = args.removeFirst(); - if (backends.dir(backendName.replace('-','/')) instanceof DirEntry backend && backend.exists()) { - haveBackend.class_path(buildDir.jarFile("hat-backend-" + backendName + "-1.0.jar")); - if (backendName.equals("ffi-opencl")){ - haveBackend.class_path(wrapJar, clwrapJar, jextractedOpenCLJar); - } - } else { - throw new RuntimeException("No such backend " + backendName); - } - if (!args.isEmpty() && args.removeFirst() instanceof String exampleName) { - if (examples.dir(exampleName) instanceof DirEntry example && example.exists()) { haveBackend - .class_path(buildDir.jarFile("hat-example-" + exampleName + "-1.0.jar")) - .when(jextractedOpenCLJar.exists() && jextractedOpenGLJar.exists() && exampleName.equals("nbody"), _->{ haveBackend - .class_path(jextractedOpenCLJar,jextractedOpenGLJar, wrapJar, clwrapJar, glwrapJar ) - .start_on_first_thread(); - }) - .when(jextractedOpenCLJar.exists() && exampleName.equals("life"), _->{ haveBackend - .class_path(jextractedOpenCLJar, wrapJar, clwrapJar); - }) - .main_class(exampleName + ".Main") - .args(args); - } else { - throw new RuntimeException("no such example " + exampleName); - } - } - }, _ -> { - throw new RuntimeException("No backend provided...\n" + usage); - }) - ); -} diff --git a/hat/intellij/hat.iml b/hat/intellij/hat.iml new file mode 100644 index 00000000000..6215d7eac4f --- /dev/null +++ b/hat/intellij/hat.iml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager" inherit-compiler-output="true"> + <exclude-output /> + <content url="file://$MODULE_DIR$/../hat/"> + <sourceFolder url="file://$MODULE_DIR$/../hat" isTestSource="false" /> + </content> + <content url="file://$MODULE_DIR$/../docs" /> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + </component> +</module> diff --git a/hat/mkpoms b/hat/mkpoms deleted file mode 100644 index 1dbc4f7bc8d..00000000000 --- a/hat/mkpoms +++ /dev/null @@ -1,334 +0,0 @@ -/* vim: set ft=java: - * - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import static bldr.Bldr.*; -import static bldr.Bldr.Capabilities.*; - -void main(String[] argv) { - var pomComment = """ - Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. - DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - - This code is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License version 2 only, as - published by the Free Software Foundation. Oracle designates this - particular file as subject to the "Classpath" exception as provided - by Oracle in the LICENSE file that accompanied this code. - - This code is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - version 2 for more details (a copy is included in the LICENSE file that - accompanied this code). - - You should have received a copy of the GNU General Public License version - 2 along with this work; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - - Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - or visit www.oracle.com if you need additional information or have any - questions. - """; - - var hatDir = DirEntry.current(); - var hatCore = hatDir.existingDir("hat-core"); - var backends = hatDir.existingDir("backends"); - var examples = hatDir.existingDir("examples"); - var extractions = hatDir.existingDir("extractions"); - var buildDir = hatDir.existingBuildDir("build"); - - var opencl = OpenCL.of(); - var opengl = OpenGL.of(); - var cuda = CUDA.of(); - var hip = HIP.of(); - var jextract = JExtract.of(); - var cmake = CMake.of(); - - var capabilities = Capabilities.of(opencl, opengl, cuda, hip, jextract, cmake); - - if (cmake.available()) { - cmake.probe(buildDir, capabilities); - } - capabilities.capabilities().forEach(fw -> println((fw.available() ? "we have " : "no ") + fw.name)); - - hatDir.pom(pomComment, pom -> pom - .comment("Auto generated by mkpoms") - .pom("oracle.code", "hat-root", "1.0") - .properties(properties -> properties - .property("project.build.sourceEncoding", "UTF-8") - .property("hat.root", "${env.PWD}") - .property("hat.build", "${hat.root}/build") - .property("hat.stage", "${hat.root}/stage") - .property("hat.stage.repo", "${hat.stage}/repo") - .property("hat.stage.jextract", "${hat.stage}/jextract") - .property("mac.app.frameworks", "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks") - .property("mac.lib.frameworks", "/System/Library/Frameworks") - ) - .modules("hat", "extractions", "backends", "examples") - .build(build -> build - .plugins(plugins -> plugins - .compilerPlugin(plugin -> plugin - .configuration(configuration -> configuration - .compilerArgs( - "--add-modules=jdk.incubator.code", - "--enable-preview", - "--add-exports=java.base/jdk.internal=ALL-UNNAMED", - "--add-exports=java.base/jdk.internal.vm.annotation=ALL-UNNAMED" - ) - .source("24") - .target("24") - .showDeprecation("true") - .failOnError("true") - .showWarnings("true") - ) - ) - ) - ) - ); - - // Now hat/pom.xml - hatCore.pom(pomComment, pom -> pom - .comment("Auto generated by mkpoms") - .jar("oracle.code", "hat", "1.0") - .parent("oracle.code", "hat-root", "1.0") - .dependsOn("org.junit.jupiter", "junit-jupiter-engine", "5.10.0", "test") - .build(build -> build - .pluginManagement(pluginManagement -> pluginManagement - .plugins(plugins -> plugins - .surefirePlugin(plugin -> plugin - .configuration(configuration -> configuration - .argLine("-enable-preview") - ) - ) - ) - ) - .plugins(plugins -> plugins - .antPlugin(plugin -> plugin - .executions(executions -> executions - .ant("1", "install", "run", ant -> ant - .copy("target/${project.artifactId}-1.0.jar", "${hat.build}") - ) - ) - ) - ) - ) - ); - - // Note that we filter by capability here. So we only create poms (and include modules in parent) if capability is available - var extractionDirs = extractions - .subDirs(extraction -> !extraction.matches("^.*(target)$")).filter(dir -> capabilities.capabilityIsAvailable(dir.fileName())).toList(); - - extractions.pom(pomComment, pom -> pom - .comment("Auto generated by mkpoms") - .pom("oracle.code", "hat-extractions", "1.0") - .parent("oracle.code", "hat-root", "1.0") - .modules(extractionDirs.stream().map(PathHolder::fileName).toList()) - .build(build -> build - .plugins(plugins -> plugins - .antPlugin(plugin -> plugin - .executions(executions -> executions - .ant("createDir", "compile", "run", ant -> ant - .mkdir("${hat.stage.jextract}") - .echo("${hat.stage.jextract}/compile_flags.txt", "-F${mac.app.frameworks}") - ) - ) - ) - ) - - ) - ); - - extractionDirs.forEach(extraction -> extraction - .pom(pomComment, examplePom -> examplePom - .comment("Auto generated by mkpoms") - .pom("oracle.code", "hat-extraction-" + extraction.fileName(), "1.0") - .parent("oracle.code", "hat-extractions", "1.0") - .build(build -> build - .plugins(plugins -> plugins - .execPlugin(plugin -> plugin - .executions(execution -> execution - .execIdPhaseConf("2", "compile", configuration -> configuration - .executable("jextract") - .workingDirectory("${hat.stage.jextract}") - .arguments(arguments -> { - arguments - .argument("--output").argument("${hat.stage.jextract}") - .argument("-t").argument(extraction.fileName()); - switch (extraction.fileName()) { - case "opencl" -> arguments - .argument("-l").argument("${mac.lib.frameworks}/OpenCL.framework/OpenCL") - .argument("${mac.app.frameworks}/OpenCL.framework/Headers/opencl.h"); - case "opengl" -> arguments - .argument("-l").argument("${mac.lib.frameworks}/GLUT.framework/GLUT") - .argument("-l").argument("${mac.lib.frameworks}/OpenGL.framework/OpenGL") - .argument("${mac.app.frameworks}/GLUT.framework/Headers/glut.h"); - default -> - throw new IllegalStateException("Unexpected value: " + extraction.fileName()); - } - }) - ) - ) - ) - .antPlugin(plugin -> plugin - .executions(executions -> executions - .ant("1", "install", "run", ant -> ant - .antjar("${hat.stage.jextract}", extraction.fileName(), "${hat.build}/jextracted-" + extraction.fileName() + "-1.0.jar") - //.copy("target/jextracted" + extraction.fileName() + "-1.0.jar", "${hat.build}") - ) - ) - ) - ) - ) - ) - ); - - var exampleDirs = examples.subDirs(example -> !example.matches("^.*(experiments|target|nbody|.idea)$")).toList(); - - // Here we create examples/pom.xml and nested inside we create each example/*/pom.xml - examples.pom(pomComment, examplesPom -> examplesPom - .comment("Auto generated by mkpoms") - .pom("oracle.code", "hat-examples", "1.0") - .parent("oracle.code", "hat-root", "1.0") - .dependsOn("oracle.code", "hat", "1.0") - .modules(exampleDirs.stream().map(PathHolder::fileName).toList()) - ); - - exampleDirs.forEach(example -> example - .pom(pomComment, examplePom -> examplePom - .comment("Auto generated by mkpoms") - .jar("oracle.code", "hat-example-" + example.fileName(), "1.0") - .parent("oracle.code", "hat-examples", "1.0") - .dependsOn("oracle.code", "hat", "1.0") - .build(build -> build - .plugins(plugins -> plugins - .antPlugin(plugin -> plugin - .executions(executions -> executions - .ant("1", "install", "run", ant -> ant - .copy("target/hat-example-" + example.fileName() + "-1.0.jar", "${hat.build}") - ) - ) - ) - ) - ) - ) - ); - var backendDirs = backends.subDirs(backend -> !backend.matches("^.*(jextracted|target|.idea)$")).toList(); - - // Now backends/pom.xml and backends/*/pom.xml - backends.pom(pomComment, backendsPom -> backendsPom - .comment("Auto generated by mkpoms") - .pom("oracle.code", "hat-backends", "1.0") - .parent("oracle.code", "hat-root", "1.0") - .dependsOn("oracle.code", "hat", "1.0") - .modules("java", "ffi") - ); - - { - var ffiBackend = backends.dir("ffi"); - - - var ffiBackendDirs = ffiBackend.subDirs(backend -> !backend.matches("^.*(hip|spirv|shared|openclx|target|.idea)$")).toList(); - - ffiBackend.pom(pomComment, backendsPom -> backendsPom - .comment("Auto generated by mkpoms") - .pom("oracle.code", "hat-backends-ffi", "1.0") - .parent("oracle.code", "hat-backends", "1.0") - .dependsOn("oracle.code", "hat", "1.0") - .modules(ffiBackendDirs.stream().map(PathHolder::fileName).toList()) - .build(build -> build - .plugins(plugins -> plugins - .execPlugin(plugin -> plugin - .executions(executions -> executions - .cmake("1", "compile", "-DHAT_TARGET=${hat.build}", "-B", "${hat.build}/cmake-build-debug") - .cmake("2", "install", "--build", "${hat.build}/cmake-build-debug") - ) - ) - ) - ) - ); - - ffiBackendDirs.forEach(backend -> backend - .pom(pomComment, backendPom -> backendPom - .comment("Auto generated by mkpoms") - .jar("oracle.code", "hat-backend-ffi-" + backend.fileName(), "1.0") - .parent("oracle.code", "hat-backends-ffi", "1.0") - .dependsOn("oracle.code", "hat", "1.0") - .build(build -> build - .plugins(plugins -> plugins - .execPlugin(plugin -> plugin - .configuration(configuration -> configuration - .skip("true") - ) - ) - .antPlugin(plugin -> plugin - .executions(executions -> executions - .ant("1", "install", "run", ant -> ant - .copy("target/hat-backend-ffi-" + backend.fileName() + "-1.0.jar", "${hat.build}") - ) - ) - ) - ) - ) - ) - ); - } - { - var javaBackend = backends.dir("java"); - var javaBackendDirs = javaBackend.subDirs(backend -> !backend.matches("^.*(target|.idea)$")).toList(); - - javaBackend.pom(pomComment, backendsPom -> backendsPom - .comment("Auto generated by mkpoms") - .pom("oracle.code", "hat-backends-java", "1.0") - .parent("oracle.code", "hat-backends", "1.0") - .dependsOn("oracle.code", "hat", "1.0") - .modules(javaBackendDirs.stream().map(PathHolder::fileName).toList()) - ); - - javaBackendDirs.forEach(backend -> backend - .pom(pomComment, backendPom -> backendPom - .comment("Auto generated by mkpoms") - .jar("oracle.code", "hat-backend-java-" + backend.fileName(), "1.0") - .parent("oracle.code", "hat-backends-java", "1.0") - .dependsOn("oracle.code", "hat", "1.0") - .build(build -> build - .plugins(plugins -> plugins - .antPlugin(plugin -> plugin - .executions(executions -> executions - .ant("1", "install", "run", ant -> ant - .copy("target/hat-backend-java-" + backend.fileName() + "-1.0.jar", "${hat.build}") - ) - ) - ) - ) - ) - ) - ); - } - - - var backendJExtracted = backends.dir("jextracted"); - -} diff --git a/hat/tst/MinBufferTest.java b/hat/tst/MinBufferTest.java deleted file mode 100644 index 71edabe6fbb..00000000000 --- a/hat/tst/MinBufferTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package tst; -import hat.Accelerator; -import hat.ComputeContext; -import hat.KernelContext; -import hat.backend.ffi.OpenCLBackend; -import hat.buffer.S32Array; -import static hat.ifacemapper.MappableIface.*; -import jdk.incubator.code.CodeReflection; - -import java.lang.invoke.MethodHandles; - -import static hat.backend.ffi.Config.*; - -public class MinBufferTest { - public static class Compute { - @CodeReflection - public static void inc(@RO KernelContext kc, @RW S32Array s32Array, int len) { - if (kc.x < kc.maxX) { - s32Array.array(kc.x, s32Array.array(kc.x) + 1); - } - } - - @CodeReflection - public static void add(ComputeContext cc, @RW S32Array s32Array, int len, int n) { - for (int i = 0; i < n; i++) { - cc.dispatchKernel(len, kc -> inc(kc, s32Array, len)); - System.out.println(i);//s32Array.array(0)); - } - } - } - - public static void main(String[] args) { - Accelerator accelerator = new Accelerator(MethodHandles.lookup(), - new OpenCLBackend(of( - // TRACE(), - TRACE_COPIES(), - GPU(), - MINIMIZE_COPIES() - )) - - ); - int len = 10000000; - int valueToAdd = 10; - S32Array s32Array = S32Array.create(accelerator, len,i->i); - accelerator.compute( - cc -> Compute.add(cc, s32Array, len, valueToAdd) - ); - // Quite an expensive way of adding 20 to each array alement - for (int i = 0; i < 20; i++) { - System.out.println(i + "=" + s32Array.array(i)); - } - } -}