src/share/tools/ProjectCreator/WinGammaPlatform.java

Wed, 15 Dec 2010 07:11:31 -0800

author
sla
date
Wed, 15 Dec 2010 07:11:31 -0800
changeset 2369
aa6e219afbf1
parent 2314
f95d63e2154a
child 2540
15d6977f04b0
permissions
-rw-r--r--

7006354: Updates to Visual Studio project creation and development launcher
Summary: Updates to Visual Studio project creation and development launcher
Reviewed-by: stefank, coleenp

     1 /*
     2  * Copyright (c) 1999, 2010, 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  */
    25 import java.io.File;
    26 import java.io.IOException;
    27 import java.io.PrintWriter;
    28 import java.util.Enumeration;
    29 import java.util.Hashtable;
    30 import java.util.Iterator;
    31 import java.util.List;
    32 import java.util.TreeSet;
    33 import java.util.Vector;
    35 abstract class HsArgHandler extends ArgHandler {
    36     static final int STRING = 1;
    37     static final int VECTOR = 2;
    38     static final int HASH   = 3;
    40     boolean nextNotKey(ArgIterator it) {
    41         if (it.next()) {
    42             String s = it.get();
    43             return (s.length() == 0) || (s.charAt(0) != '-');
    44         } else {
    45             return false;
    46         }
    47     }
    49     void empty(String key, String message) {
    50         if (key != null) {
    51             System.err.println("** Error: empty " + key);
    52         }
    53         if (message != null) {
    54             System.err.println(message);
    55         }
    56         WinGammaPlatform.usage();
    57     }
    59     static String getCfg(String val) {
    60         int under = val.indexOf('_');
    61         int len = val.length();
    62         if (under != -1 && under < len - 1) {
    63             return val.substring(under+1, len);
    64         } else {
    65             return null;
    66         }
    67     }
    68 }
    70 class ArgRuleSpecific extends ArgRule {
    71     ArgRuleSpecific(String arg, ArgHandler handler) {
    72         super(arg, handler);
    73     }
    75     boolean match(String rulePattern, String arg) {
    76         return rulePattern.startsWith(arg);
    77     }
    78 }
    81 class SpecificHsArgHandler extends HsArgHandler {
    83     String message, argKey, valKey;
    84     int type;
    86     public void handle(ArgIterator it) {
    87         String cfg = getCfg(it.get());
    88         if (nextNotKey(it)) {
    89             String val = it.get();
    90             switch (type) {
    91             case VECTOR:
    92                 BuildConfig.addFieldVector(cfg, valKey, val);
    93                 break;
    94             case HASH:
    95                 BuildConfig.putFieldHash(cfg, valKey, val, "1");
    96                 break;
    97             case STRING:
    98                 BuildConfig.putField(cfg, valKey, val);
    99                 break;
   100             default:
   101                 empty(valKey, "Unknown type: "+type);
   102             }
   103             it.next();
   105         } else {
   106             empty(argKey, message);
   107         }
   108     }
   110     SpecificHsArgHandler(String argKey, String valKey, String message, int type) {
   111         this.argKey = argKey;
   112         this.valKey = valKey;
   113         this.message = message;
   114         this.type = type;
   115     }
   116 }
   119 class HsArgRule extends ArgRuleSpecific {
   121     HsArgRule(String argKey, String valKey, String message, int type) {
   122         super(argKey, new SpecificHsArgHandler(argKey, valKey, message, type));
   123     }
   125 }
   127 public abstract class WinGammaPlatform {
   129     public boolean fileNameStringEquality(String s1, String s2) {
   130         return s1.equalsIgnoreCase(s2);
   131     }
   133     static void usage() throws IllegalArgumentException {
   134         System.err.println("WinGammaPlatform platform-specific options:");
   135         System.err.println("  -sourceBase <path to directory (workspace) " +
   136                            "containing source files; no trailing slash>");
   137         System.err.println("  -projectFileName <full pathname to which project file " +
   138                            "will be written; all parent directories must " +
   139                            "already exist>");
   140         System.err.println("  If any of the above are specified, "+
   141                            "they must all be.");
   142         System.err.println("  Additional, optional arguments, which can be " +
   143                            "specified multiple times:");
   144         System.err.println("    -absoluteInclude <string containing absolute " +
   145                            "path to include directory>");
   146         System.err.println("    -relativeInclude <string containing include " +
   147                            "directory relative to -sourceBase>");
   148         System.err.println("    -define <preprocessor flag to be #defined " +
   149                            "(note: doesn't yet support " +
   150                            "#define (flag) (value))>");
   151         System.err.println("    -startAt <subdir of sourceBase>");
   152         System.err.println("    -additionalFile <file not in database but " +
   153                            "which should show up in project file>");
   154         System.err.println("    -additionalGeneratedFile <absolute path to " +
   155                            "directory containing file; no trailing slash> " +
   156                            "<name of file generated later in the build process>");
   157         throw new IllegalArgumentException();
   158     }
   161     public void addPerFileLine(Hashtable table,
   162                                String fileName,
   163                                String line) {
   164         Vector v = (Vector) table.get(fileName);
   165         if (v != null) {
   166             v.add(line);
   167         } else {
   168             v = new Vector();
   169             v.add(line);
   170             table.put(fileName, v);
   171         }
   172     }
   174     protected static class PerFileCondData {
   175         public String releaseString;
   176         public String debugString;
   177     }
   179     protected void addConditionalPerFileLine(Hashtable table,
   180                                            String fileName,
   181                                            String releaseLine,
   182                                            String debugLine) {
   183         PerFileCondData data = new PerFileCondData();
   184         data.releaseString = releaseLine;
   185         data.debugString = debugLine;
   186         Vector v = (Vector) table.get(fileName);
   187         if (v != null) {
   188             v.add(data);
   189         } else {
   190             v = new Vector();
   191             v.add(data);
   192             table.put(fileName, v);
   193         }
   194     }
   196     protected static class PrelinkCommandData {
   197       String description;
   198       String commands;
   199     }
   201     protected void addPrelinkCommand(Hashtable table,
   202                                      String build,
   203                                      String description,
   204                                      String commands) {
   205       PrelinkCommandData data = new PrelinkCommandData();
   206       data.description = description;
   207       data.commands = commands;
   208       table.put(build, data);
   209     }
   211     public boolean findString(Vector v, String s) {
   212         for (Iterator iter = v.iterator(); iter.hasNext(); ) {
   213             if (((String) iter.next()).equals(s)) {
   214                 return true;
   215             }
   216         }
   218         return false;
   219     }
   221     /* This returns a String containing the full path to the passed
   222        file name, or null if an error occurred. If the file was not
   223        found or was a duplicate and couldn't be resolved using the
   224        preferred paths, the file name is added to the appropriate
   225        Vector of Strings. */
   226     private String findFileInDirectory(String fileName,
   227                                        DirectoryTree directory,
   228                                        Vector preferredPaths,
   229                                        Vector filesNotFound,
   230                                        Vector filesDuplicate) {
   231         List locationsInTree = directory.findFile(fileName);
   232         int  rootNameLength = directory.getRootNodeName().length();
   233         String name = null;
   234         if ((locationsInTree == null) ||
   235             (locationsInTree.size() == 0)) {
   236             filesNotFound.add(fileName);
   237         } else if (locationsInTree.size() > 1) {
   238             // We shouldn't have duplicate file names in our workspace.
   239             System.err.println();
   240             System.err.println("There are multiple files named as: " + fileName);
   241             System.exit(-1);
   242             // The following code could be safely removed if we don't need duplicate
   243             // file names.
   245             // Iterate through them, trying to find one with a
   246             // preferred path
   247         search:
   248             {
   249                 for (Iterator locIter = locationsInTree.iterator();
   250                      locIter.hasNext(); ) {
   251                     DirectoryTreeNode node =
   252                         (DirectoryTreeNode) locIter.next();
   253                     String tmpName = node.getName();
   254                     for (Iterator prefIter = preferredPaths.iterator();
   255                          prefIter.hasNext(); ) {
   256                         // We need to make sure the preferred path is
   257                         // found from the file path not including the root node name.
   258                         if (tmpName.indexOf((String)prefIter.next(),
   259                                             rootNameLength) != -1) {
   260                             name = tmpName;
   261                             break search;
   262                         }
   263                     }
   264                 }
   265             }
   267             if (name == null) {
   268                 filesDuplicate.add(fileName);
   269             }
   270         } else {
   271             name = ((DirectoryTreeNode) locationsInTree.get(0)).getName();
   272         }
   274         return name;
   275     }
   277     protected String envVarPrefixedFileName(String fileName,
   278                                             int sourceBaseLen,
   279                                             DirectoryTree tree,
   280                                             Vector preferredPaths,
   281                                             Vector filesNotFound,
   282                                             Vector filesDuplicate) {
   283         String fullName = findFileInDirectory(fileName,
   284                                               tree,
   285                                               preferredPaths,
   286                                               filesNotFound,
   287                                               filesDuplicate);
   288         return fullName;
   289     }
   291      String getProjectName(String fullPath, String extension)
   292         throws IllegalArgumentException, IOException {
   293         File file = new File(fullPath).getCanonicalFile();
   294         fullPath = file.getCanonicalPath();
   295         String parent = file.getParent();
   297         if (!fullPath.endsWith(extension)) {
   298             throw new IllegalArgumentException("project file name \"" +
   299                                                fullPath +
   300                                                "\" does not end in "+extension);
   301         }
   303         if ((parent != null) &&
   304             (!fullPath.startsWith(parent))) {
   305             throw new RuntimeException(
   306                 "Internal error: parent of file name \"" + parent +
   307                 "\" does not match file name \"" + fullPath + "\""
   308             );
   309         }
   311         int len = parent.length();
   312         if (!parent.endsWith(Util.sep)) {
   313             len += Util.sep.length();
   314         }
   316         int end = fullPath.length() - extension.length();
   318         if (len == end) {
   319             throw new RuntimeException(
   320                 "Internal error: file name was empty"
   321             );
   322         }
   324         return fullPath.substring(len, end);
   325     }
   327     protected abstract String getProjectExt();
   329     public void createVcproj(String[] args)
   330         throws IllegalArgumentException, IOException {
   332         parseArguments(args);
   334         String projectFileName = BuildConfig.getFieldString(null, "ProjectFileName");
   335         String ext = getProjectExt();
   337         String projectName = getProjectName(projectFileName, ext);
   339         writeProjectFile(projectFileName, projectName, createAllConfigs());
   340     }
   342     protected void writePrologue(String[] args) {
   343         System.err.println("WinGammaPlatform platform-specific arguments:");
   344         for (int i = 0; i < args.length; i++) {
   345             System.err.print(args[i] + " ");
   346         }
   347         System.err.println();
   348     }
   351     void parseArguments(String[] args) {
   352         new ArgsParser(args,
   353                        new ArgRule[]
   354             {
   355                 new ArgRule("-sourceBase",
   356                             new HsArgHandler() {
   357                                 public void handle(ArgIterator it) {
   358                                    String cfg = getCfg(it.get());
   359                                    if (nextNotKey(it)) {
   360                                       String sb = (String) it.get();
   361                                       if (sb.endsWith(Util.sep)) {
   362                                          sb = sb.substring(0, sb.length() - 1);
   363                                       }
   364                                       BuildConfig.putField(cfg, "SourceBase", sb);
   365                                       it.next();
   366                                    } else {
   367                                       empty("-sourceBase", null);
   368                                    }
   369                                 }
   370                             }
   371                             ),
   373                 new HsArgRule("-buildBase",
   374                               "BuildBase",
   375                               "   (Did you set the HotSpotBuildSpace environment variable?)",
   376                               HsArgHandler.STRING
   377                               ),
   379                 new HsArgRule("-projectFileName",
   380                               "ProjectFileName",
   381                               null,
   382                               HsArgHandler.STRING
   383                               ),
   385                 new HsArgRule("-jdkTargetRoot",
   386                               "JdkTargetRoot",
   387                               "   (Did you set the HotSpotJDKDist environment variable?)",
   388                               HsArgHandler.STRING
   389                               ),
   391                 new HsArgRule("-compiler",
   392                               "CompilerVersion",
   393                               "   (Did you set the VcVersion correctly?)",
   394                               HsArgHandler.STRING
   395                               ),
   397                 new HsArgRule("-platform",
   398                               "Platform",
   399                               null,
   400                               HsArgHandler.STRING
   401                               ),
   403                 new HsArgRule("-absoluteInclude",
   404                               "AbsoluteInclude",
   405                               null,
   406                               HsArgHandler.VECTOR
   407                               ),
   409                 new HsArgRule("-relativeInclude",
   410                               "RelativeInclude",
   411                               null,
   412                               HsArgHandler.VECTOR
   413                               ),
   415                 new HsArgRule("-define",
   416                               "Define",
   417                               null,
   418                               HsArgHandler.VECTOR
   419                               ),
   421                 new HsArgRule("-useToGeneratePch",
   422                               "UseToGeneratePch",
   423                               null,
   424                               HsArgHandler.STRING
   425                               ),
   427                 new ArgRuleSpecific("-perFileLine",
   428                             new HsArgHandler() {
   429                                 public void handle(ArgIterator it) {
   430                                     String cfg = getCfg(it.get());
   431                                     if (nextNotKey(it)) {
   432                                         String fileName = it.get();
   433                                         if (nextNotKey(it)) {
   434                                             String line = it.get();
   435                                             BuildConfig.putFieldHash(cfg, "PerFileLine", fileName, line);
   436                                             it.next();
   437                                             return;
   438                                         }
   439                                     }
   440                                     empty(null, "** Error: wrong number of args to -perFileLine");
   441                                 }
   442                             }
   443                             ),
   445                 new ArgRuleSpecific("-conditionalPerFileLine",
   446                             new HsArgHandler() {
   447                                 public void handle(ArgIterator it) {
   448                                     String cfg = getCfg(it.get());
   449                                     if (nextNotKey(it)) {
   450                                         String fileName = it.get();
   451                                         if (nextNotKey(it)) {
   452                                             String productLine = it.get();
   453                                             if (nextNotKey(it)) {
   454                                                 String debugLine = it.get();
   455                                                 BuildConfig.putFieldHash(cfg+"_debug", "CondPerFileLine",
   456                                                                          fileName, debugLine);
   457                                                 BuildConfig.putFieldHash(cfg+"_product", "CondPerFileLine",
   458                                                                          fileName, productLine);
   459                                                 it.next();
   460                                                 return;
   461                                             }
   462                                         }
   463                                     }
   465                                     empty(null, "** Error: wrong number of args to -conditionalPerFileLine");
   466                                 }
   467                             }
   468                             ),
   470                 new HsArgRule("-disablePch",
   471                               "DisablePch",
   472                               null,
   473                               HsArgHandler.HASH
   474                               ),
   476                 new ArgRule("-startAt",
   477                             new HsArgHandler() {
   478                                 public void handle(ArgIterator it) {
   479                                     if (BuildConfig.getField(null, "StartAt") != null) {
   480                                         empty(null, "** Error: multiple -startAt");
   481                                     }
   482                                     if (nextNotKey(it)) {
   483                                         BuildConfig.putField(null, "StartAt", it.get());
   484                                         it.next();
   485                                     } else {
   486                                         empty("-startAt", null);
   487                                     }
   488                                 }
   489                             }
   490                             ),
   492                 new HsArgRule("-ignoreFile",
   493                                       "IgnoreFile",
   494                                       null,
   495                                       HsArgHandler.HASH
   496                                       ),
   498                 new HsArgRule("-ignorePath",
   499                               "IgnorePath",
   500                               null,
   501                               HsArgHandler.VECTOR
   502                               ),
   504                 new HsArgRule("-additionalFile",
   505                               "AdditionalFile",
   506                               null,
   507                               HsArgHandler.VECTOR
   508                               ),
   510                 new ArgRuleSpecific("-additionalGeneratedFile",
   511                             new HsArgHandler() {
   512                                 public void handle(ArgIterator it) {
   513                                     String cfg = getCfg(it.get());
   514                                     if (nextNotKey(it)) {
   515                                         String dir = it.get();
   516                                         if (nextNotKey(it)) {
   517                                             String fileName = it.get();
   518                                             BuildConfig.putFieldHash(cfg, "AdditionalGeneratedFile",
   519                                                                      Util.normalize(dir + Util.sep + fileName),
   520                                                                      fileName);
   521                                             it.next();
   522                                             return;
   523                                         }
   524                                     }
   525                                     empty(null, "** Error: wrong number of args to -additionalGeneratedFile");
   526                                 }
   527                             }
   528                             ),
   530                 new ArgRule("-prelink",
   531                             new HsArgHandler() {
   532                                 public void handle(ArgIterator it) {
   533                                     if (nextNotKey(it)) {
   534                                         if (nextNotKey(it)) {
   535                                             String description = it.get();
   536                                             if (nextNotKey(it)) {
   537                                                 String command = it.get();
   538                                                 BuildConfig.putField(null, "PrelinkDescription", description);
   539                                                 BuildConfig.putField(null, "PrelinkCommand", command);
   540                                                 it.next();
   541                                                 return;
   542                                             }
   543                                         }
   544                                     }
   546                                     empty(null,  "** Error: wrong number of args to -prelink");
   547                                 }
   548                             }
   549                             ),
   551                 new ArgRule("-postbuild",
   552                             new HsArgHandler() {
   553                                 public void handle(ArgIterator it) {
   554                                     if (nextNotKey(it)) {
   555                                         if (nextNotKey(it)) {
   556                                             String description = it.get();
   557                                             if (nextNotKey(it)) {
   558                                                 String command = it.get();
   559                                                 BuildConfig.putField(null, "PostbuildDescription", description);
   560                                                 BuildConfig.putField(null, "PostbuildCommand", command);
   561                                                 it.next();
   562                                                 return;
   563                                             }
   564                                         }
   565                                     }
   567                                     empty(null,  "** Error: wrong number of args to -postbuild");
   568                                 }
   569                             }
   570                             ),
   571             },
   572                                        new ArgHandler() {
   573                                            public void handle(ArgIterator it) {
   575                                                throw new RuntimeException("Arg Parser: unrecognized option "+it.get());
   576                                            }
   577                                        }
   578                                        );
   579         if (BuildConfig.getField(null, "SourceBase") == null      ||
   580             BuildConfig.getField(null, "BuildBase") == null       ||
   581             BuildConfig.getField(null, "ProjectFileName") == null ||
   582             BuildConfig.getField(null, "CompilerVersion") == null) {
   583             usage();
   584         }
   586         if (BuildConfig.getField(null, "UseToGeneratePch") == null) {
   587             throw new RuntimeException("ERROR: need to specify one file to compute PCH, with -useToGeneratePch flag");
   588         }
   590         BuildConfig.putField(null, "PlatformObject", this);
   591     }
   593     Vector createAllConfigs() {
   594         Vector allConfigs = new Vector();
   596         allConfigs.add(new C1DebugConfig());
   598         boolean b = true;
   599         if (b) {
   600             allConfigs.add(new C1FastDebugConfig());
   601             allConfigs.add(new C1ProductConfig());
   603             allConfigs.add(new C2DebugConfig());
   604             allConfigs.add(new C2FastDebugConfig());
   605             allConfigs.add(new C2ProductConfig());
   607             allConfigs.add(new TieredDebugConfig());
   608             allConfigs.add(new TieredFastDebugConfig());
   609             allConfigs.add(new TieredProductConfig());
   611             allConfigs.add(new CoreDebugConfig());
   612             allConfigs.add(new CoreFastDebugConfig());
   613             allConfigs.add(new CoreProductConfig());
   615             allConfigs.add(new KernelDebugConfig());
   616             allConfigs.add(new KernelFastDebugConfig());
   617             allConfigs.add(new KernelProductConfig());
   618         }
   620         return allConfigs;
   621     }
   623     class FileAttribute {
   624         int     numConfigs;
   625         Vector  configs;
   626         String  shortName;
   627         boolean noPch, pchRoot;
   629         FileAttribute(String shortName, BuildConfig cfg, int numConfigs) {
   630             this.shortName = shortName;
   631             this.noPch =  (cfg.lookupHashFieldInContext("DisablePch", shortName) != null);
   632             this.pchRoot = shortName.equals(BuildConfig.getFieldString(null, "UseToGeneratePch"));
   633             this.numConfigs = numConfigs;
   635             configs = new Vector();
   636             add(cfg.get("Name"));
   637         }
   639         void add(String confName) {
   640             configs.add(confName);
   642             // if presented in all configs
   643             if (configs.size() == numConfigs) {
   644                 configs = null;
   645             }
   646         }
   647     }
   649     class FileInfo implements Comparable {
   650         String        full;
   651         FileAttribute attr;
   653         FileInfo(String full, FileAttribute  attr) {
   654             this.full = full;
   655             this.attr = attr;
   656         }
   658         public int compareTo(Object o) {
   659             FileInfo oo = (FileInfo)o;
   660             return full.compareTo(oo.full);
   661         }
   663         boolean isHeader() {
   664             return attr.shortName.endsWith(".h") || attr.shortName.endsWith(".hpp");
   665         }
   666     }
   669     TreeSet sortFiles(Hashtable allFiles) {
   670         TreeSet rv = new TreeSet();
   671         Enumeration e = allFiles.keys();
   672         while (e.hasMoreElements()) {
   673             String fullPath = (String)e.nextElement();
   674             rv.add(new FileInfo(fullPath, (FileAttribute)allFiles.get(fullPath)));
   675         }
   676         return rv;
   677     }
   679     Hashtable computeAttributedFiles(Vector allConfigs) {
   680         Hashtable ht = new Hashtable();
   681         int numConfigs = allConfigs.size();
   683         for (Iterator i = allConfigs.iterator(); i.hasNext(); ) {
   684             BuildConfig bc = (BuildConfig)i.next();
   685             Hashtable  confFiles = (Hashtable)bc.getSpecificField("AllFilesHash");
   686             String confName = bc.get("Name");
   688             for (Enumeration e=confFiles.keys(); e.hasMoreElements(); ) {
   689                 String filePath = (String)e.nextElement();
   690                 FileAttribute fa = (FileAttribute)ht.get(filePath);
   692                 if (fa == null) {
   693                     fa = new FileAttribute((String)confFiles.get(filePath), bc, numConfigs);
   694                     ht.put(filePath, fa);
   695                 } else {
   696                     fa.add(confName);
   697                 }
   698             }
   699         }
   701         return ht;
   702     }
   704      Hashtable computeAttributedFiles(BuildConfig bc) {
   705         Hashtable ht = new Hashtable();
   706         Hashtable confFiles = (Hashtable)bc.getSpecificField("AllFilesHash");
   708         for (Enumeration e = confFiles.keys(); e.hasMoreElements(); ) {
   709             String filePath = (String)e.nextElement();
   710             ht.put(filePath,  new FileAttribute((String)confFiles.get(filePath), bc, 1));
   711         }
   713         return ht;
   714     }
   716     PrintWriter printWriter;
   718     public void writeProjectFile(String projectFileName, String projectName,
   719                                  Vector allConfigs) throws IOException {
   720         throw new RuntimeException("use compiler version specific version");
   721     }
   722 }

mercurial