1 /* |
1 /* |
2 * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies). |
2 * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies). |
3 * All rights reserved. |
3 * All rights reserved. |
4 * This component and the accompanying materials are made available |
4 * This component and the accompanying materials are made available |
5 * under the terms of the License "Eclipse Public License v1.0" |
5 * under the terms of the License "Eclipse Public License v1.0" |
6 * which accompanies this distribution, and is available |
6 * which accompanies this distribution, and is available |
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
8 * |
8 * |
9 * Initial Contributors: |
9 * Initial Contributors: |
10 * Nokia Corporation - initial contribution. |
10 * Nokia Corporation - initial contribution. |
11 * |
11 * |
12 * Contributors: |
12 * Contributors: |
13 * |
13 * |
14 * Description: |
14 * Description: |
15 * |
15 * |
16 */ |
16 */ |
17 package com.nokia.helium.imaker.ant.engines; |
17 package com.nokia.helium.imaker.ant.engines; |
18 |
18 |
19 import java.io.File; |
19 import java.io.File; |
|
20 import java.io.FileNotFoundException; |
20 import java.io.FileOutputStream; |
21 import java.io.FileOutputStream; |
21 import java.io.IOException; |
22 import java.io.IOException; |
22 import java.io.FileNotFoundException; |
|
23 import java.io.OutputStreamWriter; |
23 import java.io.OutputStreamWriter; |
24 import java.io.StringWriter; |
24 import java.io.StringWriter; |
25 import java.net.MalformedURLException; |
25 import java.net.MalformedURLException; |
26 import java.net.URL; |
26 import java.net.URL; |
27 import java.util.ArrayList; |
27 import java.util.ArrayList; |
45 import freemarker.template.Configuration; |
45 import freemarker.template.Configuration; |
46 import freemarker.template.Template; |
46 import freemarker.template.Template; |
47 import freemarker.template.TemplateException; |
47 import freemarker.template.TemplateException; |
48 |
48 |
49 /** |
49 /** |
50 * |
50 * |
51 * Simplest possible definition of the type, e.g: |
51 * Simplest possible definition of the type, e.g: |
|
52 * |
52 * <pre> |
53 * <pre> |
53 * <emakeEngine id="imaker.ec" /> |
54 * <emakeEngine id="imaker.ec" /> |
54 * </pre> |
55 * </pre> |
55 * |
56 * |
56 * Emake engine with some custom configuration. |
57 * Emake engine with some custom configuration. |
57 * <pre> |
58 * |
|
59 * <pre> |
58 * <emakeEngine id="imaker.ec" > |
60 * <emakeEngine id="imaker.ec" > |
59 * <arg value="--emake-annofile=imaker.anno.xml" /> |
61 * <arg value="--emake-annofile=imaker.anno.xml" /> |
60 * </emakeEngine> |
62 * </emakeEngine> |
61 * </pre> |
63 * </pre> |
62 * |
64 * |
63 * @ant.type name=emakeEngine category="imaker" |
65 * @ant.type name=emakeEngine category="imaker" |
64 */ |
66 */ |
65 public class EmakeEngine extends DataType implements Engine { |
67 public class EmakeEngine extends DataType implements Engine { |
66 private Logger log = Logger.getLogger(getClass()); |
68 private Logger log = Logger.getLogger(getClass()); |
67 private IMakerTask task; |
69 private IMakerTask task; |
68 private List<Arg> customArgs = new ArrayList<Arg>(); |
70 private List<Arg> customArgs = new ArrayList<Arg>(); |
69 private File template; |
71 private File template; |
70 |
72 |
71 /** |
73 /** |
72 * Holder for emake custom args. |
74 * Holder for emake custom args. |
73 */ |
75 */ |
74 public class Arg { |
76 public class Arg { |
75 private String value; |
77 private String value; |
76 |
78 |
77 /** |
79 /** |
78 * Get the value of the argument. |
80 * Get the value of the argument. |
|
81 * |
79 * @return the argument |
82 * @return the argument |
80 */ |
83 */ |
81 public String getValue() { |
84 public String getValue() { |
82 return value; |
85 return value; |
83 } |
86 } |
84 |
87 |
85 /** |
88 /** |
86 * Define the additional command line parameter you want to add to emake |
89 * Define the additional command line parameter you want to add to emake invocation. |
87 * invocation. |
90 * |
88 * @param value the additional command line parameter |
91 * @param value the additional command line parameter |
89 * @ant.required |
92 * @ant.required |
90 */ |
93 */ |
91 public void setValue(String value) { |
94 public void setValue(String value) { |
92 this.value = value; |
95 this.value = value; |
99 public void build(List<List<Command>> cmdSet) throws IMakerException { |
102 public void build(List<List<Command>> cmdSet) throws IMakerException { |
100 File makefile = null; |
103 File makefile = null; |
101 try { |
104 try { |
102 // Writing the makefile. |
105 // Writing the makefile. |
103 makefile = writeMakefile(cmdSet); |
106 makefile = writeMakefile(cmdSet); |
104 |
107 |
105 // Running Emake |
108 // Running Emake |
106 runEmake(makefile); |
109 runEmake(makefile); |
107 } finally { |
110 } |
|
111 finally { |
108 if (makefile != null) { |
112 if (makefile != null) { |
109 makefile.delete(); |
113 makefile.delete(); |
110 } |
114 } |
111 } |
115 } |
112 } |
116 } |
113 |
117 |
114 /** |
118 /** |
115 * Returns the jar file name containing this class |
119 * Returns the jar file name containing this class |
|
120 * |
116 * @return a File object or null if not found. |
121 * @return a File object or null if not found. |
117 * @throws IMakerException |
122 * @throws IMakerException |
118 */ |
123 */ |
119 protected File getJarFile() throws IMakerException { |
124 protected File getJarFile() throws IMakerException { |
120 URL url = this.getClass().getClassLoader().getResource(this.getClass().getName().replace('.', '/') + ".class"); |
125 URL url = this.getClass().getClassLoader().getResource(this.getClass().getName().replace('.', '/') |
|
126 + ".class"); |
121 if (url.getProtocol().equals("jar") && url.getPath().contains("!/")) { |
127 if (url.getProtocol().equals("jar") && url.getPath().contains("!/")) { |
122 String fileUrl = url.getPath().split("!/")[0]; |
128 String fileUrl = url.getPath().split("!/")[0]; |
123 try { |
129 try { |
124 return new File(new URL(fileUrl).getPath()); |
130 return new File(new URL(fileUrl).getPath()); |
125 } catch (MalformedURLException e) { |
131 } |
|
132 catch (MalformedURLException e) { |
126 throw new IMakerException("Error determining the jar file where " |
133 throw new IMakerException("Error determining the jar file where " |
127 + this.getClass().getName() + " is located.", e); |
134 + this.getClass().getName() + " is located.", e); |
128 } |
135 } |
129 } |
136 } |
130 return null; |
137 return null; |
131 } |
138 } |
|
139 |
132 /** |
140 /** |
133 * Run emake using defined makefile. |
141 * Run emake using defined makefile. |
|
142 * |
134 * @param makefile the makefile to build |
143 * @param makefile the makefile to build |
135 * @throws IMakerException |
144 * @throws IMakerException |
136 */ |
145 */ |
137 private void runEmake(File makefile) throws IMakerException { |
146 private void runEmake(File makefile) throws IMakerException { |
138 FileStreamConsumer output = null; |
147 FileStreamConsumer output = null; |
139 if (task.getOutput() != null) { |
148 if (task.getOutput() != null) { |
140 try { |
149 try { |
141 output = new FileStreamConsumer(task.getOutput()); |
150 output = new FileStreamConsumer(task.getOutput()); |
142 } catch (FileNotFoundException e) { |
151 } |
|
152 catch (FileNotFoundException e) { |
143 throw new IMakerException("Error creating the stream recorder: " + e.getMessage(), e); |
153 throw new IMakerException("Error creating the stream recorder: " + e.getMessage(), e); |
144 } |
154 } |
145 } |
155 } |
146 try { |
156 try { |
147 Emake emake = new Emake(); |
157 Emake emake = new Emake(); |
162 if (output != null) { |
172 if (output != null) { |
163 emake.addOutputLineHandler(output); |
173 emake.addOutputLineHandler(output); |
164 emake.addErrorLineHandler(output); |
174 emake.addErrorLineHandler(output); |
165 } |
175 } |
166 emake.execute(args.toArray(new String[args.size()])); |
176 emake.execute(args.toArray(new String[args.size()])); |
167 } catch (IMakerException e) { |
177 } |
|
178 catch (IMakerException e) { |
168 throw new IMakerException("Error executing emake: " + e.getMessage(), e); |
179 throw new IMakerException("Error executing emake: " + e.getMessage(), e); |
169 } finally { |
180 } |
|
181 finally { |
170 if (output != null) { |
182 if (output != null) { |
171 output.close(); |
183 output.close(); |
172 } |
184 } |
173 } |
185 } |
174 } |
186 } |
175 |
187 |
176 /** |
188 /** |
177 * Create the Makefile based on the cmdSet build sequence. |
189 * Create the Makefile based on the cmdSet build sequence. |
|
190 * |
178 * @param cmdSet |
191 * @param cmdSet |
179 * @return |
192 * @return |
180 * @throws IMakerException |
193 * @throws IMakerException |
181 * @throws IOException |
194 * @throws IOException |
182 */ |
195 */ |
183 private File writeMakefile(List<List<Command>> cmdSet) throws IMakerException { |
196 private File writeMakefile(List<List<Command>> cmdSet) throws IMakerException { |
184 try { |
197 try { |
185 Configuration cfg = new Configuration(); |
198 Configuration cfg = new Configuration(); |
186 Template template = null; |
199 Template template = null; |
187 if (this.template != null) { |
200 if (this.template != null) { |
188 if (!this.template.exists()) { |
201 if (!this.template.exists()) { |
189 throw new IMakerException("Could not find template file: " + this.template.getAbsolutePath()); |
202 throw new IMakerException("Could not find template file: " |
|
203 + this.template.getAbsolutePath()); |
190 } |
204 } |
191 task.log("Loading template: " + this.template.getAbsolutePath()); |
205 task.log("Loading template: " + this.template.getAbsolutePath()); |
192 cfg.setTemplateLoader(new FileTemplateLoader(this.template.getParentFile())); |
206 cfg.setTemplateLoader(new FileTemplateLoader(this.template.getParentFile())); |
193 template = cfg.getTemplate(this.template.getName()); |
207 template = cfg.getTemplate(this.template.getName()); |
194 } else { |
208 } |
|
209 else { |
195 cfg.setTemplateLoader(new ClassTemplateLoader(this.getClass(), "")); |
210 cfg.setTemplateLoader(new ClassTemplateLoader(this.getClass(), "")); |
196 template = cfg.getTemplate("build_imaker_roms_signing.mk.ftl"); |
211 template = cfg.getTemplate("build_imaker_roms_signing.mk.ftl"); |
197 } |
212 } |
198 File makefile = File.createTempFile("helium-imaker", ".mk", task.getEpocroot()); |
213 File makefile = File.createTempFile("helium-imaker", ".mk", task.getEpocroot()); |
199 makefile.deleteOnExit(); |
214 makefile.deleteOnExit(); |
202 data.put("cmdSets", cmdSet); |
217 data.put("cmdSets", cmdSet); |
203 data.put("makefile", makefile.getAbsoluteFile()); |
218 data.put("makefile", makefile.getAbsoluteFile()); |
204 data.put("java_home", System.getProperty("java.home")); |
219 data.put("java_home", System.getProperty("java.home")); |
205 File jar = getJarFile(); |
220 File jar = getJarFile(); |
206 if (jar != null) { |
221 if (jar != null) { |
207 task.log("Using " + jar + " as the utility container, make sure the file is available under an emake root."); |
222 task.log("Using " |
|
223 + jar |
|
224 + " as the utility container, make sure the file is available under an emake root."); |
208 data.put("java_utils_classpath", jar.getAbsolutePath()); |
225 data.put("java_utils_classpath", jar.getAbsolutePath()); |
209 } |
226 } |
210 template.process(data, out); |
227 template.process(data, out); |
211 log.debug(out.getBuffer().toString()); |
228 log.debug(out.getBuffer().toString()); |
212 |
229 |
213 OutputStreamWriter output = new OutputStreamWriter(new FileOutputStream(makefile)); |
230 OutputStreamWriter output = new OutputStreamWriter(new FileOutputStream(makefile)); |
214 output.append(out.getBuffer().toString()); |
231 output.append(out.getBuffer().toString()); |
215 output.close(); |
232 output.close(); |
216 return makefile; |
233 return makefile; |
217 } catch (IOException e) { |
234 } |
218 throw new IMakerException("Error generating the makefile: " + e.getMessage(), e); |
235 catch (IOException e) { |
219 } catch (TemplateException e) { |
236 throw new IMakerException("Error generating the makefile: " + e.getMessage(), e); |
220 throw new IMakerException("Error while rendering the makefile template: " + e.getMessage(), e); |
237 } |
221 } |
238 catch (TemplateException e) { |
222 } |
239 throw new IMakerException("Error while rendering the makefile template: " |
223 |
240 + e.getMessage(), e); |
|
241 } |
|
242 } |
|
243 |
224 /** |
244 /** |
225 * Add custom parameters for the emake invocation. |
245 * Add custom parameters for the emake invocation. |
|
246 * |
226 * @return a new Arg object. |
247 * @return a new Arg object. |
227 */ |
248 */ |
228 public Arg createArg() { |
249 public Arg createArg() { |
229 Arg arg = new Arg(); |
250 Arg arg = new Arg(); |
230 customArgs.add(arg); |
251 customArgs.add(arg); |
231 return arg; |
252 return arg; |
232 } |
253 } |
233 |
254 |
234 |
|
235 /** |
255 /** |
236 * {@inheritDoc} |
256 * {@inheritDoc} |
237 */ |
257 */ |
238 @Override |
258 @Override |
239 public void setTask(IMakerTask task) { |
259 public void setTask(IMakerTask task) { |
240 this.task = task; |
260 this.task = task; |
241 } |
261 } |
242 |
262 |
243 /** |
263 /** |
244 * Defines an alternate template to use to generate the build sequence for emake. |
264 * Defines an alternate template to use to generate the build sequence for emake. |
|
265 * |
245 * @ant.not-required |
266 * @ant.not-required |
246 */ |
267 */ |
247 public void setTemplate(File template) { |
268 public void setTemplate(File template) { |
248 this.template = template; |
269 this.template = template; |
249 } |
270 } |