1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package compiler.aot; 25 26 import jdk.test.lib.Platform; 27 import jdk.test.lib.artifacts.Artifact; 28 import jdk.test.lib.artifacts.ArtifactResolver; 29 import jdk.test.lib.process.OutputAnalyzer; 30 import java.io.File; 31 import java.io.FileNotFoundException; 32 import java.io.IOException; 33 import java.lang.annotation.Annotation; 34 import java.nio.file.Files; 35 import java.nio.file.Path; 36 import java.nio.file.Paths; 37 import java.nio.file.StandardOpenOption; 38 import java.util.ArrayList; 39 import java.util.Arrays; 40 import java.util.List; 41 import jdk.test.lib.JDKToolLauncher; 42 import jdk.test.lib.Utils; 43 import jdk.test.lib.process.ProcessTools; 44 45 /** 46 * A simple class calling AOT compiler over requested items 47 */ 48 public class AotCompiler { 49 50 private final static String METHODS_LIST_FILENAME = "methodsList.txt"; 51 52 public static void main(String args[]) { 53 String className = null; 54 List<String> compileList = new ArrayList<>(); 55 String libName = null; 56 List<String> extraopts = new ArrayList<>(); 57 for (int i = 0; i < args.length; i++) { 58 switch (args[i]) { 59 case "-class": 60 className = args[++i]; 61 break; 62 case "-compile": 63 compileList.add("compileOnly " + args[++i]); 64 break; 65 case "-libname": 66 libName = args[++i]; 67 break; 68 case "-extraopt": 69 extraopts.add(args[++i]); 70 break; 71 default: 72 throw new Error("Unknown option: " + args[i]); 73 } 74 } 75 extraopts.add("-classpath"); 76 extraopts.add(Utils.TEST_CLASS_PATH + File.pathSeparator + Utils.TEST_SRC); 77 if (className != null && libName != null) { 78 OutputAnalyzer oa = launchCompiler(libName, className, extraopts, compileList); 79 oa.shouldHaveExitValue(0); 80 } else { 81 printUsage(); 82 throw new Error("Mandatory arguments aren't passed"); 83 } 84 } 85 86 public static OutputAnalyzer launchCompilerSimple(String... args) { 87 return launchJaotc(Arrays.asList(args), null); 88 } 89 90 public static OutputAnalyzer launchCompiler(String libName, String item, List<String> extraopts, 91 List<String> compList) { 92 Path file = null; 93 if (compList != null && !compList.isEmpty()) { 94 file = Paths.get(METHODS_LIST_FILENAME); 95 try { 96 Files.write(file, compList, StandardOpenOption.CREATE); 97 } catch (IOException e) { 98 throw new Error("Couldn't write " + METHODS_LIST_FILENAME + " " + e, e); 99 } 100 } 101 List<String> args = new ArrayList<>(); 102 args.add("--compile-with-assertions"); 103 args.add("--output"); 104 args.add(libName); 105 if (file != null) { 106 args.add("--compile-commands"); 107 args.add(file.toString()); 108 } 109 args.add("--class-name"); 110 args.add(item); 111 String linker = resolveLinker(); 112 if (linker != null) { 113 args.add("--linker-path"); 114 args.add(linker); 115 } 116 // Execute with asserts 117 args.add("-J-ea"); 118 args.add("-J-esa"); 119 return launchJaotc(args, extraopts); 120 } 121 122 private static OutputAnalyzer launchJaotc(List<String> args, List<String> extraVmOpts) { 123 JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jaotc"); 124 for (String vmOpt : Utils.getTestJavaOpts()) { 125 launcher.addVMArg(vmOpt); 126 } 127 if (extraVmOpts != null) { 128 for (String vmOpt : extraVmOpts) { 129 launcher.addVMArg(vmOpt); 130 } 131 } 132 for (String arg : args) { 133 launcher.addToolArg(arg); 134 } 135 try { 136 return ProcessTools.executeCommand(new ProcessBuilder(launcher.getCommand()).redirectErrorStream(true)); 137 } catch (Throwable e) { 138 throw new Error("Can't start test process: " + e, e); 139 } 140 } 141 142 public static void printUsage() { 143 System.err.println("Usage: " + AotCompiler.class.getName() 144 + " -class <class> -libname <.so name>" 145 + " [-compile <compileItems>]* [-extraopt <java option>]*"); 146 } 147 148 public static String resolveLinker() { 149 Path linker = null; 150 // 1st, check if PATH has ld 151 for (String path : System.getenv("PATH").split(File.pathSeparator)) { 152 if (Files.exists(Paths.get(path).resolve("ld"))) { 153 // there is ld in PATH, jaotc is supposed to find it by its own 154 return null; 155 } 156 } 157 // there is no ld in PATH, will use ld from devkit 158 // artifacts are got from common/conf/jib-profiles.js 159 try { 160 if (Platform.isWindows()) { 161 if (Platform.isX64()) { 162 @Artifact(organization = "jpg.infra.builddeps", 163 name = "devkit-windows_x64", 164 revision = "VS2013SP4+1.0", 165 extension = "tar.gz") 166 class DevkitWindowsX64 { } 167 String artifactName = "jpg.infra.builddeps." 168 + "devkit-windows_x64-" 169 + "VS2013SP4+1.0"; 170 Path devkit = ArtifactResolver.resolve(DevkitWindowsX64.class) 171 .get(artifactName); 172 linker = devkit.resolve("VC") 173 .resolve("bin") 174 .resolve("amd64") 175 .resolve("link.exe"); 176 } 177 } else if (Platform.isOSX()) { 178 @Artifact(organization = "jpg.infra.builddeps", 179 name = "devkit-macosx_x64", 180 revision = "Xcode6.3-MacOSX10.9+1.0", 181 extension = "tar.gz") 182 class DevkitMacosx { } 183 String artifactName = "jpg.infra.builddeps." 184 + "devkit-macosx_x64-" 185 + "Xcode6.3-MacOSX10.9+1.0"; 186 Path devkit = ArtifactResolver.resolve(DevkitMacosx.class) 187 .get(artifactName); 188 linker = devkit.resolve("Xcode.app") 189 .resolve("Contents") 190 .resolve("Developer") 191 .resolve("Toolchains") 192 .resolve("XcodeDefault.xctoolchain") 193 .resolve("usr") 194 .resolve("bin") 195 .resolve("ld"); 196 } else if (Platform.isSolaris()) { 197 if (Platform.isSparc()) { 198 @Artifact(organization = "jpg.infra.builddeps", 199 name = "devkit-solaris_sparcv9", 200 revision = "SS12u4-Solaris11u1+1.0", 201 extension = "tar.gz") 202 class DevkitSolarisSparc { } 203 204 String artifactName = "jpg.infra.builddeps." 205 + "devkit-solaris_sparcv9-" 206 + "SS12u4-Solaris11u1+1.0"; 207 Path devkit = ArtifactResolver.resolve(DevkitSolarisSparc.class) 208 .get(artifactName); 209 linker = devkit.resolve("SS12u4-Solaris11u1") 210 .resolve("gnu") 211 .resolve("bin") 212 .resolve("ld"); 213 } else if (Platform.isX64()) { 214 @Artifact(organization = "jpg.infra.builddeps", 215 name = "devkit-solaris_x64", 216 revision = "SS12u4-Solaris11u1+1.0", 217 extension = "tar.gz") 218 class DevkitSolarisX64 { } 219 220 String artifactName = "jpg.infra.builddeps." 221 + "devkit-solaris_x64-" 222 + "SS12u4-Solaris11u1+1.0"; 223 Path devkit = ArtifactResolver.resolve(DevkitSolarisX64.class) 224 .get(artifactName); 225 linker = devkit.resolve("SS12u4-Solaris11u1") 226 .resolve("bin") 227 .resolve("amd64") 228 .resolve("ld"); 229 } 230 } else if (Platform.isLinux()) { 231 if (Platform.isAArch64()) { 232 @Artifact(organization = "jpg.infra.builddeps", 233 name = "devkit-linux_aarch64", 234 revision = "gcc-linaro-aarch64-linux-gnu-4.8-2013.11_linux+1.0", 235 extension = "tar.gz") 236 class DevkitLinuxAArch64 { } 237 238 String artifactName = "jpg.infra.builddeps." 239 + "devkit-linux_aarch64-" 240 + "gcc-linaro-aarch64-linux-gnu-4.8-2013.11_linux+1.0"; 241 Path devkit = ArtifactResolver.resolve(DevkitLinuxAArch64.class) 242 .get(artifactName); 243 linker = devkit.resolve("aarch64-linux-gnu") 244 .resolve("bin") 245 .resolve("ld"); 246 } else if (Platform.isARM()) { 247 @Artifact(organization = "jpg.infra.builddeps", 248 name = "devkit-linux_arm", 249 revision = "gcc-linaro-arm-linux-gnueabihf-raspbian-2012.09-20120921_linux+1.0", 250 extension = "tar.gz") 251 class DevkitLinuxARM { } 252 253 String artifactName = "jpg.infra.builddeps." 254 + "devkit-linux_arm-" 255 + "gcc-linaro-arm-linux-gnueabihf-raspbian-2012.09-20120921_linux+1.0"; 256 Path devkit = ArtifactResolver.resolve(DevkitLinuxARM.class) 257 .get(artifactName); 258 linker = devkit.resolve("arm-linux-gnueabihf") 259 .resolve("bin") 260 .resolve("ld"); 261 } else if (Platform.isX64()) { 262 @Artifact(organization = "jpg.infra.builddeps", 263 name = "devkit-linux_x64", 264 revision = "gcc4.9.2-OEL6.4+1.1", 265 extension = "tar.gz") 266 class DevkitLinuxX64 { } 267 268 String artifactName = "jpg.infra.builddeps." 269 + "devkit-linux_x64-" 270 + "gcc4.9.2-OEL6.4+1.1"; 271 Path devkit = ArtifactResolver.resolve(DevkitLinuxX64.class) 272 .get(artifactName); 273 linker = devkit.resolve("bin") 274 .resolve("ld"); 275 } 276 } 277 } catch (FileNotFoundException e) { 278 throw new Error("artifact resolution error: " + e, e); 279 } 280 if (linker != null) { 281 return linker.toAbsolutePath().toString(); 282 } 283 return null; 284 } 285 }