SGXSDKDiscoveryUpdater.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. ///////////////////////////////////////////////////////////////////////////
  2. // Copyright (c) 2018 Intel Corporation. //
  3. // //
  4. // All rights reserved. This program and the accompanying materials //
  5. // are made available under the terms of the Eclipse Public License v1.0 //
  6. // which accompanies this distribution, and is available at //
  7. // http://www.eclipse.org/legal/epl-v10.html //
  8. // //
  9. // Contributors: //
  10. // Intel Corporation - initial implementation and documentation //
  11. ///////////////////////////////////////////////////////////////////////////
  12. package com.intel.sgx.discovery;
  13. import java.io.BufferedReader;
  14. import java.io.File;
  15. import java.io.IOException;
  16. import java.io.InputStream;
  17. import java.io.InputStreamReader;
  18. import java.net.URISyntaxException;
  19. import java.net.URL;
  20. import java.util.ArrayList;
  21. import java.util.HashMap;
  22. import java.util.List;
  23. import java.util.Map;
  24. import java.util.Map.Entry;
  25. import org.eclipse.cdt.core.CCorePlugin;
  26. import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
  27. import org.eclipse.cdt.core.envvar.IEnvironmentVariableManager;
  28. import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
  29. import org.eclipse.cdt.managedbuilder.core.IBuilder;
  30. import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
  31. import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
  32. import org.eclipse.core.resources.IProject;
  33. import org.eclipse.core.runtime.CoreException;
  34. import org.eclipse.core.runtime.FileLocator;
  35. import org.eclipse.core.runtime.IPath;
  36. import org.eclipse.core.runtime.IProgressMonitor;
  37. import org.eclipse.core.runtime.Path;
  38. import com.intel.sgx.Activator;
  39. import com.intel.sgx.build.SGXSDKCommandLauncher;
  40. /*
  41. * This code has been taken from the NDK plugin for Linux. If there is an update to this code there, then refactor this code.
  42. */
  43. public class SGXSDKDiscoveryUpdater {
  44. private final SGXSDKDiscoveredPathInfo mPathInfo;
  45. private final IProject mProject;
  46. private boolean mCPlusPlus = false;
  47. private String mCommand;
  48. private List<String> mArguments = new ArrayList<String>();
  49. public SGXSDKDiscoveryUpdater(SGXSDKDiscoveredPathInfo pathInfo) {
  50. mPathInfo = pathInfo;
  51. mProject = pathInfo.getProject();
  52. }
  53. public void runUpdate(IProgressMonitor monitor) throws CoreException {
  54. try {
  55. // Run make -nB to get the list of commands
  56. IPath commandPath = new Path("make"); //$NON-NLS-1$
  57. String[] args = {"-f", "sgx/Makefile", "-n", "-B" }; //$NON-NLS-1$
  58. String[] env = calcEnvironment();
  59. File projectDir = new File(mProject.getLocationURI());
  60. IPath changeToDirectory = new Path(projectDir.getAbsolutePath());
  61. Process proc = new SGXSDKCommandLauncher().execute(commandPath, args, env,changeToDirectory, monitor);
  62. if (proc == null) {
  63. return;
  64. }
  65. BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
  66. String line = reader.readLine();
  67. while (line != null) {
  68. checkBuildLine(line);
  69. line = reader.readLine();
  70. }
  71. if (mCommand == null) {
  72. return;
  73. }
  74. // Run the unique commands with special gcc options to extract the
  75. // symbols and paths
  76. // -E -P -v -dD
  77. mArguments.add("-E"); //$NON-NLS-1$
  78. mArguments.add("-P"); //$NON-NLS-1$
  79. mArguments.add("-v"); //$NON-NLS-1$
  80. mArguments.add("-dD"); //$NON-NLS-1$
  81. URL url = Activator.findFile(new Path("discovery/" + (mCPlusPlus ? "test.cpp" : "test.c"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
  82. File testFile = new File(FileLocator.toFileURL(url).toURI());
  83. String testFileName = testFile.getAbsolutePath().replace('\\', '/');
  84. mArguments.add(testFileName);
  85. args = mArguments.toArray(new String[mArguments.size()]);
  86. proc = new SGXSDKCommandLauncher().execute(new Path(mCommand), args, env,changeToDirectory, monitor);
  87. final InputStream errStream = proc.getErrorStream();
  88. new Thread() {
  89. @Override
  90. public void run() {
  91. checkIncludes(errStream);
  92. };
  93. }.start();
  94. checkDefines(proc.getInputStream());
  95. } catch (IOException e) {
  96. throw new CoreException(Activator.newStatus(e));
  97. } catch (URISyntaxException e) {
  98. throw new CoreException(Activator.newStatus(e));
  99. }
  100. }
  101. private String[] calcEnvironment() throws CoreException {
  102. IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(mProject);
  103. IBuilder builder = info.getDefaultConfiguration().getBuilder();
  104. HashMap<String, String> envMap = new HashMap<String, String>();
  105. if (builder.appendEnvironment()) {
  106. ICConfigurationDescription cfgDes = ManagedBuildManager.getDescriptionForConfiguration(builder.getParent().getParent());
  107. IEnvironmentVariableManager mngr = CCorePlugin.getDefault().getBuildEnvironmentManager();
  108. IEnvironmentVariable[] vars = mngr.getVariables(cfgDes, true);
  109. for (IEnvironmentVariable var : vars) {
  110. envMap.put(var.getName(), var.getValue());
  111. }
  112. }
  113. // Add variables from build info
  114. Map<String, String> builderEnv = builder.getExpandedEnvironment();
  115. if (builderEnv != null)
  116. envMap.putAll(builderEnv);
  117. List<String> strings = new ArrayList<String>(envMap.size());
  118. for (Entry<String, String> entry : envMap.entrySet()) {
  119. StringBuffer buffer = new StringBuffer(entry.getKey());
  120. buffer.append('=').append(entry.getValue());
  121. strings.add(buffer.toString());
  122. }
  123. return strings.toArray(new String[strings.size()]);
  124. }
  125. private static class Line {
  126. private final String line;
  127. private int pos;
  128. public Line(String line) {
  129. this.line = line;
  130. }
  131. public Line(String line, int pos) {
  132. this(line);
  133. this.pos = pos;
  134. }
  135. public String getToken() {
  136. skipWhiteSpace();
  137. if (pos == line.length())
  138. return null;
  139. int start = pos;
  140. boolean inQuote = false;
  141. while (true) {
  142. char c = line.charAt(pos);
  143. if (c == ' ') {
  144. if (!inQuote)
  145. return line.substring(start, pos);
  146. } else if (c == '"') {
  147. inQuote = !inQuote;
  148. }
  149. if (++pos == line.length())
  150. return null;
  151. }
  152. }
  153. private String getRemaining() {
  154. if (pos == line.length())
  155. return null;
  156. skipWhiteSpace();
  157. String rc = line.substring(pos);
  158. pos = line.length();
  159. return rc;
  160. }
  161. private void skipWhiteSpace() {
  162. while (true) {
  163. if (pos == line.length())
  164. return;
  165. char c = line.charAt(pos);
  166. if (c == ' ')
  167. pos++;
  168. else
  169. return;
  170. }
  171. }
  172. }
  173. private void checkBuildLine(String text) {
  174. Line line = new Line(text);
  175. String cmd = line.getToken();
  176. if (cmd == null) {
  177. return;
  178. } else if (cmd.endsWith("g++")) { //$NON-NLS-1$
  179. if (mCommand == null || !mCPlusPlus) {
  180. mCommand = cmd;
  181. mCPlusPlus = true;
  182. }
  183. gatherOptions(line);
  184. } else if (cmd.endsWith("gcc")) { //$NON-NLS-1$
  185. if (mCommand == null){
  186. mCommand = cmd;
  187. }
  188. gatherOptions(line);
  189. }
  190. }
  191. private void gatherOptions(Line line) {
  192. for (String option = line.getToken(); option != null; option = line.getToken()) {
  193. if (option.startsWith("-")) { //$NON-NLS-1$
  194. // only look at options
  195. if (option.equals("-I")) { //$NON-NLS-1$
  196. String dir = line.getToken();
  197. if (dir != null)
  198. addArg(option + dir);
  199. } else if (option.startsWith("-I")) { //$NON-NLS-1$
  200. addArg(option);
  201. } else if (option.equals("-D")) { //$NON-NLS-1$
  202. String def = line.getToken();
  203. if (def != null)
  204. addArg(option + def);
  205. } else if (option.startsWith("-D")) { //$NON-NLS-1$
  206. addArg(option);
  207. } else if (option.startsWith("-f")) { //$NON-NLS-1$
  208. addArg(option);
  209. } else if (option.startsWith("-m")) { //$NON-NLS-1$
  210. addArg(option);
  211. } else if (option.startsWith("--sysroot")) { //$NON-NLS-1$
  212. addArg(option);
  213. }
  214. }
  215. }
  216. }
  217. private void addArg(String arg) {
  218. if (!mArguments.contains(arg))
  219. mArguments.add(arg);
  220. }
  221. private void checkIncludes(InputStream in) {
  222. try {
  223. List<String> includes = new ArrayList<String>();
  224. boolean inIncludes1 = false;
  225. boolean inIncludes2 = false;
  226. BufferedReader reader = new BufferedReader(new InputStreamReader(in));
  227. String line = reader.readLine();
  228. while (line != null) {
  229. if (!inIncludes1) {
  230. if (line.equals("#include \"...\" search starts here:")) //$NON-NLS-1$
  231. inIncludes1 = true;
  232. } else {
  233. if (!inIncludes2) {
  234. if (line.equals("#include <...> search starts here:")) //$NON-NLS-1$
  235. inIncludes2 = true;
  236. else
  237. includes.add(line.trim());
  238. } else {
  239. if (line.equals("End of search list.")) { //$NON-NLS-1$
  240. mPathInfo.setIncludePaths(includes);
  241. } else {
  242. includes.add(line.trim());
  243. }
  244. }
  245. }
  246. line = reader.readLine();
  247. }
  248. } catch (IOException e) {
  249. Activator.log(e);
  250. }
  251. }
  252. private void checkDefines(InputStream in) {
  253. try {
  254. Map<String, String> defines = new HashMap<String, String>();
  255. BufferedReader reader = new BufferedReader(new InputStreamReader(in));
  256. String line = reader.readLine();
  257. while (line != null) {
  258. if (line.startsWith("#define")) { //$NON-NLS-1$
  259. Line l = new Line(line, 7);
  260. String var = l.getToken();
  261. if (var == null)
  262. continue;
  263. String value = l.getRemaining();
  264. if (value == null)
  265. value = ""; //$NON-NLS-1$
  266. defines.put(var, value);
  267. }
  268. line = reader.readLine();
  269. }
  270. mPathInfo.setSymbols(defines);
  271. } catch (IOException e) {
  272. Activator.log(e);
  273. }
  274. }
  275. }