001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.cnd.makewizard;
043:
044: import java.util.ArrayList;
045: import org.netbeans.modules.cnd.loaders.AsmDataLoader;
046: import org.netbeans.modules.cnd.loaders.CCDataLoader;
047: import org.netbeans.modules.cnd.loaders.CDataLoader;
048: import org.netbeans.modules.cnd.loaders.FortranDataLoader;
049: import org.netbeans.modules.cnd.loaders.HDataLoader;
050:
051: /**
052: * A TargetData record. This class should contain ALL iformation necessary to
053: * create a specific Makefile target.
054: */
055:
056: final public class TargetData {
057:
058: /** Which type of target this is */
059: private int targetType;
060:
061: /** The name of the target */
062: private String name;
063:
064: /** The directory for object files and other transients */
065: private String outputDirectory;
066:
067: /** The unique target key */
068: private int key;
069:
070: /** The list of source files for this target */
071: private String[] sourcesList;
072:
073: /** The list of include directories for this target */
074: private String[] includesList;
075:
076: /** What system libraries to link with */
077: private StdLibFlags stdLibFlags;
078:
079: /** The list of user libraries for this target */
080: private String[] userLibsList;
081:
082: /** The target called in a recursive make command */
083: private String targetName;
084:
085: /** The dependencies of the target in a recursive make command */
086: private String dependsOn;
087:
088: /** The subdirectory a recursive make command is run in */
089: private String subdirectory;
090:
091: /** The command line flags for a recursive make command */
092: private String makeFlags;
093:
094: /** The actions for a custom Makefile target */
095: private ArrayList actions;
096:
097: /** This target is compilable (if set ) */
098: private boolean compilable;
099:
100: /** This target has one of the complex targetTypes */
101: private boolean complex;
102:
103: /** This target contains C++ source files */
104: private boolean haveCppFiles;
105:
106: /** This target contains C source files */
107: private boolean haveCFiles;
108:
109: /** This target contains Fortran source files */
110: private boolean haveFortranFiles;
111:
112: /** This target contains X-Designer source files */
113: private boolean haveXdFiles;
114:
115: /** This target contains Assembly source files */
116: private boolean haveAssemblyFiles;
117:
118: /** Single target corresponds to EXECUTABLE_MAKEFILE_TYPE */
119: public final static int SIMPLE_EXECUTABLE = MakefileData.EXECUTABLE_MAKEFILE_TYPE;
120:
121: /** Single target corresponds to ARCHIVE_MAKEFILE_TYPE */
122: public final static int SIMPLE_ARCHIVE = MakefileData.ARCHIVE_MAKEFILE_TYPE;
123:
124: /** Single target corresponds to SHAREDLIB_MAKEFILE_TYPE */
125: public final static int SIMPLE_SHAREDLIB = MakefileData.SHAREDLIB_MAKEFILE_TYPE;
126:
127: /** Complex target for an executable */
128: public final static int COMPLEX_EXECUTABLE = MakefileData.COMPLEX_MAKEFILE_TYPE + 1;
129:
130: /** Complex target for an archive */
131: public final static int COMPLEX_ARCHIVE = MakefileData.COMPLEX_MAKEFILE_TYPE + 2;
132:
133: /** Complex target for a shared library */
134: public final static int COMPLEX_SHAREDLIB = MakefileData.COMPLEX_MAKEFILE_TYPE + 3;
135:
136: /** Complex target for calling a recursive make */
137: public final static int COMPLEX_MAKE_TARGET = MakefileData.COMPLEX_MAKEFILE_TYPE + 4;
138:
139: /** Custom target */
140: public final static int COMPLEX_CUSTOM_TARGET = MakefileData.COMPLEX_MAKEFILE_TYPE + 5;
141:
142: /** Create a target data record of a single target */
143: public TargetData(int targetType, String name,
144: String outputDirectory, int key) {
145:
146: this .targetType = targetType;
147: this .name = name;
148: this .outputDirectory = outputDirectory;
149: this .key = key;
150: sourcesList = null;
151: includesList = null;
152: stdLibFlags = new StdLibFlags();
153: userLibsList = null;
154: targetName = null;
155: dependsOn = null;
156: subdirectory = null;
157: makeFlags = null;
158: actions = null;
159: compilable = false;
160: haveCppFiles = false;
161: haveCFiles = false;
162: haveFortranFiles = false;
163: haveXdFiles = false;
164: haveAssemblyFiles = false;
165:
166: if (targetType == COMPLEX_MAKE_TARGET
167: || targetType == COMPLEX_CUSTOM_TARGET) {
168: compilable = false;
169: } else {
170: compilable = true;
171: }
172:
173: if (targetType == SIMPLE_EXECUTABLE
174: || targetType == SIMPLE_ARCHIVE
175: || targetType == SIMPLE_SHAREDLIB) {
176: complex = false;
177: } else {
178: complex = true;
179: }
180: }
181:
182: /** Create a target data record from another target */
183: public TargetData(TargetData old) {
184: int i;
185:
186: targetType = old.targetType;
187: name = new String(old.name);
188: outputDirectory = new String(old.outputDirectory);
189: key = old.key;
190: sourcesList = null;
191: targetName = old.targetName;
192: dependsOn = old.dependsOn;
193: subdirectory = old.subdirectory;
194: makeFlags = old.makeFlags;
195: actions = old.actions;
196: compilable = old.compilable;
197: complex = old.complex;
198: haveCppFiles = false;
199: haveCFiles = false;
200: haveFortranFiles = false;
201: haveXdFiles = false;
202: haveAssemblyFiles = false;
203:
204: if (includesList != null) {
205: includesList = new String[old.includesList.length];
206: for (i = 0; i < includesList.length; i++) {
207: includesList[i] = old.includesList[i];
208: }
209: }
210: if (stdLibFlags != null) {
211: stdLibFlags = new StdLibFlags(old.stdLibFlags);
212: }
213: if (userLibsList != null) {
214: userLibsList = new String[old.userLibsList.length];
215: for (i = 0; i < userLibsList.length; i++) {
216: userLibsList[i] = old.userLibsList[i];
217: }
218: }
219: }
220:
221: /** Get the target type */
222: public int getTargetType() {
223: return targetType;
224: }
225:
226: /** Getter for target name */
227: public String getName() {
228: return name;
229: }
230:
231: /** Setter for target name */
232: public void setName(String name) {
233: this .name = name;
234: }
235:
236: /** Getter for target key */
237: public int getKey() {
238: return key;
239: }
240:
241: /** Getter for the source list */
242: public String[] getSourcesList() {
243: return sourcesList;
244: }
245:
246: /** Set the source list */
247: public void setSourcesList(String[] sourcesList) {
248: this .sourcesList = sourcesList;
249:
250: haveCppFiles = false;
251: haveCFiles = false;
252: haveFortranFiles = false;
253: haveXdFiles = false;
254: haveAssemblyFiles = false;
255: for (int i = 0; sourcesList != null && i < sourcesList.length; i++) {
256: if (!haveCppFiles && isCppFile(sourcesList[i])) {
257: haveCppFiles = true;
258: }
259: if (!haveCFiles && isCFile(sourcesList[i])) {
260: haveCFiles = true;
261: }
262: if (!haveFortranFiles && isFortranFile(sourcesList[i])) {
263: haveFortranFiles = true;
264: }
265: if (!haveXdFiles && isXdFile(sourcesList[i])) {
266: haveXdFiles = true;
267: }
268: if (!haveAssemblyFiles && isAssemblyFile(sourcesList[i])) {
269: haveAssemblyFiles = true;
270: }
271: }
272: }
273:
274: /** Let users know if this target has sufficient data */
275: public boolean isComplete() {
276:
277: if (targetType == COMPLEX_MAKE_TARGET
278: && (targetName != null || dependsOn != null
279: || subdirectory != null || makeFlags != null)) {
280: return true;
281: } else if (targetType == COMPLEX_CUSTOM_TARGET
282: && actions != null && actions.size() > 0) {
283: return true;
284: } else {
285: return sourcesList != null && sourcesList.length > 0;
286: }
287: }
288:
289: /** Getter for the includes list */
290: public String[] getIncludesList() {
291: return includesList;
292: }
293:
294: /** Set the includes list */
295: public void setIncludesList(String[] includesList) {
296: this .includesList = includesList;
297: }
298:
299: /** Getter for the user libraries list */
300: public String[] getUserLibsList() {
301: return userLibsList;
302: }
303:
304: /** Set the user libraries list */
305: public void setUserLibsList(String[] userLibsList) {
306: this .userLibsList = userLibsList;
307: }
308:
309: /** Getter for outputDirectory */
310: public String getOutputDirectory() {
311: return outputDirectory;
312: }
313:
314: /** Setter for outputDirectory */
315: public void setOutputDirectory(String outputDirectory) {
316: String cwd = MakefileWizard.getMakefileWizard()
317: .getMakefileData().getBaseDirectory();
318:
319: if (outputDirectory.startsWith(cwd)
320: && outputDirectory.length() > cwd.length()) {
321: this .outputDirectory = outputDirectory.substring(cwd
322: .length() + 1);
323: } else {
324: this .outputDirectory = outputDirectory;
325: }
326: }
327:
328: /** Getter for StdLibFlags */
329: public StdLibFlags getStdLibFlags() {
330: return stdLibFlags;
331: }
332:
333: /** Getter for targetName */
334: public String getTargetName() {
335: return targetName;
336: }
337:
338: /** Setter for targetName */
339: public void setTargetName(String targetName) {
340: this .targetName = targetName;
341: }
342:
343: /** Getter for dependsOn */
344: public String getDependsOn() {
345: return dependsOn;
346: }
347:
348: /** Setter for dependsOn */
349: public void setDependsOn(String dependsOn) {
350: this .dependsOn = dependsOn;
351: }
352:
353: /** Getter for subdirectory */
354: public String getSubdirectory() {
355: return subdirectory;
356: }
357:
358: /** Setter for subdirectory */
359: public void setSubdirectory(String subdirectory) {
360: this .subdirectory = subdirectory;
361: }
362:
363: /** Getter for makeFlags */
364: public String getMakeFlags() {
365: return makeFlags;
366: }
367:
368: /** Setter for makeFlags */
369: public void setMakeFlags(String makeFlags) {
370: this .makeFlags = makeFlags;
371: }
372:
373: /** Getter for action */
374: public ArrayList getActions() {
375: if (actions == null) {
376: actions = new ArrayList();
377: }
378: return actions;
379: }
380:
381: /** Setter for actions */
382: public void setActions(ArrayList actions) {
383: this .actions = actions;
384: }
385:
386: /**
387: * Let the caller know if the target can be converted to the requested type.
388: */
389: public boolean isConvertable(int newType) {
390: return (targetType == SIMPLE_EXECUTABLE && newType == COMPLEX_EXECUTABLE)
391: || (targetType == SIMPLE_ARCHIVE && newType == COMPLEX_ARCHIVE)
392: || (targetType == SIMPLE_SHAREDLIB && newType == COMPLEX_SHAREDLIB)
393: || (targetType == COMPLEX_EXECUTABLE && newType == SIMPLE_EXECUTABLE)
394: || (targetType == COMPLEX_ARCHIVE && newType == SIMPLE_ARCHIVE)
395: || (targetType == COMPLEX_SHAREDLIB && newType == SIMPLE_SHAREDLIB);
396: }
397:
398: /** Convert the SIMPLE_* target to the associated COMPLEX_* type */
399: public void convert() {
400: CompilerFlags copts = MakefileWizard.getMakefileWizard()
401: .getMakefileData().getCompilerFlags();
402:
403: switch (targetType) {
404: case SIMPLE_EXECUTABLE:
405: targetType = COMPLEX_EXECUTABLE;
406: break;
407:
408: case SIMPLE_ARCHIVE:
409: targetType = COMPLEX_ARCHIVE;
410: break;
411:
412: case SIMPLE_SHAREDLIB:
413: targetType = COMPLEX_SHAREDLIB;
414: break;
415: }
416:
417: // Now set the compiler flags
418: if (copts.isSimpleDebug()) {
419: copts.setOptionSource(OptionSource.DEVELOPMENT);
420: copts.setDevelDebug(true);
421: } else if (copts.isSimpleOptimize()) {
422: copts.setOptionSource(OptionSource.FINAL);
423: copts.setFinalOptimize(true);
424: }
425:
426: // Leave the rest of the informatino as-is. If we convert back its
427: // not lost.
428:
429: /*
430: if (UsageTracking.enabled) {
431: UsageTracking.sendAction("Convert MFW Target", null); // NOI18N
432: }
433: */
434: }
435:
436: /** Convert the COMPLEX_* target to the associated SIMPLE_* type */
437: public void convert(int newType) {
438: CompilerFlags copts = MakefileWizard.getMakefileWizard()
439: .getMakefileData().getCompilerFlags();
440:
441: targetType = newType;
442:
443: // Now set the compiler flags
444: if (copts.getOptionSource() == OptionSource.FINAL) {
445: copts.setSimpleOptimize(copts.isFinalOptimize());
446: } else {
447: copts.setSimpleDebug(true);
448: copts.setSimpleOptimize(!copts.isDevelDebug());
449: }
450:
451: // Leave the rest of the informatino as-is. If we convert back its
452: // not lost.
453:
454: /*
455: if (UsageTracking.enabled) {
456: UsageTracking.sendAction("Convert MFW Target", null); // NOI18N
457: }
458: */
459: }
460:
461: /** Helper function for checking if target is executable */
462: public boolean isExecutable() {
463: return targetType == SIMPLE_EXECUTABLE
464: || targetType == COMPLEX_EXECUTABLE;
465: }
466:
467: /** Helper function for checking if target is an archive */
468: public boolean isArchive() {
469: return targetType == SIMPLE_ARCHIVE
470: || targetType == COMPLEX_ARCHIVE;
471: }
472:
473: /** Helper function for checking if target is a shared library */
474: public boolean isSharedLib() {
475: return targetType == SIMPLE_SHAREDLIB
476: || targetType == COMPLEX_SHAREDLIB;
477: }
478:
479: /** Helper function for checking if target is a recursive make target */
480: public boolean isMakeTarget() {
481: return targetType == COMPLEX_MAKE_TARGET;
482: }
483:
484: /** Helper function for checking if target is a custom make target */
485: public boolean isCustomTarget() {
486: return targetType == COMPLEX_CUSTOM_TARGET;
487: }
488:
489: /** Check if a file is a C++ file */
490: public boolean isCppFile(String file) {
491: return CCDataLoader.getInstance().getExtensions().isRegistered(
492: file);
493: }
494:
495: /** Check if a file is a C file */
496: public boolean isCFile(String file) {
497: return CDataLoader.getInstance().getExtensions().isRegistered(
498: file);
499: }
500:
501: /** Check if a file is a C/C++ header file */
502: public boolean isHdrFile(String file) {
503: return HDataLoader.getInstance().getExtensions().isRegistered(
504: file);
505: }
506:
507: /** Check if a file is a Fortran file */
508: public boolean isFortranFile(String file) {
509: return FortranDataLoader.getInstance().getExtensions()
510: .isRegistered(file);
511: }
512:
513: /** Check if a file is a X-Designer file */
514: public boolean isXdFile(String file) {
515: return file.endsWith(".xd"); // NOI18N
516: }
517:
518: /** Check if a file is a Assembly file */
519: public boolean isAssemblyFile(String file) {
520: return AsmDataLoader.getInstance().getExtensions()
521: .isRegistered(file);
522: }
523:
524: /** Is this a simple or complex type? */
525: public boolean isComplex() {
526: return complex;
527: }
528:
529: /** Does the target get linked? */
530: public boolean isLinked() {
531:
532: return targetType == SIMPLE_EXECUTABLE
533: || targetType == COMPLEX_EXECUTABLE
534: || targetType == SIMPLE_SHAREDLIB
535: || targetType == COMPLEX_SHAREDLIB;
536: }
537:
538: /** True if this target is a type which contains compilable files */
539: public boolean isCompilable() {
540: return compilable;
541: }
542:
543: /** Let caller know if this project contains C++ source files */
544: public boolean containsCppFiles() {
545: return haveCppFiles;
546: }
547:
548: /** Let caller know if this project contains C source files */
549: public boolean containsCFiles() {
550: return haveCFiles;
551: }
552:
553: /** Let caller know if this project contains Fortran source files */
554: public boolean containsFortranFiles() {
555: return haveFortranFiles;
556: }
557:
558: /** Let caller know if this project contains X-Designer source files */
559: public boolean containsXdFiles() {
560: return haveXdFiles;
561: }
562:
563: /** Let caller know if this project contains Assembly files */
564: public boolean containsAssemblyFiles() {
565: return haveAssemblyFiles;
566: }
567:
568: private String indent = new String(""); // NOI18N
569:
570: /** Default dump has no indent */
571: public void dump() {
572: int i;
573:
574: //println("Dumping target[" + key + "]:"); // NOI18N
575: println(" name = \"" + name + "\""); // NOI18N
576: println(" type = " + (String) // NOI18N
577: (targetType == SIMPLE_EXECUTABLE ? "SIMPLE_EXECUTABLE" : // NOI18N
578: targetType == SIMPLE_ARCHIVE ? "SIMPLE_ARCHIVE"
579: : // NOI18N
580: targetType == SIMPLE_SHAREDLIB ? "SIMPLE_SHAREDLIB"
581: : // NOI18N
582: targetType == COMPLEX_EXECUTABLE ? "COMPLEX_EXECUTABLE"
583: : // NOI18N
584: targetType == COMPLEX_ARCHIVE ? "COMPLEX_ARCHIVE"
585: : // NOI18N
586: targetType == COMPLEX_SHAREDLIB ? "COMPLEX_SHAREDLIB"
587: : // NOI18N
588: targetType == COMPLEX_MAKE_TARGET ? "COMPLEX_MAKE_TARGET"
589: : // NOI18N
590: targetType == COMPLEX_CUSTOM_TARGET ? "COMPLEX_CUSTOM_TARGET"
591: : "Unknown")); // NOI18N
592:
593: println(" key = " + key); // NOI18N
594: println(" outputDirectory = \"" + outputDirectory + "\""); // NOI18N
595: if (sourcesList == null || sourcesList.length == 0) {
596: println(" sourcesList = {}"); // NOI18N
597: } else {
598: println(" sourcesList = {"); // NOI18N
599: for (i = 0; i < sourcesList.length; i++) {
600: println(" \"" + sourcesList[i] + "\""); // NOI18N
601: }
602: println(" }"); // NOI18N
603: }
604: if (includesList == null || includesList.length == 0) {
605: println(" includesList = {}"); // NOI18N
606: } else {
607: println(" includesList = {"); // NOI18N
608: for (i = 0; i < includesList.length; i++) {
609: println(" \"" + includesList[i] + "\""); // NOI18N
610: }
611: println(" }"); // NOI18N
612: }
613: stdLibFlags.dump();
614: if (userLibsList == null || userLibsList.length == 0) {
615: println(" userLibsList = {}"); // NOI18N
616: } else {
617: println(" userLibsList = {"); // NOI18N
618: for (i = 0; i < userLibsList.length; i++) {
619: println(" \"" + userLibsList[i] + "\""); // NOI18N
620: }
621: println(" }"); // NOI18N
622: }
623: println(" targetName = \"" + targetName + "\""); // NOI18N
624: println(" dependsOn = \"" + dependsOn + "\""); // NOI18N
625: println(" subdirectory = \"" + subdirectory + "\""); // NOI18N
626: println(" makeFlags = \"" + makeFlags + "\""); // NOI18N
627: if (actions == null || actions.size() == 0) {
628: println(" actions = {}"); // NOI18N
629: } else {
630: println(" actions = {"); // NOI18N
631: for (i = 0; i < actions.size(); i++) {
632: println(" " + actions.get(i).toString()); // NOI18N
633: }
634: println(" }"); // NOI18N
635: }
636:
637: }
638:
639: /**
640: * Allow caller to indent all data. This is usefull for indenting target
641: * dumps within MakefileData dumps.
642: */
643: public void dump(String in) {
644:
645: setIndent(in);
646: dump();
647: }
648:
649: private void println(String s) {
650: System.out.println(indent + s);
651: }
652:
653: private void setIndent(String indent) {
654: this.indent = indent;
655: }
656: }
|