1 /* 2 * #%L 3 * Native ARchive plugin for Maven 4 * %% 5 * Copyright (C) 2002 - 2014 NAR Maven Plugin developers. 6 * %% 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * #L% 19 */ 20 package com.github.maven_nar.cpptasks.ide; 21 22 import java.io.File; 23 import java.lang.reflect.Method; 24 import java.util.ArrayList; 25 import java.util.List; 26 import java.util.Map; 27 28 import org.apache.tools.ant.BuildException; 29 import org.apache.tools.ant.Project; 30 import org.apache.tools.ant.types.DataType; 31 32 import com.github.maven_nar.cpptasks.CCTask; 33 import com.github.maven_nar.cpptasks.CUtil; 34 import com.github.maven_nar.cpptasks.TargetInfo; 35 36 /** 37 * Requests the creation of an IDE project file. Experimental. 38 * 39 * Implementation status: msdev5, msdev6 and cbuilderx 40 * generate reasonable project files for simple projects, 41 * xcode and msdev7 and msdev71 capture source file lists and 42 * a few settings. 43 * 44 * @author Curt Arnold 45 */ 46 public final class ProjectDef extends DataType { 47 /** 48 * Name of property that must be present or definition will be ignored. May 49 * be null. 50 */ 51 private String ifProp; 52 53 /** 54 * Name of property that must be absent or definition will be ignored. May 55 * be null. 56 */ 57 private String unlessProp; 58 59 /** 60 * Project file name. 61 */ 62 private File outFile; 63 64 /** 65 * Project name. 66 */ 67 private String name; 68 69 /** 70 * Fail on error. 71 */ 72 private boolean failOnError = true; 73 74 /** 75 * Overwrite existing project file. 76 */ 77 private boolean overwrite = true; 78 79 /** 80 * Project writer. 81 */ 82 private ProjectWriter projectWriter; 83 84 /** 85 * Object directory. 86 * 87 */ 88 private File objDir; 89 90 /** 91 * List of dependency definitions. 92 */ 93 private final List<DependencyDef> dependencies = new ArrayList<>(); 94 95 /** 96 * List of comments. 97 */ 98 private final List<CommentDef> comments = new ArrayList<>(); 99 100 /** 101 * Constructor. 102 * 103 */ 104 public ProjectDef() { 105 } 106 107 /** 108 * Add comment for the generated project file. 109 * 110 * @param comment 111 * comment, may not be null. 112 */ 113 public void addComment(final CommentDef comment) { 114 this.comments.add(comment); 115 116 } 117 118 /** 119 * Add a dependency definition to the project. 120 * 121 * @param dependency 122 * dependency. 123 */ 124 public void addDependency(final DependencyDef dependency) { 125 this.dependencies.add(dependency); 126 127 } 128 129 /** 130 * Required by documentation generator. 131 */ 132 public void execute() { 133 throw new org.apache.tools.ant.BuildException("Not an actual task, but looks like one for documentation purposes"); 134 } 135 136 /** 137 * Executes the task. Compiles the given files. 138 * 139 * @param task 140 * cc task 141 * @param sources 142 * source files (includes headers) 143 * @param targets 144 * compilation targets 145 * @param linkTarget 146 * link target 147 */ 148 public void execute(final CCTask task, final List<File> sources, final Map<String, TargetInfo> targets, 149 final TargetInfo linkTarget) { 150 try { 151 this.projectWriter.writeProject(this.outFile, task, this, sources, targets, linkTarget); 152 } catch (final BuildException ex) { 153 if (this.failOnError) { 154 throw ex; 155 } else { 156 task.log(ex.toString()); 157 } 158 } catch (final Exception ex) { 159 if (this.failOnError) { 160 throw new BuildException(ex); 161 } else { 162 task.log(ex.toString()); 163 } 164 } 165 } 166 167 public List<CommentDef> getComments() { 168 return new ArrayList<>(this.comments); 169 } 170 171 public List<DependencyDef> getDependencies() { 172 return new ArrayList<>(this.dependencies); 173 } 174 175 /** 176 * Get name. 177 * 178 * @return String name 179 */ 180 public String getName() { 181 return this.name; 182 } 183 184 /** 185 * Gets the object files directory. 186 * 187 * @return directory, may be null. 188 */ 189 public File getObjdir() { 190 return this.objDir; 191 } 192 193 /** 194 * Sets the directory used for object files. If not specified, 195 * the object files directory from cc task will be used. 196 * 197 * @param oDir 198 * object file directory. 199 */ 200 public void getObjdir(final File oDir) { 201 this.objDir = oDir; 202 } 203 204 /** 205 * Gets whether an existing project file should be overwritten, 206 * default is true. If false and the project file exists, 207 * the value of failonerror will determine if the task fails. 208 * 209 * @return value 210 */ 211 public boolean getOverwrite() { 212 return this.overwrite; 213 } 214 215 /** 216 * Determine if this def should be used. 217 * 218 * Definition will be active if the "if" variable (if specified) is set and 219 * the "unless" variable (if specified) is not set and that all reference 220 * or extended definitions are active 221 * 222 * @return true if processor is active 223 */ 224 public boolean isActive() { 225 final Project project = getProject(); 226 if (!CUtil.isActive(project, this.ifProp, this.unlessProp)) { 227 return false; 228 } 229 return true; 230 } 231 232 /** 233 * Class name for a user-supplied project writer. Use the "type" 234 * attribute to specify built-in project writer implementations. 235 * 236 * @param className 237 * full class name 238 * 239 */ 240 public void setClassname(final String className) { 241 Object proc = null; 242 try { 243 final Class<?> implClass = ProjectDef.class.getClassLoader().loadClass(className); 244 try { 245 final Method getInstance = implClass.getMethod("getInstance"); 246 proc = getInstance.invoke(null); 247 } catch (final Exception ex) { 248 proc = implClass.newInstance(); 249 } 250 } catch (final Exception ex) { 251 throw new BuildException(ex); 252 } 253 this.projectWriter = (ProjectWriter) proc; 254 } 255 256 /** 257 * Sets whether a failure to write the project file should cause the 258 * task to fail. Default is true. 259 * 260 * @param value 261 * new value 262 */ 263 public void setFailonerror(final boolean value) { 264 this.failOnError = value; 265 } 266 267 /** 268 * Sets the property name for the 'if' condition. 269 * 270 * The configuration will be ignored unless the property is defined. 271 * 272 * The value of the property is insignificant, but values that would imply 273 * misinterpretation ("false", "no") will throw an exception when 274 * evaluated. 275 * 276 * @param propName 277 * name of property 278 */ 279 public void setIf(final String propName) { 280 this.ifProp = propName; 281 } 282 283 /** 284 * Set name. 285 * 286 * @param value 287 * String name 288 */ 289 public void setName(final String value) { 290 this.name = value; 291 } 292 293 /** 294 * Sets the name for the generated project file. 295 * 296 * @param outfile 297 * output file name 298 */ 299 public void setOutfile(final File outfile) { 300 // 301 // if file name was empty, skip link step 302 // 303 if (outfile == null || outfile.toString().length() > 0) { 304 this.outFile = outfile; 305 } 306 } 307 308 /** 309 * Sets whether an existing project file should be overwritten, 310 * default is true. If false and the project file exists, 311 * the value of failonerror will determine if the task fails. 312 * 313 * @param value 314 * new value 315 */ 316 public void setOverwrite(final boolean value) { 317 this.overwrite = value; 318 } 319 320 /** 321 * Set project type. 322 * 323 * 324 * <table width="100%" border="1"> 325 * <thead>Supported project formats </thead> 326 * <tr> 327 * <td>cbuilderx</td> 328 * <td>Borland C++BuilderX</td> 329 * </tr> 330 * <tr> 331 * <td>msvc5</td> 332 * <td>Microsoft Visual C++ 97</td> 333 * </tr> 334 * <tr> 335 * <td>msvc6</td> 336 * <td>Microsoft Visual C++ 6</td> 337 * </tr> 338 * <tr> 339 * <td>msvc7</td> 340 * <td>Microsoft Visual C++.NET</td> 341 * </tr> 342 * <tr> 343 * <td>msvc71</td> 344 * <td>Microsoft Visual C++.NET 2003</td> 345 * </tr> 346 * <tr> 347 * <td>msvc8</td> 348 * <td>Microsoft Visual C++ 2005</td> 349 * </tr> 350 * <tr> 351 * <td>msvc9</td> 352 * <td>Microsoft Visual C++ 2008</td> 353 * </tr> 354 * <tr> 355 * <td>xcode</td> 356 * <td>Apple Xcode</td> 357 * </tr> 358 * </table> 359 * 360 * @param value 361 * new value 362 */ 363 public void setType(final ProjectWriterEnum value) { 364 this.projectWriter = value.getProjectWriter(); 365 } 366 367 /** 368 * Set the property name for the 'unless' condition. 369 * 370 * If named property is set, the configuration will be ignored. 371 * 372 * The value of the property is insignificant, but values that would imply 373 * misinterpretation ("false", "no") of the behavior will throw an 374 * exception when evaluated. 375 * 376 * @param propName 377 * name of property 378 */ 379 public void setUnless(final String propName) { 380 this.unlessProp = propName; 381 } 382 383 }