You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Javac.java 29 kB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016
  1. /*
  2. * Copyright 2000-2006 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. package org.apache.tools.ant.taskdefs;
  18. import java.io.File;
  19. import org.apache.tools.ant.BuildException;
  20. import org.apache.tools.ant.DirectoryScanner;
  21. import org.apache.tools.ant.Project;
  22. import org.apache.tools.ant.taskdefs.compilers.CompilerAdapter;
  23. import org.apache.tools.ant.taskdefs.compilers.CompilerAdapterFactory;
  24. import org.apache.tools.ant.types.Path;
  25. import org.apache.tools.ant.types.Reference;
  26. import org.apache.tools.ant.util.GlobPatternMapper;
  27. import org.apache.tools.ant.util.JavaEnvUtils;
  28. import org.apache.tools.ant.util.SourceFileScanner;
  29. import org.apache.tools.ant.util.facade.FacadeTaskHelper;
  30. /**
  31. * Compiles Java source files. This task can take the following
  32. * arguments:
  33. * <ul>
  34. * <li>sourcedir
  35. * <li>destdir
  36. * <li>deprecation
  37. * <li>classpath
  38. * <li>bootclasspath
  39. * <li>extdirs
  40. * <li>optimize
  41. * <li>debug
  42. * <li>encoding
  43. * <li>target
  44. * <li>depend
  45. * <li>verbose
  46. * <li>failonerror
  47. * <li>includeantruntime
  48. * <li>includejavaruntime
  49. * <li>source
  50. * <li>compiler
  51. * </ul>
  52. * Of these arguments, the <b>sourcedir</b> and <b>destdir</b> are required.
  53. * <p>
  54. * When this task executes, it will recursively scan the sourcedir and
  55. * destdir looking for Java source files to compile. This task makes its
  56. * compile decision based on timestamp.
  57. *
  58. *
  59. * @since Ant 1.1
  60. *
  61. * @ant.task category="java"
  62. */
  63. public class Javac extends MatchingTask {
  64. private static final String FAIL_MSG
  65. = "Compile failed; see the compiler error output for details.";
  66. private static final String JAVAC16 = "javac1.6";
  67. private static final String JAVAC15 = "javac1.5";
  68. private static final String JAVAC14 = "javac1.4";
  69. private static final String JAVAC13 = "javac1.3";
  70. private static final String JAVAC12 = "javac1.2";
  71. private static final String JAVAC11 = "javac1.1";
  72. private static final String MODERN = "modern";
  73. private static final String CLASSIC = "classic";
  74. private static final String EXTJAVAC = "extJavac";
  75. private Path src;
  76. private File destDir;
  77. private Path compileClasspath;
  78. private Path compileSourcepath;
  79. private String encoding;
  80. private boolean debug = false;
  81. private boolean optimize = false;
  82. private boolean deprecation = false;
  83. private boolean depend = false;
  84. private boolean verbose = false;
  85. private String targetAttribute;
  86. private Path bootclasspath;
  87. private Path extdirs;
  88. private boolean includeAntRuntime = true;
  89. private boolean includeJavaRuntime = false;
  90. private boolean fork = false;
  91. private String forkedExecutable = null;
  92. private boolean nowarn = false;
  93. private String memoryInitialSize;
  94. private String memoryMaximumSize;
  95. private FacadeTaskHelper facade = null;
  96. protected boolean failOnError = true;
  97. protected boolean listFiles = false;
  98. protected File[] compileList = new File[0];
  99. private String source;
  100. private String debugLevel;
  101. private File tmpDir;
  102. /**
  103. * Javac task for compilation of Java files.
  104. */
  105. public Javac() {
  106. facade = new FacadeTaskHelper(assumedJavaVersion());
  107. }
  108. private String assumedJavaVersion() {
  109. if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)) {
  110. return JAVAC11;
  111. } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_2)) {
  112. return JAVAC12;
  113. } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_3)) {
  114. return JAVAC13;
  115. } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_4)) {
  116. return JAVAC14;
  117. } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_5)) {
  118. return JAVAC15;
  119. } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_6)) {
  120. return JAVAC16;
  121. } else {
  122. return CLASSIC;
  123. }
  124. }
  125. /**
  126. * Get the value of debugLevel.
  127. * @return value of debugLevel.
  128. */
  129. public String getDebugLevel() {
  130. return debugLevel;
  131. }
  132. /**
  133. * Keyword list to be appended to the -g command-line switch.
  134. *
  135. * This will be ignored by all implementations except modern
  136. * and classic(ver >= 1.2). Legal values are none or a
  137. * comma-separated list of the following keywords: lines, vars,
  138. * and source. If debuglevel is not specified, by default, :none
  139. * will be appended to -g. If debug is not turned on, this attribute
  140. * will be ignored.
  141. *
  142. * @param v Value to assign to debugLevel.
  143. */
  144. public void setDebugLevel(String v) {
  145. this.debugLevel = v;
  146. }
  147. /**
  148. * Get the value of source.
  149. * @return value of source.
  150. */
  151. public String getSource() {
  152. return source;
  153. }
  154. /**
  155. * Value of the -source command-line switch; will be ignored
  156. * by all implementations except modern and jikes.
  157. *
  158. * If you use this attribute together with jikes, you must make
  159. * sure that your version of jikes supports the -source switch.
  160. * Legal values are 1.3, 1.4, 1.5, and 5 - by default, no
  161. * -source argument will be used at all.
  162. *
  163. * @param v Value to assign to source.
  164. */
  165. public void setSource(String v) {
  166. this.source = v;
  167. }
  168. /**
  169. * Adds a path for source compilation.
  170. *
  171. * @return a nested src element.
  172. */
  173. public Path createSrc() {
  174. if (src == null) {
  175. src = new Path(getProject());
  176. }
  177. return src.createPath();
  178. }
  179. /**
  180. * Recreate src.
  181. *
  182. * @return a nested src element.
  183. */
  184. protected Path recreateSrc() {
  185. src = null;
  186. return createSrc();
  187. }
  188. /**
  189. * Set the source directories to find the source Java files.
  190. * @param srcDir the source directories as a path
  191. */
  192. public void setSrcdir(Path srcDir) {
  193. if (src == null) {
  194. src = srcDir;
  195. } else {
  196. src.append(srcDir);
  197. }
  198. }
  199. /**
  200. * Gets the source dirs to find the source java files.
  201. * @return the source directories as a path
  202. */
  203. public Path getSrcdir() {
  204. return src;
  205. }
  206. /**
  207. * Set the destination directory into which the Java source
  208. * files should be compiled.
  209. * @param destDir the destination director
  210. */
  211. public void setDestdir(File destDir) {
  212. this.destDir = destDir;
  213. }
  214. /**
  215. * Gets the destination directory into which the java source files
  216. * should be compiled.
  217. * @return the destination directory
  218. */
  219. public File getDestdir() {
  220. return destDir;
  221. }
  222. /**
  223. * Set the sourcepath to be used for this compilation.
  224. * @param sourcepath the source path
  225. */
  226. public void setSourcepath(Path sourcepath) {
  227. if (compileSourcepath == null) {
  228. compileSourcepath = sourcepath;
  229. } else {
  230. compileSourcepath.append(sourcepath);
  231. }
  232. }
  233. /**
  234. * Gets the sourcepath to be used for this compilation.
  235. * @return the source path
  236. */
  237. public Path getSourcepath() {
  238. return compileSourcepath;
  239. }
  240. /**
  241. * Adds a path to sourcepath.
  242. * @return a sourcepath to be configured
  243. */
  244. public Path createSourcepath() {
  245. if (compileSourcepath == null) {
  246. compileSourcepath = new Path(getProject());
  247. }
  248. return compileSourcepath.createPath();
  249. }
  250. /**
  251. * Adds a reference to a source path defined elsewhere.
  252. * @param r a reference to a source path
  253. */
  254. public void setSourcepathRef(Reference r) {
  255. createSourcepath().setRefid(r);
  256. }
  257. /**
  258. * Set the classpath to be used for this compilation.
  259. *
  260. * @param classpath an Ant Path object containing the compilation classpath.
  261. */
  262. public void setClasspath(Path classpath) {
  263. if (compileClasspath == null) {
  264. compileClasspath = classpath;
  265. } else {
  266. compileClasspath.append(classpath);
  267. }
  268. }
  269. /**
  270. * Gets the classpath to be used for this compilation.
  271. * @return the class path
  272. */
  273. public Path getClasspath() {
  274. return compileClasspath;
  275. }
  276. /**
  277. * Adds a path to the classpath.
  278. * @return a class path to be configured
  279. */
  280. public Path createClasspath() {
  281. if (compileClasspath == null) {
  282. compileClasspath = new Path(getProject());
  283. }
  284. return compileClasspath.createPath();
  285. }
  286. /**
  287. * Adds a reference to a classpath defined elsewhere.
  288. * @param r a reference to a classpath
  289. */
  290. public void setClasspathRef(Reference r) {
  291. createClasspath().setRefid(r);
  292. }
  293. /**
  294. * Sets the bootclasspath that will be used to compile the classes
  295. * against.
  296. * @param bootclasspath a path to use as a boot class path (may be more
  297. * than one)
  298. */
  299. public void setBootclasspath(Path bootclasspath) {
  300. if (this.bootclasspath == null) {
  301. this.bootclasspath = bootclasspath;
  302. } else {
  303. this.bootclasspath.append(bootclasspath);
  304. }
  305. }
  306. /**
  307. * Gets the bootclasspath that will be used to compile the classes
  308. * against.
  309. * @return the boot path
  310. */
  311. public Path getBootclasspath() {
  312. return bootclasspath;
  313. }
  314. /**
  315. * Adds a path to the bootclasspath.
  316. * @return a path to be configured
  317. */
  318. public Path createBootclasspath() {
  319. if (bootclasspath == null) {
  320. bootclasspath = new Path(getProject());
  321. }
  322. return bootclasspath.createPath();
  323. }
  324. /**
  325. * Adds a reference to a classpath defined elsewhere.
  326. * @param r a reference to a classpath
  327. */
  328. public void setBootClasspathRef(Reference r) {
  329. createBootclasspath().setRefid(r);
  330. }
  331. /**
  332. * Sets the extension directories that will be used during the
  333. * compilation.
  334. * @param extdirs a path
  335. */
  336. public void setExtdirs(Path extdirs) {
  337. if (this.extdirs == null) {
  338. this.extdirs = extdirs;
  339. } else {
  340. this.extdirs.append(extdirs);
  341. }
  342. }
  343. /**
  344. * Gets the extension directories that will be used during the
  345. * compilation.
  346. * @return the extension directories as a path
  347. */
  348. public Path getExtdirs() {
  349. return extdirs;
  350. }
  351. /**
  352. * Adds a path to extdirs.
  353. * @return a path to be configured
  354. */
  355. public Path createExtdirs() {
  356. if (extdirs == null) {
  357. extdirs = new Path(getProject());
  358. }
  359. return extdirs.createPath();
  360. }
  361. /**
  362. * If true, list the source files being handed off to the compiler.
  363. * @param list if true list the source files
  364. */
  365. public void setListfiles(boolean list) {
  366. listFiles = list;
  367. }
  368. /**
  369. * Get the listfiles flag.
  370. * @return the listfiles flag
  371. */
  372. public boolean getListfiles() {
  373. return listFiles;
  374. }
  375. /**
  376. * Indicates whether the build will continue
  377. * even if there are compilation errors; defaults to true.
  378. * @param fail if true halt the build on failure
  379. */
  380. public void setFailonerror(boolean fail) {
  381. failOnError = fail;
  382. }
  383. /**
  384. * @ant.attribute ignore="true"
  385. * @param proceed inverse of failoferror
  386. */
  387. public void setProceed(boolean proceed) {
  388. failOnError = !proceed;
  389. }
  390. /**
  391. * Gets the failonerror flag.
  392. * @return the failonerror flag
  393. */
  394. public boolean getFailonerror() {
  395. return failOnError;
  396. }
  397. /**
  398. * Indicates whether source should be
  399. * compiled with deprecation information; defaults to off.
  400. * @param deprecation if true turn on deprecation information
  401. */
  402. public void setDeprecation(boolean deprecation) {
  403. this.deprecation = deprecation;
  404. }
  405. /**
  406. * Gets the deprecation flag.
  407. * @return the deprecation flag
  408. */
  409. public boolean getDeprecation() {
  410. return deprecation;
  411. }
  412. /**
  413. * The initial size of the memory for the underlying VM
  414. * if javac is run externally; ignored otherwise.
  415. * Defaults to the standard VM memory setting.
  416. * (Examples: 83886080, 81920k, or 80m)
  417. * @param memoryInitialSize string to pass to VM
  418. */
  419. public void setMemoryInitialSize(String memoryInitialSize) {
  420. this.memoryInitialSize = memoryInitialSize;
  421. }
  422. /**
  423. * Gets the memoryInitialSize flag.
  424. * @return the memoryInitialSize flag
  425. */
  426. public String getMemoryInitialSize() {
  427. return memoryInitialSize;
  428. }
  429. /**
  430. * The maximum size of the memory for the underlying VM
  431. * if javac is run externally; ignored otherwise.
  432. * Defaults to the standard VM memory setting.
  433. * (Examples: 83886080, 81920k, or 80m)
  434. * @param memoryMaximumSize string to pass to VM
  435. */
  436. public void setMemoryMaximumSize(String memoryMaximumSize) {
  437. this.memoryMaximumSize = memoryMaximumSize;
  438. }
  439. /**
  440. * Gets the memoryMaximumSize flag.
  441. * @return the memoryMaximumSize flag
  442. */
  443. public String getMemoryMaximumSize() {
  444. return memoryMaximumSize;
  445. }
  446. /**
  447. * Set the Java source file encoding name.
  448. * @param encoding the source file encoding
  449. */
  450. public void setEncoding(String encoding) {
  451. this.encoding = encoding;
  452. }
  453. /**
  454. * Gets the java source file encoding name.
  455. * @return the source file encoding name
  456. */
  457. public String getEncoding() {
  458. return encoding;
  459. }
  460. /**
  461. * Indicates whether source should be compiled
  462. * with debug information; defaults to off.
  463. * @param debug if true compile with debug information
  464. */
  465. public void setDebug(boolean debug) {
  466. this.debug = debug;
  467. }
  468. /**
  469. * Gets the debug flag.
  470. * @return the debug flag
  471. */
  472. public boolean getDebug() {
  473. return debug;
  474. }
  475. /**
  476. * If true, compiles with optimization enabled.
  477. * @param optimize if true compile with optimization enabled
  478. */
  479. public void setOptimize(boolean optimize) {
  480. this.optimize = optimize;
  481. }
  482. /**
  483. * Gets the optimize flag.
  484. * @return the optimize flag
  485. */
  486. public boolean getOptimize() {
  487. return optimize;
  488. }
  489. /**
  490. * Enables dependency-tracking for compilers
  491. * that support this (jikes and classic).
  492. * @param depend if true enable dependency-tracking
  493. */
  494. public void setDepend(boolean depend) {
  495. this.depend = depend;
  496. }
  497. /**
  498. * Gets the depend flag.
  499. * @return the depend flag
  500. */
  501. public boolean getDepend() {
  502. return depend;
  503. }
  504. /**
  505. * If true, asks the compiler for verbose output.
  506. * @param verbose if true, asks the compiler for verbose output
  507. */
  508. public void setVerbose(boolean verbose) {
  509. this.verbose = verbose;
  510. }
  511. /**
  512. * Gets the verbose flag.
  513. * @return the verbose flag
  514. */
  515. public boolean getVerbose() {
  516. return verbose;
  517. }
  518. /**
  519. * Sets the target VM that the classes will be compiled for. Valid
  520. * values depend on the compiler, for jdk 1.4 the valid values are
  521. * "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "5" and "6".
  522. * @param target the target VM
  523. */
  524. public void setTarget(String target) {
  525. this.targetAttribute = target;
  526. }
  527. /**
  528. * Gets the target VM that the classes will be compiled for.
  529. * @return the target VM
  530. */
  531. public String getTarget() {
  532. return targetAttribute;
  533. }
  534. /**
  535. * If true, includes Ant's own classpath in the classpath.
  536. * @param include if true, includes Ant's own classpath in the classpath
  537. */
  538. public void setIncludeantruntime(boolean include) {
  539. includeAntRuntime = include;
  540. }
  541. /**
  542. * Gets whether or not the ant classpath is to be included in the classpath.
  543. * @return whether or not the ant classpath is to be included in the classpath
  544. */
  545. public boolean getIncludeantruntime() {
  546. return includeAntRuntime;
  547. }
  548. /**
  549. * If true, includes the Java runtime libraries in the classpath.
  550. * @param include if true, includes the Java runtime libraries in the classpath
  551. */
  552. public void setIncludejavaruntime(boolean include) {
  553. includeJavaRuntime = include;
  554. }
  555. /**
  556. * Gets whether or not the java runtime should be included in this
  557. * task's classpath.
  558. * @return the includejavaruntime attribute
  559. */
  560. public boolean getIncludejavaruntime() {
  561. return includeJavaRuntime;
  562. }
  563. /**
  564. * If true, forks the javac compiler.
  565. *
  566. * @param f "true|false|on|off|yes|no"
  567. */
  568. public void setFork(boolean f) {
  569. fork = f;
  570. }
  571. /**
  572. * Sets the name of the javac executable.
  573. *
  574. * <p>Ignored unless fork is true or extJavac has been specified
  575. * as the compiler.</p>
  576. * @param forkExec the name of the executable
  577. */
  578. public void setExecutable(String forkExec) {
  579. forkedExecutable = forkExec;
  580. }
  581. /**
  582. * The value of the executable attribute, if any.
  583. *
  584. * @since Ant 1.6
  585. * @return the name of the java executable
  586. */
  587. public String getExecutable() {
  588. return forkedExecutable;
  589. }
  590. /**
  591. * Is this a forked invocation of JDK's javac?
  592. * @return true if this is a forked invocation
  593. */
  594. public boolean isForkedJavac() {
  595. return fork || "extJavac".equals(getCompiler());
  596. }
  597. /**
  598. * The name of the javac executable to use in fork-mode.
  599. *
  600. * <p>This is either the name specified with the executable
  601. * attribute or the full path of the javac compiler of the VM Ant
  602. * is currently running in - guessed by Ant.</p>
  603. *
  604. * <p>You should <strong>not</strong> invoke this method if you
  605. * want to get the value of the executable command - use {@link
  606. * #getExecutable getExecutable} for this.</p>
  607. * @return the name of the javac executable
  608. */
  609. public String getJavacExecutable() {
  610. if (forkedExecutable == null && isForkedJavac()) {
  611. forkedExecutable = getSystemJavac();
  612. } else if (forkedExecutable != null && !isForkedJavac()) {
  613. forkedExecutable = null;
  614. }
  615. return forkedExecutable;
  616. }
  617. /**
  618. * If true, enables the -nowarn option.
  619. * @param flag if true, enable the -nowarn option
  620. */
  621. public void setNowarn(boolean flag) {
  622. this.nowarn = flag;
  623. }
  624. /**
  625. * Should the -nowarn option be used.
  626. * @return true if the -nowarn option should be used
  627. */
  628. public boolean getNowarn() {
  629. return nowarn;
  630. }
  631. /**
  632. * Adds an implementation specific command-line argument.
  633. * @return a ImplementationSpecificArgument to be configured
  634. */
  635. public ImplementationSpecificArgument createCompilerArg() {
  636. ImplementationSpecificArgument arg =
  637. new ImplementationSpecificArgument();
  638. facade.addImplementationArgument(arg);
  639. return arg;
  640. }
  641. /**
  642. * Get the additional implementation specific command line arguments.
  643. * @return array of command line arguments, guaranteed to be non-null.
  644. */
  645. public String[] getCurrentCompilerArgs() {
  646. String chosen = facade.getExplicitChoice();
  647. try {
  648. // make sure facade knows about magic properties and fork setting
  649. String appliedCompiler = getCompiler();
  650. facade.setImplementation(appliedCompiler);
  651. String[] result = facade.getArgs();
  652. String altCompilerName = getAltCompilerName(facade.getImplementation());
  653. if (result.length == 0 && altCompilerName != null) {
  654. facade.setImplementation(altCompilerName);
  655. result = facade.getArgs();
  656. }
  657. return result;
  658. } finally {
  659. facade.setImplementation(chosen);
  660. }
  661. }
  662. private String getAltCompilerName(String anImplementation) {
  663. if (JAVAC16.equalsIgnoreCase(anImplementation)
  664. || JAVAC15.equalsIgnoreCase(anImplementation)
  665. || JAVAC14.equalsIgnoreCase(anImplementation)
  666. || JAVAC13.equalsIgnoreCase(anImplementation)) {
  667. return MODERN;
  668. }
  669. if (JAVAC12.equalsIgnoreCase(anImplementation)
  670. || JAVAC11.equalsIgnoreCase(anImplementation)) {
  671. return CLASSIC;
  672. }
  673. if (MODERN.equalsIgnoreCase(anImplementation)) {
  674. String nextSelected = assumedJavaVersion();
  675. if (JAVAC16.equalsIgnoreCase(nextSelected)
  676. || JAVAC15.equalsIgnoreCase(nextSelected)
  677. || JAVAC14.equalsIgnoreCase(nextSelected)
  678. || JAVAC13.equalsIgnoreCase(nextSelected)) {
  679. return nextSelected;
  680. }
  681. }
  682. if (CLASSIC.equals(anImplementation)) {
  683. return assumedJavaVersion();
  684. }
  685. if (EXTJAVAC.equalsIgnoreCase(anImplementation)) {
  686. return assumedJavaVersion();
  687. }
  688. return null;
  689. }
  690. /**
  691. * Where Ant should place temporary files.
  692. *
  693. * @since Ant 1.6
  694. * @param tmpDir the temporary directory
  695. */
  696. public void setTempdir(File tmpDir) {
  697. this.tmpDir = tmpDir;
  698. }
  699. /**
  700. * Where Ant should place temporary files.
  701. *
  702. * @since Ant 1.6
  703. * @return the temporary directory
  704. */
  705. public File getTempdir() {
  706. return tmpDir;
  707. }
  708. /**
  709. * Executes the task.
  710. * @exception BuildException if an error occurs
  711. */
  712. public void execute() throws BuildException {
  713. checkParameters();
  714. resetFileLists();
  715. // scan source directories and dest directory to build up
  716. // compile lists
  717. String[] list = src.list();
  718. for (int i = 0; i < list.length; i++) {
  719. File srcDir = getProject().resolveFile(list[i]);
  720. if (!srcDir.exists()) {
  721. throw new BuildException("srcdir \""
  722. + srcDir.getPath()
  723. + "\" does not exist!", getLocation());
  724. }
  725. DirectoryScanner ds = this.getDirectoryScanner(srcDir);
  726. String[] files = ds.getIncludedFiles();
  727. scanDir(srcDir, destDir != null ? destDir : srcDir, files);
  728. }
  729. compile();
  730. }
  731. /**
  732. * Clear the list of files to be compiled and copied..
  733. */
  734. protected void resetFileLists() {
  735. compileList = new File[0];
  736. }
  737. /**
  738. * Scans the directory looking for source files to be compiled.
  739. * The results are returned in the class variable compileList
  740. *
  741. * @param srcDir The source directory
  742. * @param destDir The destination directory
  743. * @param files An array of filenames
  744. */
  745. protected void scanDir(File srcDir, File destDir, String[] files) {
  746. GlobPatternMapper m = new GlobPatternMapper();
  747. m.setFrom("*.java");
  748. m.setTo("*.class");
  749. SourceFileScanner sfs = new SourceFileScanner(this);
  750. File[] newFiles = sfs.restrictAsFiles(files, srcDir, destDir, m);
  751. if (newFiles.length > 0) {
  752. File[] newCompileList
  753. = new File[compileList.length + newFiles.length];
  754. System.arraycopy(compileList, 0, newCompileList, 0,
  755. compileList.length);
  756. System.arraycopy(newFiles, 0, newCompileList,
  757. compileList.length, newFiles.length);
  758. compileList = newCompileList;
  759. }
  760. }
  761. /**
  762. * Gets the list of files to be compiled.
  763. * @return the list of files as an array
  764. */
  765. public File[] getFileList() {
  766. return compileList;
  767. }
  768. /**
  769. * Is the compiler implementation a jdk compiler
  770. *
  771. * @param compilerImpl the name of the compiler implementation
  772. * @return true if compilerImpl is "modern", "classic",
  773. * "javac1.1", "javac1.2", "javac1.3", "javac1.4", "javac1.5" or
  774. * "javac1.6".
  775. */
  776. protected boolean isJdkCompiler(String compilerImpl) {
  777. return MODERN.equals(compilerImpl)
  778. || CLASSIC.equals(compilerImpl)
  779. || JAVAC16.equals(compilerImpl)
  780. || JAVAC15.equals(compilerImpl)
  781. || JAVAC14.equals(compilerImpl)
  782. || JAVAC13.equals(compilerImpl)
  783. || JAVAC12.equals(compilerImpl)
  784. || JAVAC11.equals(compilerImpl);
  785. }
  786. /**
  787. * @return the executable name of the java compiler
  788. */
  789. protected String getSystemJavac() {
  790. return JavaEnvUtils.getJdkExecutable("javac");
  791. }
  792. /**
  793. * Choose the implementation for this particular task.
  794. * @param compiler the name of the compiler
  795. * @since Ant 1.5
  796. */
  797. public void setCompiler(String compiler) {
  798. facade.setImplementation(compiler);
  799. }
  800. /**
  801. * The implementation for this particular task.
  802. *
  803. * <p>Defaults to the build.compiler property but can be overridden
  804. * via the compiler and fork attributes.</p>
  805. *
  806. * <p>If fork has been set to true, the result will be extJavac
  807. * and not classic or java1.2 - no matter what the compiler
  808. * attribute looks like.</p>
  809. *
  810. * @see #getCompilerVersion
  811. *
  812. * @since Ant 1.5
  813. */
  814. public String getCompiler() {
  815. String compilerImpl = getCompilerVersion();
  816. if (fork) {
  817. if (isJdkCompiler(compilerImpl)) {
  818. compilerImpl = "extJavac";
  819. } else {
  820. log("Since compiler setting isn't classic or modern,"
  821. + "ignoring fork setting.", Project.MSG_WARN);
  822. }
  823. }
  824. return compilerImpl;
  825. }
  826. /**
  827. * The implementation for this particular task.
  828. *
  829. * <p>Defaults to the build.compiler property but can be overridden
  830. * via the compiler attribute.</p>
  831. *
  832. * <p>This method does not take the fork attribute into
  833. * account.</p>
  834. *
  835. * @see #getCompiler
  836. *
  837. * @since Ant 1.5
  838. */
  839. public String getCompilerVersion() {
  840. facade.setMagicValue(getProject().getProperty("build.compiler"));
  841. return facade.getImplementation();
  842. }
  843. /**
  844. * Check that all required attributes have been set and nothing
  845. * silly has been entered.
  846. *
  847. * @since Ant 1.5
  848. * @exception BuildException if an error occurs
  849. */
  850. protected void checkParameters() throws BuildException {
  851. if (src == null) {
  852. throw new BuildException("srcdir attribute must be set!",
  853. getLocation());
  854. }
  855. if (src.size() == 0) {
  856. throw new BuildException("srcdir attribute must be set!",
  857. getLocation());
  858. }
  859. if (destDir != null && !destDir.isDirectory()) {
  860. throw new BuildException("destination directory \""
  861. + destDir
  862. + "\" does not exist "
  863. + "or is not a directory", getLocation());
  864. }
  865. }
  866. /**
  867. * Perform the compilation.
  868. *
  869. * @since Ant 1.5
  870. */
  871. protected void compile() {
  872. String compilerImpl = getCompiler();
  873. if (compileList.length > 0) {
  874. log("Compiling " + compileList.length + " source file"
  875. + (compileList.length == 1 ? "" : "s")
  876. + (destDir != null ? " to " + destDir : ""));
  877. if (listFiles) {
  878. for (int i = 0; i < compileList.length; i++) {
  879. String filename = compileList[i].getAbsolutePath();
  880. log(filename);
  881. }
  882. }
  883. CompilerAdapter adapter =
  884. CompilerAdapterFactory.getCompiler(compilerImpl, this);
  885. // now we need to populate the compiler adapter
  886. adapter.setJavac(this);
  887. // finally, lets execute the compiler!!
  888. if (!adapter.execute()) {
  889. if (failOnError) {
  890. throw new BuildException(FAIL_MSG, getLocation());
  891. } else {
  892. log(FAIL_MSG, Project.MSG_ERR);
  893. }
  894. }
  895. }
  896. }
  897. /**
  898. * Adds an "compiler" attribute to Commandline$Attribute used to
  899. * filter command line attributes based on the current
  900. * implementation.
  901. */
  902. public class ImplementationSpecificArgument extends
  903. org.apache.tools.ant.util.facade.ImplementationSpecificArgument {
  904. /**
  905. * @param impl the name of the compiler
  906. */
  907. public void setCompiler(String impl) {
  908. super.setImplementation(impl);
  909. }
  910. }
  911. }