1. /*
  2. * Copyright 2001-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. /*
  18. * build notes
  19. * -The reference CD to listen to while editing this file is
  20. * nap: Underworld - Everything, Everything
  21. */
  22. // ====================================================================
  23. // place in the optional ant tasks package
  24. // but in its own dotnet group
  25. // ====================================================================
  26. package org.apache.tools.ant.taskdefs.optional.dotnet;
  27. // ====================================================================
  28. // imports
  29. // ====================================================================
  30. import java.io.File;
  31. import org.apache.tools.ant.taskdefs.condition.Os;
  32. // ====================================================================
  33. /**
  34. * Compiles C# source into executables or modules.
  35. *
  36. * csc.exe on Windows or mcs on other platforms must be on the execute path, unless another executable
  37. * or the full path to that executable is specified in the <tt>executable</tt>
  38. * parameter
  39. * <p>
  40. * All parameters are optional: <csc/> should suffice to produce a debug
  41. * build of all *.cs files. However, naming an <tt>destFile</tt>stops the
  42. * csc compiler from choosing an output name from random, and
  43. * allows the dependency checker to determine if the file is out of date.
  44. * <p>
  45. * The task is a directory based task, so attributes like <b>includes="*.cs"
  46. * </b> and <b>excludes="broken.cs"</b> can be used to control the files pulled
  47. * in. By default, all *.cs files from the project folder down are included in
  48. * the command. When this happens the output file -if not specified- is taken
  49. * as the first file in the list, which may be somewhat hard to control.
  50. * Specifying the output file with <tt>destFile</tt> seems prudent. <p>
  51. *
  52. * <p>
  53. * For more complex source trees, nested <tt>src</tt> elemements can be
  54. * supplied. When such an element is present, the implicit fileset is ignored.
  55. * This makes sense, when you think about it :)
  56. * <p>
  57. *
  58. * References to external files can be made through the references attribute,
  59. * or (since Ant1.6), via nested <reference> filesets. With the latter,
  60. * the timestamps of the references are also used in the dependency
  61. * checking algorithm.
  62. * <p>
  63. *
  64. * Example
  65. *
  66. * <pre><csc
  67. * optimize="true"
  68. * debug="false"
  69. * docFile="documentation.xml"
  70. * warnLevel="4"
  71. * unsafe="false"
  72. * targetType="exe"
  73. * incremental="false"
  74. * mainClass = "MainApp"
  75. * destFile="NetApp.exe"
  76. * >
  77. * <src dir="src" includes="*.cs" />
  78. * <reference file="${testCSC.dll}" />
  79. * <define name="RELEASE" />
  80. * <define name="DEBUG" if="debug.property"/>
  81. * <define name="def3" unless="def3.property"/>
  82. * </csc>
  83. * </pre>
  84. *
  85. *
  86. * @ant.task name="csc" category="dotnet"
  87. * @since Ant 1.3
  88. */
  89. public class CSharp extends DotnetCompile {
  90. /**
  91. * defines list: RELEASE;WIN32;NO_SANITY_CHECKS;;SOMETHING_ELSE'
  92. */
  93. String definitions;
  94. /**
  95. * output XML documentation flag
  96. */
  97. private File docFile;
  98. /**
  99. * file alignment; 0 means let the compiler decide
  100. */
  101. private int fileAlign = 0;
  102. /**
  103. * use full paths to things
  104. */
  105. private boolean fullpaths = false;
  106. /**
  107. * incremental build flag
  108. */
  109. private boolean incremental;
  110. /**
  111. * enable unsafe code flag. Clearly set to false by default
  112. */
  113. protected boolean unsafe;
  114. /**
  115. * A flag that tells the compiler not to read in the compiler
  116. * settings files 'csc.rsp' in its bin directory and then the local directory
  117. */
  118. private boolean noconfig = false;
  119. /**
  120. * constructor inits everything and set up the search pattern
  121. */
  122. public CSharp() {
  123. clear();
  124. }
  125. /**
  126. * full cleanup
  127. */
  128. public void clear() {
  129. super.clear();
  130. docFile = null;
  131. fileAlign = 0;
  132. fullpaths = true;
  133. incremental = false;
  134. unsafe = false;
  135. noconfig = false;
  136. definitions = null;
  137. setExecutable(Os.isFamily("windows") ? "csc" : "mcs");
  138. }
  139. /**
  140. * file for generated XML documentation
  141. *
  142. *@param f output file
  143. */
  144. public void setDocFile(File f) {
  145. docFile = f;
  146. }
  147. /**
  148. * get the argument or null for no argument needed
  149. *
  150. *@return The DocFile Parameter to CSC
  151. */
  152. protected String getDocFileParameter() {
  153. if (docFile != null) {
  154. return "/doc:" + docFile.toString();
  155. } else {
  156. return null;
  157. }
  158. }
  159. /**
  160. * Set the file alignment.
  161. * Valid values are 0,512, 1024, 2048, 4096, 8192,
  162. * and 16384, 0 means 'leave to the compiler'
  163. */
  164. public void setFileAlign(int fileAlign) {
  165. this.fileAlign = fileAlign;
  166. }
  167. /**
  168. * get the argument or null for no argument needed
  169. *
  170. *@return The OutputFile Parameter to CSC
  171. */
  172. protected String getFileAlignParameter() {
  173. if (fileAlign != 0) {
  174. return "/filealign:" + fileAlign;
  175. } else {
  176. return null;
  177. }
  178. }
  179. /**
  180. * If true, print the full path of files on errors.
  181. *
  182. *@param enabled The new fullPaths value
  183. */
  184. public void setFullPaths(boolean enabled) {
  185. fullpaths = enabled;
  186. }
  187. /**
  188. * Gets the fullPathsParameter attribute of the CSharp object
  189. *
  190. *@return The fullPathsParameter value or null if unset
  191. */
  192. protected String getFullPathsParameter() {
  193. return fullpaths ? "/fullpaths" : null;
  194. }
  195. /**
  196. * set the incremental compilation flag on or off.
  197. *
  198. *@param incremental on/off flag
  199. */
  200. public void setIncremental(boolean incremental) {
  201. this.incremental = incremental;
  202. }
  203. /**
  204. * query the incrementalflag
  205. *
  206. *@return true if incremental compilation is turned on
  207. */
  208. public boolean getIncremental() {
  209. return incremental;
  210. }
  211. /**
  212. * get the incremental build argument
  213. *
  214. *@return The Incremental Parameter to CSC
  215. */
  216. protected String getIncrementalParameter() {
  217. return "/incremental" + (incremental ? "+" : "-");
  218. }
  219. /**
  220. * The output file. This is identical to the destFile attribute.
  221. *
  222. *@param params The new outputFile value
  223. */
  224. public void setOutputFile(File params) {
  225. setDestFile(params);
  226. }
  227. /**
  228. * If true, enables the unsafe keyword.
  229. *
  230. *@param unsafe The new Unsafe value
  231. */
  232. public void setUnsafe(boolean unsafe) {
  233. this.unsafe = unsafe;
  234. }
  235. /**
  236. * query the Unsafe attribute
  237. *
  238. *@return The Unsafe value
  239. */
  240. public boolean getUnsafe() {
  241. return this.unsafe;
  242. }
  243. /**
  244. * get the argument or null for no argument needed
  245. *
  246. *@return The Unsafe Parameter to CSC
  247. */
  248. protected String getUnsafeParameter() {
  249. return unsafe ? "/unsafe" : null;
  250. }
  251. /**
  252. * A flag that tells the compiler not to read in the compiler
  253. * settings files 'csc.rsp' in its bin directory and then the local directory
  254. *
  255. *@param enabled The new noConfig value
  256. */
  257. public void setNoConfig(boolean enabled) {
  258. noconfig = enabled;
  259. }
  260. /**
  261. * Gets the noConfigParameter attribute of the CSharp object
  262. *
  263. *@return The noConfigParameter value
  264. */
  265. protected String getNoConfigParameter() {
  266. return noconfig ? "/noconfig" : null;
  267. }
  268. /**
  269. * Semicolon separated list of defined constants.
  270. *
  271. *@param params The new definitions value
  272. */
  273. public void setDefinitions(String params) {
  274. definitions = params;
  275. }
  276. /**
  277. * override the superclasses version of this method (which we call)
  278. * with a check for a definitions attribute, the contents of which
  279. * are appended to the list.
  280. *@return The Definitions Parameter to CSC
  281. */
  282. protected String getDefinitionsParameter() {
  283. String predecessors = super.getDefinitionsParameter();
  284. if (notEmpty(definitions)) {
  285. if (predecessors == null) {
  286. predecessors = "/define:";
  287. }
  288. return predecessors + definitions;
  289. } else {
  290. return predecessors;
  291. }
  292. }
  293. /**
  294. * add Commands unique to C#.
  295. * @param command ongoing command
  296. */
  297. public void addCompilerSpecificOptions(NetCommand command) {
  298. command.addArgument(getIncludeDefaultReferencesParameter());
  299. command.addArgument(getWarnLevelParameter());
  300. command.addArgument(getDocFileParameter());
  301. command.addArgument(getFullPathsParameter());
  302. command.addArgument(getFileAlignParameter());
  303. command.addArgument(getIncrementalParameter());
  304. command.addArgument(getNoConfigParameter());
  305. command.addArgument(getUnsafeParameter());
  306. }
  307. // end execute
  308. /**
  309. * Returns the delimiter which C# uses to separate references, i.e., a semi colon.
  310. */
  311. public String getReferenceDelimiter() {
  312. return ";";
  313. }
  314. /**
  315. * This method indicates the filename extension for C# files.
  316. * @return the file extension for C#, i.e., "cs" (without the dot).
  317. */
  318. public String getFileExtension() {
  319. return "cs";
  320. }
  321. /**
  322. * from a resource, get the resource param string
  323. * @param resource
  324. * @return a string containing the resource param, or a null string
  325. * to conditionally exclude a resource.
  326. */
  327. protected String createResourceParameter(DotnetResource resource) {
  328. return resource.getCSharpStyleParameter();
  329. }
  330. }