Clojure编译的起点
Clojure项目可以使用maven编译,从maven的配置看,是通过maven-antrun-plugin
插件触发的Clojure官方库编译。
- pom.xml
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>clojure-compile</id>
<phase>compile</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<property name="maven.compile.classpath" refid="maven.compile.classpath" />
<ant target="compile-clojure" />
</target>
</configuration>
</execution>
<execution>
<id>clojure-test</id>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<property name="maven.test.classpath" refid="maven.test.classpath" />
<ant target="test" />
</target>
</configuration>
</execution>
</executions>
</plugin>
这是一个执行ant命令的插件,实际执行了ant的compile-clojure
。
- build.xml
<target name="compile-clojure"
description="Compile Clojure sources.">
<java classname="clojure.lang.Compile"
classpath="${maven.compile.classpath}:${build}:${cljsrc}"
failonerror="true"
fork="true">
<sysproperty key="clojure.compile.path" value="${build}"/>
<!--<sysproperty key="clojure.compiler.elide-meta" value="[:doc :file :line :added]"/>-->
<!--<sysproperty key="clojure.compiler.disable-locals-clearing" value="true"/>-->
<!--<sysproperty key="clojure.compile.warn-on-reflection" value="true"/>-->
<sysproperty key="clojure.compiler.direct-linking" value="true"/>
<sysproperty key="java.awt.headless" value="true"/>
<arg value="clojure.core"/>
<arg value="clojure.core.protocols"/>
<arg value="clojure.core.server"/>
<arg value="clojure.main"/>
<arg value="clojure.set"/>
<arg value="clojure.edn"/>
<arg value="clojure.xml"/>
<arg value="clojure.zip"/>
<arg value="clojure.inspector"/>
<arg value="clojure.walk"/>
<arg value="clojure.stacktrace"/>
<arg value="clojure.template"/>
<arg value="clojure.test"/>
<arg value="clojure.test.tap"/>
<arg value="clojure.test.junit"/>
<arg value="clojure.pprint"/>
<arg value="clojure.java.io"/>
<arg value="clojure.repl"/>
<arg value="clojure.java.browse"/>
<arg value="clojure.java.javadoc"/>
<arg value="clojure.java.shell"/>
<arg value="clojure.java.browse-ui"/>
<arg value="clojure.string"/>
<arg value="clojure.data"/>
<arg value="clojure.reflect"/>
<arg value="clojure.datafy"/>
<arg value="clojure.instant"/>
<arg value="clojure.uuid"/>
<arg value="clojure.core.reducers"/>
<arg value="clojure.math"/>
</java>
</target>
可见最终调用了java类clojure.lang.Compile
的main
方法执行了编译,同时在classpath
配置了clojure.compile.path
作为Clojure编译器的输出目录,并将需要编译的Clojure官方库需要编译的namespace通过main
方法传入
- Compile.java
public static void main(String[] args) throws IOException, ClassNotFoundException{
RT.init();
OutputStreamWriter out = (OutputStreamWriter) RT.OUT.deref();
PrintWriter err = RT.errPrintWriter();
String path = System.getProperty(PATH_PROP);
int count = args.length;
if(path == null)
{
err.println("ERROR: Must set system property " + PATH_PROP +
"\nto the location for compiled .class files." +
"\nThis directory must also be on your CLASSPATH.");
System.exit(1);
}
boolean warnOnReflection = System.getProperty(REFLECTION_WARNING_PROP, "false").equals("true");
String uncheckedMathProp = System.getProperty(UNCHECKED_MATH_PROP);
Object uncheckedMath = Boolean.FALSE;
if("true".equals(uncheckedMathProp))
uncheckedMath = Boolean.TRUE;
else if("warn-on-boxed".equals(uncheckedMathProp))
uncheckedMath = Keyword.intern("warn-on-boxed");
// force load to avoid transitive compilation during lazy load
RT.load("clojure/core/specs/alpha");
try
{
Var.pushThreadBindings(RT.map(compile_path, path,
warn_on_reflection, warnOnReflection,
unchecked_math, uncheckedMath));
for(String lib : args)
{
out.write("Compiling " + lib + " to " + path + "\n");
out.flush();
compile.invoke(Symbol.intern(lib));
}
}
finally
{
Var.popThreadBindings();
try
{
out.flush();
}
catch(IOException e)
{
e.printStackTrace(err);
}
}
}
网友评论