/
IkvmMavenMojo.java
194 lines (163 loc) · 6.88 KB
/
IkvmMavenMojo.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
//
// ikvm-maven-plugin - generates C# DLL from Java code via IKVM
// http://github.com/samskivert/ikvm-maven-plugin/blob/master/LICENSE
package com.samskivert;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.codehaus.plexus.util.cli.CommandLineException;
import org.codehaus.plexus.util.cli.CommandLineUtils;
import org.codehaus.plexus.util.cli.Commandline;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
/**
* Goal which generates an IKVM dll containing all the jars on the classpath.
*
* @goal ikvm
* @phase package
*/
public class IkvmMavenMojo extends AbstractMojo
{
/**
* Location of the IKVM installation.
* @parameter expression="${ikvm.path}"
*/
public File ikvmPath;
/**
* The location of the Mono standard library DLLs.
* @parameter expression="${mono.path}" default-value="/Developer/MonoTouch/usr/lib/mono/2.1"
*/
public File monoPath;
/**
* Additional arguments to pass to IKVM.
* @parameter
*/
public List<String> ikvmArgs;
/**
* Additional DLLs (beyond mscorlib, System and System.Core) to reference. These can be
* absoulte paths, or relative to {@ocde monoPath}.
* @parameter
*/
public List<String> dlls;
/**
* The local repository to use when resolving dependencies.
* @parameter default-value="${localRepository}"
*/
public ArtifactRepository localRepository;
public void execute () throws MojoExecutionException {
if (ikvmPath == null) {
getLog().warn("ikvm.path is not set. Skipping IKVM build.");
return;
}
// sanity checks
if (!monoPath.isDirectory()) {
throw new MojoExecutionException(
"mono.path refers to non- or non-existent directory: " + monoPath);
}
if (!ikvmPath.isDirectory()) {
throw new MojoExecutionException(
"ikvm.path refers to non- or non-existent directory: " + monoPath);
}
File ikvmc = new File(new File(ikvmPath, "bin"), "ikvmc.exe");
if (!ikvmc.exists()) {
throw new MojoExecutionException("Unable to find ikmvc at: " + ikvmc);
}
// resolve the (non-test) jar dependencies, all of which we'll include in our DLL
List<File> depends = new ArrayList<File>();
try {
Set artifacts = _project.createArtifacts(_factory, null, null);
// ArtifactFilter filter = ...
ArtifactResolutionResult arr = _resolver.resolveTransitively(
artifacts, _project.getArtifact(), _project.getManagedVersionMap(), localRepository,
_project.getRemoteArtifactRepositories(), _metadataSource);
for (Object art : arr.getArtifacts()) {
Artifact artifact = (Artifact)art;
if (!artifact.getScope().equals(Artifact.SCOPE_TEST)) {
depends.add(artifact.getFile());
}
}
} catch (Exception e) {
throw new MojoExecutionException("Failed to resolve dependencies.", e);
}
// create a command that executes mono on ikvmc.exe
Commandline cli = new Commandline("mono");
File ikvmcExe = new File(new File(ikvmPath, "bin"), "ikvmc.exe");
cli.createArgument().setValue(ikvmcExe.getAbsolutePath());
// add our standard args
List<String> stdArgs = new ArrayList<String>();
stdArgs.add("-nostdlib");
stdArgs.add("-target:library");
for (String arg : stdArgs) {
cli.createArgument().setValue(arg);
}
// add our user defined args (making sure they don't duplicate stdargs)
for (String arg : ikvmArgs) {
if (stdArgs.contains(arg)) continue;
if (arg.startsWith("-out:")) {
getLog().warn("Don't specify -out:file directly. Set project.build.directory " +
"and project.build.finalName in your POM.");
continue;
}
cli.createArgument().setValue(arg);
}
// add our output file
String outname = _project.getBuild().getFinalName() + ".dll";
File outfile = new File(new File(_project.getBuild().getDirectory()), outname);
cli.createArgument().setValue("-out:" + outfile.getAbsolutePath());
// set the MONO_PATH envvar
cli.addEnvironment("MONO_PATH", monoPath.getAbsolutePath());
// add our standard DLLs
List<String> stdDlls = new ArrayList<String>();
stdDlls.add("mscorlib.dll");
stdDlls.add("System.dll");
stdDlls.add("System.Core.dll");
for (String dll : stdDlls) {
cli.createArgument().setValue("-r:" + new File(monoPath, dll).getAbsolutePath());
}
// add our DLLs
for (String dll : dlls) {
if (stdDlls.contains(dll)) continue;
if (new File(dll).isAbsolute()) {
cli.createArgument().setValue("-r:" + dll);
} else {
cli.createArgument().setValue("-r:" + new File(monoPath, dll).getAbsolutePath());
}
}
// add our jar files
for (File depend : depends) {
cli.createArgument().setValue(depend.getAbsolutePath());
}
// log our full command for great debuggery
getLog().debug("CMD: " + cli);
CommandLineUtils.StringStreamConsumer stdoutC = new CommandLineUtils.StringStreamConsumer();
CommandLineUtils.StringStreamConsumer stderrC = new CommandLineUtils.StringStreamConsumer();
try {
int rv = CommandLineUtils.executeCommandLine(cli, null, stdoutC, stderrC);
String stdout = stdoutC.getOutput();
if (stdout != null && stdout.length() > 0) getLog().info(stdout);
String stderr = stderrC.getOutput();
if (stderr != null && stderr.length() > 0) getLog().warn(stderr);
if (rv != 0) {
throw new MojoExecutionException("ikvmc.exe failed; see above output.");
}
} catch (CommandLineException clie) {
throw new MojoExecutionException("Executing ikvmc.exe failed", clie);
}
}
/** @parameter default-value="${project}" */
private MavenProject _project;
/** @component */
private ArtifactResolver _resolver;
/** @component */
private ArtifactMetadataSource _metadataSource;
/** @component */
private ArtifactFactory _factory;
}