| /******************************************************************************* |
| * Copyright (c) 2006,2008 IBM Corp. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corp. - initial implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.ptp.pldt.wizards.wizardPages; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.MissingResourceException; |
| import java.util.ResourceBundle; |
| |
| import org.eclipse.cdt.core.templateengine.TemplateCore; |
| import org.eclipse.cdt.core.templateengine.process.ProcessArgument; |
| import org.eclipse.cdt.core.templateengine.process.ProcessFailureException; |
| import org.eclipse.cdt.core.templateengine.process.ProcessRunner; |
| import org.eclipse.cdt.managedbuilder.core.BuildException; |
| import org.eclipse.cdt.managedbuilder.core.IConfiguration; |
| import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; |
| import org.eclipse.cdt.managedbuilder.core.IManagedProject; |
| import org.eclipse.cdt.managedbuilder.core.IOption; |
| import org.eclipse.cdt.managedbuilder.core.ITool; |
| import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.ptp.pldt.wizards.MpiWizardsPlugin; |
| |
| /** |
| * |
| * After the MPIProjectWizardPage runs, and we get MPI include path from the user, |
| * we have this opportunity to use that information to modify the include paths, build cmd, etc. |
| * in the project |
| * |
| * <p>This handles plain C projects; MPIProjectProcessCPP extends this to handle C++ projects |
| * |
| * @author Beth Tibbitts |
| * |
| */ |
| public class MPIProjectProcess extends ProcessRunner { |
| private static final boolean traceOn=false; |
| private boolean wizTraceOn=MPIProjectWizardPage.wizardTraceOn; |
| //private static final templateID= |
| |
| protected Map<String,String> valueStore; |
| |
| @Override |
| public void process(TemplateCore template, ProcessArgument[] args, |
| String processId, IProgressMonitor monitor) |
| throws ProcessFailureException { |
| if(wizTraceOn)System.out.println("MPIProjectProcess().run()..."); |
| |
| valueStore= template.getValueStore(); |
| String pageID = MPIProjectWizardPage.PAGE_ID; |
| |
| Object obj = getNewPropValue(pageID, MPIProjectWizardPage.DO_MPI_INCLUDES, null); |
| // use the default value if nothing was set in the pageData by the user |
| boolean doMpiIncludes = MPIProjectWizardPage.getDefaultUseMpiIncludes(); |
| if (obj != null) |
| doMpiIncludes = Boolean.valueOf((String) obj); |
| if (!doMpiIncludes) { |
| if (traceOn) |
| System.out.println("Do not save MPI info in this project."); |
| return; |
| } |
| |
| // this process must be executed after a separate process which creates the project |
| IProject proj= ResourcesPlugin.getWorkspace().getRoot().getProject(valueStore.get("projectName")); |
| if(!proj.exists()) { |
| System.out.println("Project does not exist!. Quitting. No MPI info added to project."); |
| return; |
| } |
| |
| if(traceOn)System.out.println("Project: " + proj.getName()); |
| |
| // Collect the values that the user entered on the wizard page |
| String propID = MPIProjectWizardPage.INCLUDE_PATH_PROP_ID; |
| String newIncludePath = getNewPropValue(pageID, propID,"c:/mpich2/include"); |
| if(traceOn)System.out.println("Got prop: "+propID+"="+newIncludePath); |
| |
| propID = MPIProjectWizardPage.LIB_PROP_ID; |
| String newLib=getNewPropValue(pageID,propID,"lib"); |
| |
| propID=MPIProjectWizardPage.LIBRARY_SEARCH_PATH_PROP_ID; |
| String newLibSearchPath=getNewPropValue(pageID,propID,"c:/mpich2/lib"); |
| |
| propID=MPIProjectWizardPage.MPI_COMPILE_COMMAND_PROP_ID; |
| String mpiCompileCommand=getNewPropValue(pageID,propID,"mpicc"); |
| |
| propID=MPIProjectWizardPage.MPI_LINK_COMMAND_PROP_ID; |
| String mpiLinkCommand=getNewPropValue(pageID,propID,"mpicc"); |
| |
| IManagedBuildInfo info = null; |
| try { |
| info = ManagedBuildManager.getBuildInfo(proj); |
| // note: assumed null if this is not a managed build project? will we get here in that case? |
| if(traceOn)System.out.println("Build info: " + info); |
| } catch (Exception e) { |
| System.out.println("MPIProjectProcess.run(), "+e.getMessage()); |
| e.printStackTrace(); |
| return; |
| } |
| assert(info!=null); |
| |
| IManagedProject mProj = info.getManagedProject(); |
| if(traceOn)showOptions(mProj); |
| |
| // add the include path, linker, build cmd, etc. values to all the configurations |
| IConfiguration[] configs = mProj.getConfigurations(); |
| for (int i = 0; i < configs.length; i++) { |
| IConfiguration cf = configs[i]; |
| if(traceOn)System.out.println("Config " + i + ": " + cf.getName()); |
| addIncludePath(cf, newIncludePath); |
| addLinkerOpt(cf,newLib,newLibSearchPath); |
| setCompileCommand(cf,mpiCompileCommand); |
| setLinkCommand(cf,mpiLinkCommand); |
| } |
| if(traceOn)System.out.println("MPIProjectProcess, newIncludePath: "+newIncludePath); |
| if(traceOn)System.out.println(" newLib: "+newLib+" newLibSrchPth: "+newLibSearchPath); |
| if(traceOn)System.out.println(" compileCmd: "+mpiCompileCommand); |
| if(traceOn)System.out.println(" linkCmd: "+mpiLinkCommand); |
| // ManagedBuildManger.saveBuildInfo(...) assures that the |
| // values are persisted in the build model, otherwise they will |
| // be lost when you shut down Eclipse. |
| if(traceOn)System.out.println("ManagedBuildManager.saveBuildInfo..."); |
| |
| ManagedBuildManager.saveBuildInfo(proj, true); |
| |
| } |
| public static String getResourceString(String key) { |
| ResourceBundle bundle = MpiWizardsPlugin.getDefault().getResourceBundle(); |
| try { |
| return (bundle != null) ? bundle.getString(key) : key; |
| } catch (MissingResourceException e) { |
| return key; |
| } |
| } |
| |
| /** |
| * Get a value that was possibly obtained from the user on the associated wizard page. |
| * @param pageID The pageID for our wizard page |
| * @param propID The propID of the value we want |
| * @param defaultVal The default value to use if the user didn't select anything, |
| * or if we haven't gotten around to LETTING the user select anything yet. |
| * @return |
| */ |
| protected String getNewPropValue(String pageID, String propID, String defaultVal) { |
| Object obj = valueStore.get(pageID+MPIProjectWizardPage.DOT+propID); |
| // if selection made on page, obj is non-null. |
| String newValue = defaultVal; |
| String msg=" ( used default value)"; |
| if (obj != null) { |
| newValue = obj.toString(); |
| msg=""; |
| } |
| if(traceOn)System.out.println("propID=" + propID + " value=" + newValue+msg); |
| return newValue; |
| } |
| |
| |
| /** |
| * Add an include path for C compiling to the existing include paths of the given |
| * Configuration. XLC is handled as a special case to find its include path option; |
| * for other tools, we assume there is a single option for include paths, so we take |
| * the first one. |
| * |
| * @param cf |
| * the configuration of the project (e.g. Release, Debug, etc.) |
| * @param newIncludePath |
| * include path(s) to add. If more than one, separate by |
| * java.io.File.pathSeparator, which is semicolon for Windows, colon for Mac/Linux |
| */ |
| protected void addIncludePath(IConfiguration cf, String newIncludePath) { |
| // note: could be > 1 path in 'newIncludePath' |
| String ext = "c"; |
| ITool cfTool = cf.getToolFromInputExtension(ext); |
| |
| //String id = cfTool.getId(); // "cdt.managedbuild.tool.xlc.c.compiler.exe.debug.1423270745" |
| String name = cfTool.getName();// "XL C Compiler" |
| IOption option = null; |
| if (name.startsWith("XL C")) { // special case for XL C compiler |
| option = cfTool.getOptionById("xlc.c.compiler.option.include.paths"); |
| } else { // otherwise we assume there is only one include path option. |
| option = getFirstOptionByType(cf, cfTool, IOption.INCLUDE_PATH); |
| } |
| if (option != null) { |
| String[] includePaths = null; |
| try { |
| includePaths = option.getIncludePaths(); |
| } catch (BuildException e) { |
| e.printStackTrace(); |
| } |
| String[] newIncludePaths = add(includePaths, newIncludePath); |
| if (traceOn) |
| System.out.println(" add " + newIncludePath + " to existing includePaths: " |
| + unroll(includePaths)); |
| ManagedBuildManager.setOption(cf, cfTool, option, newIncludePaths); |
| } |
| else{ |
| System.out.println("MPIProjectProcess, no option for include paths found."); |
| } |
| } |
| |
| |
| /** |
| * Add a new linker option. Assumes that there is ONE instance of an option |
| * of type <code>IOption.LIBRARY_PATHS</code> and <code>IOption.LIBRARIES</code>. |
| * This method adds the libName and libPath to these two options. |
| * @param cf the Configuration to which we want to add to linker options |
| * @param libName the lib name (e.g. "lib") |
| * @param libPath the library search path name (e.g. "c:/mypath/lib") |
| * |
| */ |
| protected void addLinkerOpt(IConfiguration cf, String libName, String libPath) { |
| String ext = "o"; |
| ITool cfTool = cf.getToolFromInputExtension(ext); |
| |
| IOption lpOpt = getFirstOptionByType(cf, cfTool, IOption.LIBRARY_PATHS); |
| addOptionValue(cf, cfTool, lpOpt, libPath); |
| |
| IOption libOpt = getFirstOptionByType(cf, cfTool, IOption.LIBRARIES); |
| addOptionValue(cf, cfTool, libOpt, libName); |
| } |
| |
| |
| protected void setCompileCommand(IConfiguration cf, String buildCmd) { |
| if(traceOn)System.out.println("compile cmd: "+buildCmd); |
| ITool compiler = cf.getToolFromInputExtension("c"); |
| compiler.setToolCommand(buildCmd); |
| } |
| |
| protected void setLinkCommand(IConfiguration cf, String buildCmd) { |
| if(traceOn)System.out.println("link cmd: "+buildCmd); |
| ITool linker=cf.getToolFromInputExtension("o"); |
| linker.setToolCommand(buildCmd); |
| |
| } |
| |
| /** |
| * Add a value to a multi-valued tool option<br> |
| * (For example, add a path to include paths, or a lib to libraries list) |
| * @param cf the Configuration |
| * @param tool the tool in which to update the option |
| * @param option the option to update |
| * @param value the new value to add to the list of existing values in the option |
| */ |
| protected void addOptionValue(IConfiguration cf, ITool tool, IOption option, String value) { |
| try { |
| int type = option.getValueType(); |
| String[] valueList = null; |
| switch (type) { |
| case IOption.INCLUDE_PATH: |
| valueList = option.getIncludePaths(); |
| valueList = add(valueList,value); |
| break; |
| case IOption.LIBRARIES: |
| valueList = option.getLibraries(); |
| valueList=addNotPath(valueList, value); |
| break; |
| case IOption.LIBRARY_PATHS:// this is type for library search path cdt 4.0 |
| valueList=option.getBasicStringListValue(); |
| valueList=addNotPath(valueList,value); |
| break; |
| |
| default: |
| System.out.println("MPIProjectWizard Process postprocessing (MPIProjectProcess), can't get type of option for " + option.getName()); |
| return; |
| } |
| // update the option in the managed builder options |
| ManagedBuildManager.setOption(cf, tool, option, valueList); |
| |
| } catch (BuildException e) { |
| System.out.println("MPIProjectProcess.addOptionValue(), "+e.getMessage()); |
| System.out.println(e.getMessage()); |
| e.printStackTrace(); |
| } |
| |
| } |
| |
| /** |
| * Print the options for a project.<br> |
| * e.g. for Debug and Release configurations, get all the tools (compiler, linker etc.) then for each tool, |
| * get all the options and print them. |
| * |
| * IResource resource= ... ;// can be any resource, I use project. |
| * IManagedBuildInfo mbo = ManagedBuildManager.getBuildInfo(resource); |
| * IManagedProject mp=mbo.getManagedProject(); |
| * <br> |
| * This helps in figuring out what they are, and what you want to change. |
| * Some sample output is at the bottom of this file. |
| * |
| * @param proj the (managed) project for which print all this stuff. |
| */ |
| protected void showOptions(IManagedProject proj) { |
| if(traceOn)System.out.println("Managed Project: "+proj.getName()); |
| if(traceOn)System.out.println("Path.SEPARATOR="+Path.SEPARATOR); |
| if(traceOn)System.out.println("Path.DEVICE_SEPARATOR="+Path.DEVICE_SEPARATOR); |
| IConfiguration[] configs = proj.getConfigurations(); |
| try { |
| for (int i = 0; i < configs.length; i++) { |
| IConfiguration cf = configs[i]; |
| ITool[] allTools = cf.getTools(); |
| |
| int numTools = allTools.length; |
| System.out.println("Config " + i + ": " + cf.getName()+ " has "+numTools+" tools."); |
| |
| for (int k = 0; k < allTools.length; k++) { |
| ITool tool = allTools[k]; |
| System.out.println(" Tool " + k + ": " + tool.getName()); |
| //boolean rc=tool.setToolCommand("foo"); |
| String toolCmd=tool.getToolCommand(); |
| String toolID=tool.getId(); |
| System.out.println(" cmd="+toolCmd+" toolID="+toolID); |
| |
| |
| IOption[] options = tool.getOptions(); |
| |
| for (int j = 0; j < options.length; j++) { |
| IOption opt = options[j]; |
| String foundOptionID = opt.getId(); |
| int type=opt.getValueType(); |
| System.out.println(" option " + j + " " + opt.getName() + " id=" |
| + foundOptionID+" type="+showType(type)); |
| if(opt.getValueType()==IOption.INCLUDE_PATH) { |
| showIncludePaths(opt); |
| } |
| } |
| } |
| |
| System.out.println("Config " + i + ": " + cf.getName() |
| + "======= End of ALL tools "); |
| |
| // another way to access Tool |
| String ext = "c"; |
| ITool cfTool = cf.getToolFromInputExtension(ext); |
| System.out.println("Tool by ext: " + ext + " is: " + cfTool.getName()); |
| |
| // Look for include path |
| IOption option = getFirstOptionByType(cf, cfTool, IOption.INCLUDE_PATH); |
| if (option != null) { |
| String oname = option.getName(); |
| System.out.println("Option " + option.getId() + " is " + oname); |
| showIncludePaths(option); |
| } |
| else System.out.println("No include path option found. "); |
| |
| } |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| |
| } |
| protected String showType(int type){ |
| if(type==IOption.INCLUDE_PATH) return type+" (IOption.INCLUDE_PATH)"; |
| if(type==IOption.LIBRARY_PATHS) return type+" (IOption.LIBRARY_PATHS)"; |
| if(type==IOption.LIBRARIES) return type+" (IOption.LIBRARIES)"; |
| return type+" "; |
| } |
| |
| /** |
| * Display the list of include paths in an option which is presumed |
| * to be the include paths option. |
| * @param opt |
| * @throws BuildException |
| */ |
| protected void showIncludePaths(IOption opt) throws BuildException { |
| assert opt.getValueType() == IOption.INCLUDE_PATH ; |
| // if the option is a list of include paths, display them. |
| String[] includePaths = opt.getIncludePaths(); |
| for (int index = 0; index < includePaths.length; index++) { |
| String path = includePaths[index]; |
| System.out.println(" include path " + index + ": " + path); |
| } |
| |
| } |
| |
| /** |
| * Add one or more paths to the list of paths |
| * |
| * @param existingPaths the existing list of paths to add to |
| * @param newPath the new path to add; may be >1 directory, with path delimiter java.io.File.pathSeparator |
| * (usually semicolon or colon) |
| * @return the merged list |
| */ |
| protected String[] add(String[] existingPaths, String newPath) { |
| String pathSep=java.io.File.pathSeparator; // semicolon for windows, colon for Mac/Linux |
| List<String> newPathList = new ArrayList<String>(); |
| String path; |
| for (int i = 0; i < existingPaths.length; i++) { |
| path = existingPaths[i]; |
| newPathList.add(path); |
| } |
| String[] newPathArray=newPath.split(pathSep); |
| for (int i = 0; i < newPathArray.length; i++) { |
| path = newPathArray[i]; |
| newPathList.add(path); |
| } |
| |
| String[] newArray=(String[])newPathList.toArray(new String[0]); |
| return newArray; |
| } |
| |
| /** |
| * Add a single string to an array of strings |
| * @param strList |
| * @param newStr |
| * @return |
| */ |
| protected String[] addNotPath(String[] strList, String newStr) { |
| int len = strList.length; |
| String newList[] = new String[len + 1]; |
| System.arraycopy(strList, 0, newList, 0, len); |
| newList[len] = newStr; |
| return newList; |
| } |
| /** |
| * Simple string representation of items in a string array |
| * @param list |
| * @return |
| */ |
| protected String unroll (String[] list){ |
| StringBuffer result=new StringBuffer(); |
| //list = new String[]{"one","two"}; |
| //System.out.println(list); |
| for (int i = 0; i < list.length; i++) { |
| String string = list[i]; |
| result.append(string); |
| result.append(", "); |
| } |
| if (result.length() > 2) { |
| result.delete(result.length() - 2, result.length() - 1); |
| } |
| return result.toString(); |
| } |
| /** |
| * Get the options of a specific type.<br> |
| * We really need an ITool.getOptionsByType(int) so we don't have to do |
| * this. |
| * |
| * @param cf |
| * the IConfiguration in which to search |
| * @param cfTool |
| * the ITool whose options are being searched |
| * @param optionType |
| * the option type we are looking for, e.g. IOption.SOMETHING |
| * @return |
| */ |
| protected List<IOption> getOptionsByType(IConfiguration cf, ITool cfTool, int optionType) { |
| |
| // run thru ALL options and check type for each, returning the ones that match |
| IOption[] allOptions = cfTool.getOptions(); |
| List<IOption> foundOptions = new ArrayList<IOption>(); |
| |
| for (int i = 0; i < allOptions.length; i++) { |
| IOption option = allOptions[i]; |
| |
| int oType = 0; |
| try { |
| oType = option.getValueType(); |
| } catch (BuildException e) { |
| e.printStackTrace(); |
| continue; |
| } |
| if (optionType == oType) { |
| // add it to the list |
| foundOptions.add(option); |
| } |
| |
| } |
| //IOption[] ret= foundOptions.toArray(new IOption[foundOptions.size()]); |
| return foundOptions; |
| } |
| /** |
| * Returns the <i>first</i> option of the specified type from the tool |
| * @param cf |
| * @param cfTool |
| * @param optionType |
| * @return |
| */ |
| protected IOption getFirstOptionByType(IConfiguration cf, ITool cfTool, int optionType){ |
| List<IOption> allOptions=getOptionsByType(cf,cfTool,optionType); |
| if(allOptions.size()>0){ |
| return allOptions.get(0); |
| } |
| return null; |
| } |
| } |
| |
| /** |
| * |
| * Some sample tool data from showOptions() on Windows XP with cygwin Tool 1: |
| * GCC C Compiler |
| * <p> |
| * |
| * option 0 Do not search system directories (-nostdinc) |
| * id=gnu.c.compiler.option.preprocessor.nostdinc<br> |
| * option 1 Preprocess only (-E) |
| * id=gnu.c.compiler.option.preprocessor.preprocess<br> |
| * option 2 Defined symbols (-D) |
| * id=gnu.c.compiler.option.preprocessor.def.symbols<br> |
| * option 3 Undefined symbols (-U) |
| * id=gnu.c.compiler.option.preprocessor.undef.symbol<br> |
| * option 4 Include paths (-I) id=gnu.c.compiler.option.include.paths<br> |
| * option 5 Optimization Level |
| * id=gnu.c.compiler.cygwin.exe.release.option.optimization.level<br> |
| * option 6 Other optimization flags id=gnu.c.compiler.option.optimization.flags<br> |
| * option 7 Debug Level |
| * id=gnu.c.compiler.cygwin.exe.release.option.debugging.level<br> |
| * option 8 Other debugging flags id=gnu.c.compiler.option.debugging.other<br> |
| * option 9 Generate gprof information (-pg) |
| * id=gnu.c.compiler.option.debugging.gprof<br> |
| * option 10 Generate prof information (-p) |
| * id=gnu.c.compiler.option.debugging.prof<br> |
| * option 11 Check syntax only (-fsyntax-only) |
| * id=gnu.c.compiler.option.warnings.syntax<br> |
| * option 12 Pedantic (-pedantic) id=gnu.c.compiler.option.warnings.pedantic<br> |
| * option 13 Pedantic warnings as errors (-pedantic-errors) |
| * id=gnu.c.compiler.option.warnings.pedantic.error<br> |
| * option 14 Inhibit all warnings (-w) id=gnu.c.compiler.option.warnings.nowarn<br> |
| * option 15 All warnings (-Wall) id=gnu.c.compiler.option.warnings.allwarn<br> |
| * option 16 Warnings as errors (-Werror) |
| * id=gnu.c.compiler.option.warnings.toerrors<br> |
| * option 17 Other flags id=gnu.c.compiler.option.misc.other<br> |
| * option 18 Verbose (-v) id=gnu.c.compiler.option.misc.verbose<br> |
| * option 19 Support ANSI programs (-ansi) id=gnu.c.compiler.option.misc.ansi<br> |
| * |
| * Tool 2: GCC C Linker <br> |
| * option 5 Libraries (-l) id=gnu.c.link.option.libs<br> |
| * option 6 Library search path (-L) id=gnu.c.link.option.paths<br> |
| * |
| */ |
| |