001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: /*
020: * build notes
021: * -The reference CD to listen to while editing this file is
022: * nap: Underworld - Everything, Everything
023: */
024: // ====================================================================
025: // place in the optional ant tasks package
026: // but in its own dotnet group
027: // ====================================================================
028: package org.apache.tools.ant.taskdefs.optional.dotnet;
029:
030: // ====================================================================
031: // imports
032: // ====================================================================
033:
034: import java.io.File;
035:
036: // ====================================================================
037:
038: /**
039: * Compiles C# source into executables or modules.
040: *
041: * csc.exe on Windows or mcs on other platforms must be on the execute
042: * path, unless another executable or the full path to that executable
043: * is specified in the <tt>executable</tt> parameter
044: * <p>
045: * All parameters are optional: <csc/> should suffice to produce a debug
046: * build of all *.cs files. However, naming an <tt>destFile</tt>stops the
047: * csc compiler from choosing an output name from random, and
048: * allows the dependency checker to determine if the file is out of date.
049: * <p>
050: * The task is a directory based task, so attributes like <b>includes="*.cs"
051: * </b> and <b>excludes="broken.cs"</b> can be used to control the files pulled
052: * in. By default, all *.cs files from the project folder down are included in
053: * the command. When this happens the output file -if not specified- is taken
054: * as the first file in the list, which may be somewhat hard to control.
055: * Specifying the output file with <tt>destFile</tt> seems prudent. <p>
056: *
057: * <p>
058: * For more complex source trees, nested <tt>src</tt> elemements can be
059: * supplied. When such an element is present, the implicit fileset is ignored.
060: * This makes sense, when you think about it :)
061: *
062: * <p>For historical reasons the pattern
063: * <code>**</code><code>/*.cs</code> is preset as includes list and
064: * you can not override it with an explicit includes attribute. Use
065: * nested <code><src></code> elements instead of the basedir
066: * attribute if you need more control.</p>
067: *
068: * <p>
069: * References to external files can be made through the references attribute,
070: * or (since Ant1.6), via nested <reference> filesets. With the latter,
071: * the timestamps of the references are also used in the dependency
072: * checking algorithm.
073: * <p>
074: *
075: * Example
076: *
077: * <pre><csc
078: * optimize="true"
079: * debug="false"
080: * docFile="documentation.xml"
081: * warnLevel="4"
082: * unsafe="false"
083: * targetType="exe"
084: * incremental="false"
085: * mainClass = "MainApp"
086: * destFile="NetApp.exe"
087: * >
088: * <src dir="src" includes="*.cs" />
089: * <reference file="${testCSC.dll}" />
090: * <define name="RELEASE" />
091: * <define name="DEBUG" if="debug.property"/>
092: * <define name="def3" unless="def3.property"/>
093: * </csc>
094: * </pre>
095: *
096: *
097: * @ant.task name="csc" category="dotnet"
098: * @since Ant 1.3
099: */
100:
101: public class CSharp extends DotnetCompile {
102:
103: // CheckStyle:VisibilityModifier OFF - bc
104: /**
105: * defines list: RELEASE;WIN32;NO_SANITY_CHECKS;;SOMETHING_ELSE'
106: */
107: String definitions;
108:
109: /**
110: * output XML documentation flag
111: */
112: private File docFile;
113:
114: /**
115: * file alignment; 0 means let the compiler decide
116: */
117: private int fileAlign = 0;
118:
119: /**
120: * use full paths to things
121: */
122: private boolean fullpaths = false;
123:
124: /**
125: * incremental build flag
126: */
127: private boolean incremental;
128:
129: /**
130: * enable unsafe code flag. Clearly set to false by default
131: */
132: protected boolean unsafe;
133:
134: /**
135: * A flag that tells the compiler not to read in the compiler
136: * settings files 'csc.rsp' in its bin directory and then the local directory
137: */
138: private boolean noconfig = false;
139:
140: // CheckStyle:VisibilityModifier ON
141:
142: /**
143: * constructor inits everything and set up the search pattern
144: */
145:
146: public CSharp() {
147: clear();
148: }
149:
150: /**
151: * full cleanup
152: */
153: public void clear() {
154: super .clear();
155: docFile = null;
156: fileAlign = 0;
157: fullpaths = true;
158: incremental = false;
159: unsafe = false;
160: noconfig = false;
161: definitions = null;
162: setExecutable(isWindows ? "csc" : "mcs");
163: }
164:
165: /**
166: * file for generated XML documentation
167: *
168: *@param f output file
169: */
170: public void setDocFile(File f) {
171: docFile = f;
172: }
173:
174: /**
175: * get the argument or null for no argument needed
176: *
177: *@return The DocFile Parameter to CSC
178: */
179: protected String getDocFileParameter() {
180: if (docFile != null) {
181: return "/doc:" + docFile.toString();
182: } else {
183: return null;
184: }
185: }
186:
187: /**
188: * Set the file alignment.
189: * Valid values are 0,512, 1024, 2048, 4096, 8192,
190: * and 16384, 0 means 'leave to the compiler'
191: * @param fileAlign the value to use.
192: */
193: public void setFileAlign(int fileAlign) {
194: this .fileAlign = fileAlign;
195: }
196:
197: /**
198: * get the argument or null for no argument needed
199: *
200: *@return The OutputFile Parameter to CSC
201: */
202: protected String getFileAlignParameter() {
203: if (fileAlign != 0 && !"mcs".equals(getExecutable())) {
204: return "/filealign:" + fileAlign;
205: } else {
206: return null;
207: }
208: }
209:
210: /**
211: * If true, print the full path of files on errors.
212: *
213: *@param enabled The new fullPaths value
214: */
215: public void setFullPaths(boolean enabled) {
216: fullpaths = enabled;
217: }
218:
219: /**
220: * Gets the fullPathsParameter attribute of the CSharp object
221: *
222: *@return The fullPathsParameter value or null if unset
223: */
224: protected String getFullPathsParameter() {
225: return fullpaths ? "/fullpaths" : null;
226: }
227:
228: /**
229: * set the incremental compilation flag on or off.
230: *
231: *@param incremental on/off flag
232: */
233: public void setIncremental(boolean incremental) {
234: this .incremental = incremental;
235: }
236:
237: /**
238: * query the incrementalflag
239: *
240: *@return true if incremental compilation is turned on
241: */
242: public boolean getIncremental() {
243: return incremental;
244: }
245:
246: /**
247: * get the incremental build argument
248: *
249: *@return The Incremental Parameter to CSC
250: */
251: protected String getIncrementalParameter() {
252: return "/incremental" + (incremental ? "+" : "-");
253: }
254:
255: /**
256: * The output file. This is identical to the destFile attribute.
257: *
258: *@param params The new outputFile value
259: */
260: public void setOutputFile(File params) {
261: setDestFile(params);
262: }
263:
264: /**
265: * If true, enables the unsafe keyword.
266: *
267: *@param unsafe The new Unsafe value
268: */
269: public void setUnsafe(boolean unsafe) {
270: this .unsafe = unsafe;
271: }
272:
273: /**
274: * query the Unsafe attribute
275: *
276: *@return The Unsafe value
277: */
278: public boolean getUnsafe() {
279: return this .unsafe;
280: }
281:
282: /**
283: * get the argument or null for no argument needed
284: *
285: *@return The Unsafe Parameter to CSC
286: */
287: protected String getUnsafeParameter() {
288: return unsafe ? "/unsafe" : null;
289: }
290:
291: /**
292: * A flag that tells the compiler not to read in the compiler
293: * settings files 'csc.rsp' in its bin directory and then the local directory
294: *
295: *@param enabled The new noConfig value
296: */
297: public void setNoConfig(boolean enabled) {
298: noconfig = enabled;
299: }
300:
301: /**
302: * Gets the noConfigParameter attribute of the CSharp object
303: *
304: *@return The noConfigParameter value
305: */
306: protected String getNoConfigParameter() {
307: return noconfig ? "/noconfig" : null;
308: }
309:
310: /**
311: * Semicolon separated list of defined constants.
312: *
313: *@param params The new definitions value
314: */
315: public void setDefinitions(String params) {
316: definitions = params;
317: }
318:
319: /**
320: * override the superclasses version of this method (which we call)
321: * with a check for a definitions attribute, the contents of which
322: * are appended to the list.
323: *@return The Definitions Parameter to CSC
324: */
325: protected String getDefinitionsParameter() {
326: String predecessors = super .getDefinitionsParameter();
327: if (notEmpty(definitions)) {
328: if (predecessors == null) {
329: predecessors = "/define:";
330: }
331: return predecessors + definitions;
332: } else {
333: return predecessors;
334: }
335: }
336:
337: /**
338: * add Commands unique to C#.
339: * @param command ongoing command
340: */
341: public void addCompilerSpecificOptions(NetCommand command) {
342: command.addArgument(getIncludeDefaultReferencesParameter());
343: command.addArgument(getWarnLevelParameter());
344: command.addArgument(getDocFileParameter());
345: command.addArgument(getFullPathsParameter());
346: command.addArgument(getFileAlignParameter());
347: command.addArgument(getIncrementalParameter());
348: command.addArgument(getNoConfigParameter());
349: command.addArgument(getUnsafeParameter());
350: }
351:
352: // end execute
353:
354: /**
355: * Returns the delimiter which C# uses to separate references, i.e., a semi colon.
356: * @return the delimiter.
357: */
358: public String getReferenceDelimiter() {
359: return ";";
360: }
361:
362: /**
363: * This method indicates the filename extension for C# files.
364: * @return the file extension for C#, i.e., "cs" (without the dot).
365: */
366: public String getFileExtension() {
367: return "cs";
368: }
369:
370: /**
371: * Build a C# style parameter.
372: * @param command the command.
373: * @param resource the resource.
374: */
375: protected void createResourceParameter(NetCommand command,
376: DotnetResource resource) {
377: resource.getParameters(getProject(), command, true);
378: }
379:
380: }
|