1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.github.maven_nar;
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.Iterator;
25 import java.util.LinkedList;
26 import java.util.List;
27
28 import org.apache.maven.artifact.Artifact;
29 import org.apache.maven.model.Profile;
30 import org.apache.maven.plugin.MojoExecutionException;
31 import org.apache.maven.plugin.MojoFailureException;
32 import org.apache.maven.plugins.annotations.LifecyclePhase;
33 import org.apache.maven.plugins.annotations.Mojo;
34 import org.apache.maven.plugins.annotations.ResolutionScope;
35 import org.apache.maven.shared.artifact.filter.collection.ScopeFilter;
36 import org.apache.tools.ant.BuildException;
37 import org.apache.tools.ant.Project;
38
39 import com.github.maven_nar.cpptasks.CCTask;
40 import com.github.maven_nar.cpptasks.CUtil;
41 import com.github.maven_nar.cpptasks.CompilerDef;
42 import com.github.maven_nar.cpptasks.LinkerDef;
43 import com.github.maven_nar.cpptasks.OutputTypeEnum;
44 import com.github.maven_nar.cpptasks.RuntimeType;
45 import com.github.maven_nar.cpptasks.SubsystemEnum;
46 import com.github.maven_nar.cpptasks.ide.ProjectDef;
47 import com.github.maven_nar.cpptasks.ide.ProjectWriterEnum;
48 import com.github.maven_nar.cpptasks.types.DefineArgument;
49 import com.github.maven_nar.cpptasks.types.DefineSet;
50 import com.github.maven_nar.cpptasks.types.LibrarySet;
51 import com.github.maven_nar.cpptasks.types.LinkerArgument;
52 import com.github.maven_nar.cpptasks.types.SystemLibrarySet;
53
54
55
56
57
58
59
60
61 @Mojo(name = "nar-vcproj", defaultPhase = LifecyclePhase.GENERATE_RESOURCES,
62 requiresDependencyResolution = ResolutionScope.COMPILE)
63 public class NarVcprojMojo extends AbstractCompileMojo {
64
65
66 private void createVcProjFile(final Project antProject, final Library library)
67 throws MojoExecutionException, MojoFailureException {
68
69
70 final CCTask task = new CCTask();
71 task.setProject(antProject);
72 task.setDebug(true);
73
74
75 final SubsystemEnum subSystem = new SubsystemEnum();
76 subSystem.setValue(library.getSubSystem());
77 task.setSubsystem(subSystem);
78
79
80 final OutputTypeEnum outTypeEnum = new OutputTypeEnum();
81 final String type = library.getType();
82 outTypeEnum.setValue(type);
83 task.setOuttype(outTypeEnum);
84
85
86 task.setLinkCPP(library.linkCPP());
87
88
89
90
91 File outDir = new File(getTargetDirectory(), "bin");
92 outDir = new File(outDir, getAOL().toString());
93 outDir.mkdirs();
94
95
96 final File outFile = new File(outDir, getOutput(getAOL(), type));
97
98 getLog().debug("NAR - output: '" + outFile + "'");
99 task.setOutfile(outFile);
100
101
102 File objDir = new File(getTargetDirectory(), "obj");
103 objDir = new File(objDir, getAOL().toString());
104 objDir.mkdirs();
105 task.setObjdir(objDir);
106
107
108 task.setFailonerror(failOnError(getAOL()));
109 task.setLibtool(useLibtool(getAOL()));
110
111
112 final RuntimeType runtimeType = new RuntimeType();
113 runtimeType.setValue(getRuntime(getAOL()));
114 task.setRuntime(runtimeType);
115
116
117 final CompilerDef cpp = getCpp().getCompiler(Compiler.MAIN, null);
118 if (cpp != null) {
119 task.addConfiguredCompiler(cpp);
120 }
121
122
123
124 final DefineSet defineSet = new DefineSet();
125 final DefineArgument defineArgument = new DefineArgument();
126 defineArgument.setName("VCPROJ_MOJO");
127 defineSet.addDefine(defineArgument);
128 cpp.addConfiguredDefineset(defineSet);
129
130
131 final File jniDirectory = getJavah().getJniDirectory();
132 if (jniDirectory.exists()) {
133 task.createIncludePath().setPath(jniDirectory.getPath());
134 }
135
136
137 getJava().addIncludePaths(task, Library.EXECUTABLE);
138
139 getMsvc().configureCCTask(task);
140
141 final List<NarArtifact> dependencies = getNarArtifacts();
142
143 for (final Object element : dependencies) {
144
145 final NarArtifact narDependency = (NarArtifact) element;
146 final String binding = narDependency.getNarInfo().getBinding(getAOL(), Library.STATIC);
147 getLog().debug("Looking for " + narDependency + " found binding " + binding);
148 if (!binding.equals(Library.JNI)) {
149 final File unpackDirectory = getUnpackDirectory();
150 final File include = getLayout().getIncludeDirectory(unpackDirectory, narDependency.getArtifactId(),
151 narDependency.getBaseVersion());
152 getLog().debug("Looking for directory: " + include);
153 if (include.exists()) {
154 task.createIncludePath().setPath(include.getPath());
155 } else {
156 getLog().warn(String.format("Unable to locate %1$s lib include path '%2$s'", binding, include));
157 }
158 }
159 }
160
161
162 final LinkerDef linkerDefinition = getLinker().getLinker(this, task, getOS(), getAOL().getKey() + ".linker.",
163 type);
164 task.addConfiguredLinker(linkerDefinition);
165
166
167
168
169 if (type.equals(Library.SHARED) || type.equals(Library.JNI) || type.equals(Library.EXECUTABLE)) {
170
171 final List depLibOrder = getDependencyLibOrder();
172 List depLibs = dependencies;
173
174
175
176 if (depLibOrder != null && !depLibOrder.isEmpty()) {
177
178 final List tmp = new LinkedList();
179
180 for (final Object aDepLibOrder : depLibOrder) {
181
182 final String depToOrderName = (String) aDepLibOrder;
183
184 for (final Iterator j = depLibs.iterator(); j.hasNext(); ) {
185
186 final NarArtifact dep = (NarArtifact) j.next();
187 final String depName = dep.getGroupId() + ":" + dep.getArtifactId();
188
189 if (depName.equals(depToOrderName)) {
190
191 tmp.add(dep);
192 j.remove();
193 }
194 }
195 }
196
197 tmp.addAll(depLibs);
198 depLibs = tmp;
199 }
200
201 for (final Object depLib : depLibs) {
202
203 final NarArtifact dependency = (NarArtifact) depLib;
204
205
206
207
208 final String binding = dependency.getNarInfo().getBinding(getAOL(), Library.STATIC);
209 getLog().debug("Using Binding: " + binding);
210 AOL aol = getAOL();
211 aol = dependency.getNarInfo().getAOL(getAOL());
212 getLog().debug("Using Library AOL: " + aol.toString());
213
214 if (!binding.equals(Library.JNI) && !binding.equals(Library.NONE) && !binding.equals(Library.EXECUTABLE)) {
215 final File unpackDirectory = getUnpackDirectory();
216 final File dir = getLayout()
217 .getLibDirectory(unpackDirectory, dependency.getArtifactId(), dependency.getBaseVersion(), aol.toString(),
218 binding);
219 getLog().debug("Looking for Library Directory: " + dir);
220 if (dir.exists()) {
221 final LibrarySet libSet = new LibrarySet();
222 libSet.setProject(antProject);
223
224
225 final String libs = dependency.getNarInfo().getLibs(getAOL());
226 if (libs != null && !libs.equals("")) {
227 getLog().debug("Using LIBS = " + libs);
228 libSet.setLibs(new CUtil.StringArrayBuilder(libs));
229 libSet.setDir(dir);
230 task.addLibset(libSet);
231 }
232 } else {
233 getLog().debug("Library Directory " + dir + " does NOT exist.");
234 }
235
236
237
238 final String options = dependency.getNarInfo().getOptions(getAOL());
239 if (options != null && !options.equals("")) {
240 getLog().debug("Using OPTIONS = " + options);
241 final LinkerArgument arg = new LinkerArgument();
242 arg.setValue(options);
243 linkerDefinition.addConfiguredLinkerArg(arg);
244 }
245
246 final String sysLibs = dependency.getNarInfo().getSysLibs(getAOL());
247
248 if (sysLibs != null && !sysLibs.equals("")) {
249 getLog().debug("Using SYSLIBS = " + sysLibs);
250 final SystemLibrarySet sysLibSet = new SystemLibrarySet();
251 sysLibSet.setProject(antProject);
252
253 sysLibSet.setLibs(new CUtil.StringArrayBuilder(sysLibs));
254
255 task.addSyslibset(sysLibSet);
256 }
257 }
258 }
259
260
261 getJava().addRuntime(task, getJavaHome(getAOL()), getOS(), getAOL().getKey() + "java.");
262
263
264 getLog().debug("NAR: Writing project file...");
265 final ProjectWriterEnum projectWriterEnum = new ProjectWriterEnum();
266 projectWriterEnum.setValue("msvc8");
267 final ProjectDef projectDef = new ProjectDef();
268 projectDef.setType(projectWriterEnum);
269 String filename = null;
270 try {
271 final File outputDir = new File(getTargetDirectory(), "vcproj");
272 if (!outputDir.exists()) {
273 final boolean succeeded = outputDir.mkdir();
274 if (!succeeded) {
275 throw new MojoExecutionException("Unable to create directory: " + outputDir);
276 }
277 }
278 filename = outputDir + "/" + getMavenProject().getArtifactId();
279 final File projFile = new File(filename);
280 projectDef.setOutfile(projFile.getCanonicalFile());
281 } catch (final IOException e) {
282 throw new MojoExecutionException("Unable to create file: " + filename, e);
283 }
284 task.addProject(projectDef);
285 task.setProjectsOnly(true);
286
287
288 task.setOuttype(new OutputTypeEnum());
289
290
291 try {
292 task.execute();
293 getLog().info("Wrote project file: " + filename + ".vcproj");
294 } catch (final BuildException e) {
295 throw new MojoExecutionException("NAR: Compile failed", e);
296 }
297 }
298 }
299
300
301
302
303
304
305 @Override
306 protected ScopeFilter getArtifactScopeFilter() {
307 return new ScopeFilter( Artifact.SCOPE_COMPILE, null );
308 }
309
310 @Override
311 public void narExecute() throws MojoExecutionException, MojoFailureException {
312
313
314 if (!getOS().equals(OS.WINDOWS)) {
315 getLog().debug("Skipping -- not running on Windows");
316 return;
317 }
318
319
320
321 boolean debug = false;
322
323 final List profiles = NarUtil.collectActiveProfiles(getMavenProject());
324 for (final Object profile1 : profiles) {
325 final Profile profile = (Profile) profile1;
326 if (profile.getId().equalsIgnoreCase("windows-debug")) {
327 debug = true;
328 break;
329 }
330 }
331
332 if (!debug) {
333 getLog().info("NAR: Skipping vcproj generation. Run with -P windows-debug to enable this step.");
334 return;
335 }
336
337 if (getLibraries().isEmpty()) {
338 getLog().info("NAR: Skipping vcproj generation. No libraries to be built.");
339 return;
340 }
341
342
343
344
345
346 createVcProjFile(getAntProject(), getLibraries().get(0));
347 }
348 }