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. package org.apache.tools.ant.taskdefs.optional.dotnet;
  23. import java.io.File;
  24. import java.util.Vector;
  25. import org.apache.tools.ant.BuildException;
  26. import org.apache.tools.ant.Project;
  27. import org.apache.tools.ant.types.EnumeratedAttribute;
  28. import org.apache.tools.ant.types.FileSet;
  29. /**
  30. * Assembles .NET Intermediate Language files.
  31. * ilasm.exe must be on the execute path, unless another executable
  32. * or the full path to that executable is specified in the <tt>executable</tt>
  33. * parameter
  34. * <p>
  35. *
  36. * <p>
  37. *
  38. * All parameters are optional: <il/> should suffice to produce a debug
  39. * build of all *.il files. The option set is roughly compatible with the
  40. * CSharp class; even though the command line options are only vaguely
  41. * equivalent. [The low level commands take things like /OUT=file, csc wants
  42. * /out:file ... /verbose is used some places; /quiet here in ildasm... etc.]
  43. * It would be nice if someone made all the command line tools consistent (and
  44. * not as brittle as the java cmdline tools) <p>
  45. * <p>
  46. * The task is a directory based task, so attributes like <b>includes="*.il"
  47. * </b> and <b>excludes="broken.il"</b> can be used to control the files pulled
  48. * in. You can also use nested <src> filesets to refer to source.
  49. * <p>
  50. *
  51. * @ant.task name="ilasm" category="dotnet"
  52. */
  53. public class Ilasm
  54. extends DotnetBaseMatchingTask {
  55. /**
  56. * Name of the executable. The .exe suffix is deliberately not included in
  57. * anticipation of the unix version
  58. */
  59. protected static final String exe_name = "ilasm";
  60. /**
  61. * what is the file extension we search on?
  62. */
  63. protected static final String file_ext = "il";
  64. /**
  65. * and now derive the search pattern from the extension
  66. */
  67. protected static final String file_pattern = "**/*." + file_ext;
  68. /**
  69. * title of task for external presentation
  70. */
  71. protected static final String exe_title = "ilasm";
  72. /**
  73. * type of target. Should be one of exe|library|module|winexe|(null)
  74. * default is exe; the actual value (if not null) is fed to the command
  75. * line. <br>
  76. * See /target
  77. */
  78. protected String targetType;
  79. /**
  80. * verbose flag
  81. */
  82. protected boolean verbose;
  83. /**
  84. * listing flag
  85. */
  86. protected boolean listing;
  87. /**
  88. * resource file (.res format) to include in the app.
  89. */
  90. protected File resourceFile;
  91. /**
  92. * flag to control action on execution trouble
  93. */
  94. protected boolean failOnError;
  95. /**
  96. * debug flag. Controls generation of debug information.
  97. */
  98. protected boolean debug;
  99. /**
  100. * file containing private key
  101. */
  102. private File keyfile;
  103. /**
  104. * any extra command options?
  105. */
  106. protected String extraOptions;
  107. /**
  108. * filesets of references
  109. */
  110. protected Vector referenceFilesets = new Vector();
  111. /**
  112. * constructor inits everything and set up the search pattern
  113. */
  114. public Ilasm() {
  115. Clear();
  116. setIncludes(file_pattern);
  117. }
  118. /**
  119. * reset all contents.
  120. */
  121. public void Clear() {
  122. targetType = null;
  123. srcDir = null;
  124. listing = false;
  125. verbose = false;
  126. debug = true;
  127. outputFile = null;
  128. failOnError = true;
  129. resourceFile = null;
  130. extraOptions = null;
  131. }
  132. /**
  133. * Sets the type of target, either "exe" or "library".
  134. *
  135. *@param targetType one of exe|library|
  136. *@exception BuildException if target is not one of
  137. * exe|library
  138. */
  139. public void setTargetType(String targetType)
  140. throws BuildException {
  141. this.targetType = targetType.toLowerCase();
  142. if (!targetType.equals("exe") && !targetType.equals("library")) {
  143. throw new BuildException("targetType " + targetType + " is not a valid type");
  144. }
  145. }
  146. /**
  147. * accessor method for target type
  148. *
  149. *@return the current target option
  150. */
  151. public String getTargetType() {
  152. return targetType;
  153. }
  154. /**
  155. * g get the target type or null for no argument needed
  156. *
  157. *@return The TargetTypeParameter value
  158. */
  159. protected String getTargetTypeParameter() {
  160. if (!notEmpty(targetType)) {
  161. return null;
  162. }
  163. if (targetType.equals("exe")) {
  164. return "/exe";
  165. } else if (targetType.equals("library")) {
  166. return "/dll";
  167. } else {
  168. return null;
  169. }
  170. }
  171. /**
  172. * Sets the Owner attribute.
  173. *
  174. * @param s The new Owner value
  175. * @ant.attribute ignore="true"
  176. */
  177. public void setOwner(String s) {
  178. log("This option is not supported by ILASM as of Beta-2, "
  179. + "and will be ignored", Project.MSG_WARN);
  180. }
  181. /**
  182. * test for a string containing something useful
  183. *
  184. *@param s any string
  185. *@return true if the argument is not null or empty
  186. */
  187. protected boolean notEmpty(String s) {
  188. return s != null && s.length() != 0;
  189. }
  190. /**
  191. * If true, enable verbose ILASM output.
  192. *
  193. *@param b flag set to true for verbose on
  194. */
  195. public void setVerbose(boolean b) {
  196. verbose = b;
  197. }
  198. /**
  199. * turn the verbose flag into a parameter for ILASM
  200. *
  201. *@return null or the appropriate command line string
  202. */
  203. protected String getVerboseParameter() {
  204. return verbose ? null : "/quiet";
  205. }
  206. /**
  207. * If true, produce a listing (off by default).
  208. *
  209. *@param b flag set to true for listing on
  210. */
  211. public void setListing(boolean b) {
  212. listing = b;
  213. }
  214. /**
  215. * turn the listing flag into a parameter for ILASM
  216. *
  217. *@return the appropriate string from the state of the listing flag
  218. */
  219. protected String getListingParameter() {
  220. return listing ? "/listing" : "/nolisting";
  221. }
  222. /**
  223. * Set the output file; identical to setDestFile
  224. * @see DotnetBaseMatchingTask#setDestFile
  225. *@param params The new outputFile value
  226. */
  227. public void setOutputFile(File params) {
  228. outputFile = params;
  229. }
  230. /**
  231. * get the output file
  232. *
  233. *@return the argument string or null for no argument
  234. */
  235. protected String getOutputFileParameter() {
  236. if (outputFile == null) {
  237. return null;
  238. }
  239. return "/output=" + outputFile.toString();
  240. }
  241. /**
  242. * name of resource file to include.
  243. *
  244. * @param fileName path to the file. Can be relative, absolute, whatever.
  245. */
  246. public void setResourceFile(File fileName) {
  247. resourceFile = fileName;
  248. }
  249. /**
  250. * Gets the resourceFileParameter attribute of the Ilasm task
  251. *
  252. *@return The resourceFileParameter value
  253. */
  254. protected String getResourceFileParameter() {
  255. if (resourceFile != null) {
  256. return "/resource=" + resourceFile.toString();
  257. } else {
  258. return null;
  259. }
  260. }
  261. /**
  262. * If true, fails if ilasm tool fails.
  263. *
  264. *@param b The new failOnError value
  265. */
  266. public void setFailOnError(boolean b) {
  267. failOnError = b;
  268. }
  269. /**
  270. * query fail on error flag
  271. *
  272. *@return The failFailOnError value
  273. */
  274. public boolean getFailOnError() {
  275. return failOnError;
  276. }
  277. /**
  278. * set the debug flag on or off.
  279. *
  280. *@param f on/off flag
  281. */
  282. public void setDebug(boolean f) {
  283. debug = f;
  284. }
  285. /**
  286. * query the debug flag
  287. *
  288. *@return true if debug is turned on
  289. */
  290. public boolean getDebug() {
  291. return debug;
  292. }
  293. /**
  294. * get the argument or null for no argument needed
  295. *
  296. *@return The debugParameter value
  297. */
  298. protected String getDebugParameter() {
  299. return debug ? "/debug" : null;
  300. }
  301. /**
  302. * the name of a file containing a private key.
  303. *
  304. *@param keyfile The new keyfile value
  305. */
  306. public void setKeyfile(File keyfile) {
  307. this.keyfile = keyfile;
  308. }
  309. /**
  310. * get the argument or null for no argument needed
  311. *
  312. *@return The keyfileParameter value
  313. */
  314. protected String getKeyfileParameter() {
  315. if (keyfile != null) {
  316. return "/keyfile:" + keyfile.toString();
  317. } else {
  318. return null;
  319. }
  320. }
  321. /**
  322. * Any extra options which are not explicitly
  323. * supported by this task.
  324. *
  325. *@param extraOptions The new ExtraOptions value
  326. */
  327. public void setExtraOptions(String extraOptions) {
  328. this.extraOptions = extraOptions;
  329. }
  330. /**
  331. * Gets the ExtraOptions attribute
  332. *
  333. *@return The ExtraOptions value
  334. */
  335. public String getExtraOptions() {
  336. return this.extraOptions;
  337. }
  338. /**
  339. * get any extra options or null for no argument needed
  340. *
  341. *@return The ExtraOptions Parameter to CSC
  342. */
  343. protected String getExtraOptionsParameter() {
  344. if (extraOptions != null && extraOptions.length() != 0) {
  345. return extraOptions;
  346. } else {
  347. return null;
  348. }
  349. }
  350. /**
  351. * set the target type to one of exe|library
  352. * @param targetType
  353. */
  354. public void setTargetType(TargetTypes targetType) {
  355. this.targetType = targetType.getValue();
  356. }
  357. /**
  358. * This is the execution entry point. Build a list of files and call ilasm
  359. * on each of them.
  360. *
  361. *@throws BuildException if the assembly failed and FailOnError is true
  362. */
  363. public void execute()
  364. throws BuildException {
  365. NetCommand command = buildIlasmCommand();
  366. addFilesAndExecute(command, false);
  367. }
  368. // end execute
  369. /**
  370. * build up our ilasm command
  371. * @return
  372. */
  373. private NetCommand buildIlasmCommand() {
  374. NetCommand command = new NetCommand(this, exe_title, exe_name);
  375. command.setFailOnError(getFailOnError());
  376. //fill in args
  377. command.addArgument(getDebugParameter());
  378. command.addArgument(getTargetTypeParameter());
  379. command.addArgument(getListingParameter());
  380. command.addArgument(getOutputFileParameter());
  381. command.addArgument(getResourceFileParameter());
  382. command.addArgument(getVerboseParameter());
  383. command.addArgument(getKeyfileParameter());
  384. command.addArgument(getExtraOptionsParameter());
  385. /*
  386. * space for more argumentativeness
  387. * command.addArgument();
  388. * command.addArgument();
  389. */
  390. return command;
  391. }
  392. /**
  393. * add a new reference fileset to the compilation
  394. * @param reference
  395. */
  396. public void addReference(FileSet reference) {
  397. referenceFilesets.add(reference);
  398. }
  399. /**
  400. * test for a file being managed or not
  401. * @return true if we think this is a managed executable, and thus OK
  402. * for linking
  403. * @todo look at the PE header of the exe and see if it is managed or not.
  404. */
  405. protected static boolean isFileManagedBinary(File file) {
  406. String filename = file.toString().toLowerCase();
  407. return filename.endsWith(".exe") || filename.endsWith(".dll")
  408. || filename.endsWith(".netmodule");
  409. }
  410. /**
  411. * Target types to build.
  412. * valid build types are exe|library|module|winexe
  413. */
  414. public static class TargetTypes extends EnumeratedAttribute {
  415. public String[] getValues() {
  416. return new String[]{
  417. "exe",
  418. "library",
  419. };
  420. }
  421. }
  422. }