DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world
A Pure-Java Alternative To 'make' Or 'ANT'
import java.io.*;
import java.util.*;
import java.util.concurrent.*;
/**
* A simple project build routine.
* I hate makefiles, and ANT uses the horrid XML so I'm doing this hack
* instead. Actually, I've used this technique before to great success. I
* ought to make a Real Project out of it someday.
*
* What you see is the 'guts' of make/ANT PLUS the project file dependencies
* at the end - all in pure Java. Thus I can add new features to the make
* (parallel distributed make, shared caching, etc) or add new dependencies.
* Especially for the dependencies, there is no obtuse format to describe
* things - it's all pure Java.
*
* TO DO LIST:
*
* Parallize Yea Olde Above Priority Queue across the Build Farm
* FindBugz nitpicky
*
* Priorities -
* 1) Things that failed for syntax errors last time; under the assumption
* you're working in a tight edit/compile cycle anything that failed in the
* last go-round should be compiled first this go-round - because you
* probably don't have all the syntax errors out yet. This is very useful
* when hacking top-level includes like thread.hpp, because each touch of
* thread.hpp will force the World to recompile but likely there's exactly
* .cpp file you care about (thread.cpp?) and it's usually very late in the
* build. One easy way to do this is to notice that failed build steps
* always nuke their target, so a missing target is most likely came from a
* syntax error on the last edit/compile cycle.
*
* 2) Jobs that might make more work - such as the ADLC or JVMTI or reading
* the foo.P files; each of these steps might possibly make more targets to
* build. Thus the priority queue has to be dynamic; some targets appear
* only after some build-steps have happened.
*
* 3) Slow jobs; waiting to the end of a 200-file compile to START compiling
* 'type.cpp' just lengthens the build cycle. type.cpp probably takes more
* than 60sec to compile whereas most jobs compile less than 5sec. We want
* to overlap the compile of type.cpp with many other compiles.
*
* @since 1.6
* @author Cliff Click
*/
class build {
static int _verbose; // Be noisy; 0 (quiet), 1 (noisy) or 2 (very noisy)
static boolean _justprint; // Print, do not do any building
static boolean _clean; // Remove target instead of building it
static boolean _keepontrucking; // Do not stop at errors
// Top-level project directory
static File TOP; // File for the project directory
static String TOP_PATH; // Path to top-level
static String TOP_PATH_SLASH;
// Where the results go
static String SANDBOX;
// Pick up JAVA_HOME from the java property "java.home"
static String JAVA_HOME;
// --- main ----------------------------------------------------------------
static public void main( final String args[] ) throws IOException, InterruptedException {
// --- First up: find build.java!
// Where we exec'd java.exe from
TOP = new File(".");
TOP_PATH = TOP.getCanonicalPath();
File f = new File(TOP,"build/build.java");
while( !f.exists() ) {
File p2 = new File(TOP,"..");
if( p2.getCanonicalPath().equals(TOP_PATH) )
throw new Error("build/build.java not found; build/build.java marks top of project hierarchy");
TOP = p2;
TOP_PATH = TOP.getCanonicalPath();
f = new File(TOP,"build/build.java");
}
TOP_PATH_SLASH = TOP_PATH.replaceAll("\\\\","\\\\\\\\");
// --- Track down default sandbox
File sand = TOP;
f = new File(sand,"sandbox");
while( !f.exists() ) {
File p2 = new File(sand,"..");
String spath = sand.getCanonicalPath();
if( p2.getCanonicalPath().equals(spath) )
break; // No sandbox found
sand = p2;
f = new File(sand,"sandbox");
}
if( f.exists() ) SANDBOX = f.getCanonicalPath();
JAVA_HOME = System.getProperty("java.home");
if (JAVA_HOME.endsWith("/jre")) {
JAVA_HOME = JAVA_HOME.substring(0, JAVA_HOME.lastIndexOf('/'));
}
// --- Strip out any flags; sanity check all targets before doing any of them
int j = 0;
boolean error = false;
String coreOrJIT = "jit";
String targetPlatform = null;
String buildvariant = null;
String g_suffix = "";
for( int i=0; i<args.length; i++ ) {
final String arg = args[i];
if( arg.charAt(0) == '-' ) {
if( false ) ;
else if( arg.equals("-v" ) ) _verbose = 1;
else if( arg.equals("-vv" ) ) _verbose = 2;
else if( arg.equals("-n" ) ) _justprint = true;
else if( arg.equals("-k" ) ) _keepontrucking = true;
else if( arg.equals("-clean") ) _clean = true;
else if( arg.equals("-s" ) ) SANDBOX = args[++i];
else if( arg.equals("-t" ) ) targetPlatform = args[++i];
else if( arg.equals("-core" ) ) coreOrJIT = "core";
else if( arg.equals("-jit" ) ) coreOrJIT = "jit";
else {
error = true;
System.out.println("Unknown flag "+arg);
}
} else if( arg.equals("debug") || arg.equals("fastdebug") ) {
buildvariant = arg;
g_suffix = "_g";
} else if( arg.equals("optimized") || arg.equals("product") ) {
buildvariant = arg;
} else {
args[j++] = arg; // Compact out flags from target list
}
}
if (targetPlatform != null) {
if (targetPlatform.equals("aztek-vega2")) {
args[j++] = "sandbox/obj/hotspot6/aztek_vega2_" + coreOrJIT + "1.6/" + buildvariant + "/libjvm" + g_suffix + ".a";
} else if (targetPlatform.equals("acapulco-nxu")) {
args[j++] = "sandbox/obj/hotspot6/acapulco_nxu_" + coreOrJIT + "1.6/" + buildvariant + "/libjvm" + g_suffix + ".a";
} else {
throw new Error("Unknown target platform specified with -t");
}
if (_verbose > 0) {
System.out.println("Target is " + args[j-1]);
}
}
try {
if( error ) {
System.out.println("");
System.out.println("Usage: build [-v|-vv] [-n] [-k] [-clean] [-s SANDBOX] [-t PLATFORM] [-core|-jit] [debug|fastdebug|optimized|product]");
System.out.println("\t -v : verbose output, overrides -vv option");
System.out.println("\t -vv : super verbose output, overrides -v option");
System.out.println("\t -n : do nothing, just print");
System.out.println("\t -k : don't stop on errors");
System.out.println("\t -clean : delete build output");
System.out.println("\t -s SANDBOX : set SANDBOX directory");
System.out.println("\t -t PLATFORM : set target platform");
System.out.println("\t -core : build the \"core\" target, overrides -jit option");
System.out.println("\t -jit : build the \"jit\" target, overrides -core option");
System.out.println("");
throw new Error("Command line errors");
}
if( _verbose > 0 )
System.out.println("Building in "+TOP.getCanonicalPath());
if( SANDBOX == null )
throw new Error("No sandbox");
if( !SANDBOX.endsWith("/sandbox") )
throw new Error("Sandbox does not end with /sandbox");
if( !new File(SANDBOX).exists() )
throw new Error("Sandbox does not exist: "+SANDBOX);
// Make SANDBOX a relative path, if it's shorter. Much easier to read the output.
String t=TOP_PATH;
String up="";
while( !SANDBOX.startsWith(t) ) {
up = up+"../";
t = t.substring(0,t.lastIndexOf('/'));
}
SANDBOX = up+SANDBOX.substring(t.length()+1);
if( _verbose > 0 )
System.out.println("Sandbox is "+SANDBOX);
// Command-line targets starting with "sandbox/" are essentially
// shortcuts for "$SANDBOX/", but for our chosen SANDBOX not some OS
// environment variable.
for( int i=0; i<j; i++ )
if( args[i].startsWith("sandbox/") )
args[i] = SANDBOX+args[i].substring(7);
// --- Put all named targets into a bogus top-level target
if( j == 0 ) throw new Error("No default target and no targets specified; did you mean to build nothing?");
} finally {
// --- All Done!
System.out.flush();
System.err.flush();
}
build0.main0(Arrays.copyOf(args,j));
}
}
// --- build0 -------------------------------------------------------------------
class build0 {
static private class BuildError extends Error { BuildError( String s ) { super(s); } }
final static int _verbose = build._verbose; // Be noisy; 0 (quiet), 1 (noisy) or 2 (very noisy)
final static boolean _justprint = build._justprint; // Print, do not do any building
final static boolean _clean = build._clean; // Remove target instead of building it
final static boolean _keepontrucking = build._keepontrucking; // Do not stop at errors
final static boolean _allow_timestamp_ties = true;
// Top-level project directory
final static File TOP = build.TOP; // File for the project directory
final static String TOP_PATH = build.TOP_PATH; // Path to top-level
final static String TOP_PATH_SLASH = build.TOP_PATH_SLASH; // Canonical path to top level
// Where the results go
final static String SANDBOX = build.SANDBOX;
// Some common strings
static final String JAVA_HOME = build.JAVA_HOME;
static final String JAVAC = JAVA_HOME + "/bin/javac";
static final String JAVA = JAVA_HOME + "/bin/java";
// A work-queue for the Main thread. Tasks on this list need to have their
// dependencies inspected. This is normally once per task, but foo.P files
// run an "extra_check" which expands out a list of source .h file
// dependencies.
static final LinkedBlockingQueue<Q> _FindDeps = new LinkedBlockingQueue<Q>();
static final Q ALL_DONE_SENTINEL = new Q("no such target");
// The work queue
static final Runtime RUN = Runtime.getRuntime();
static final int numCPUs = RUN.availableProcessors();
static final int numWorkers = (numCPUs<3) ? (numCPUs+1) : ((numCPUs<8)?(numCPUs+2):(numCPUs+(numCPUs>>2)));
static final ThreadPoolExecutor TPE =
new ThreadPoolExecutor( numCPUs/*starting thread count*/, numWorkers/*max threads*/, 1L, TimeUnit.SECONDS,
new PriorityBlockingQueue<Runnable>());
// --- main0 ---------------------------------------------------------------
static public void main0( final String args[] ) throws IOException, InterruptedException {
// --- Next up: always re-make self as needed
// _build_c - is the class file for build.java (this file!)
_build_c.find_deps();
_FindDeps.take().find_deps();
assert _FindDeps.size() == 0 ;
long bc_time = _build_c._modtime;
_build_c.build_step(0);
_FindDeps.take();
if( _build_c._modtime != bc_time ) {
// Since we remade ourself, launch & run self in a nested process to do
// the actual 'build' using the new version of self.
TPE.shutdown();
String a = JAVA + " -cp build build ";
for( String arg : args )
a += arg+" ";
sys_exec(a,true).writeTo(System.out);
System.out.flush();
System.err.flush();
System.exit(0);
}
try {
Q qs[] = new Q[args.length];
boolean error = false;
for( int i=0; i<args.length; i++ ) { // For all targets
qs[i] = Q.FILES.get(args[i]);
if( qs[i] == null ) {
error = true;
System.err.println("Unknown target "+args[i]);
}
}
if( error ) throw new BuildError("Command line errors");
// When the top-level targets 'do_it' runs, it will do nothing but put the
// end-of-lazily-found deps on the _FindDeps queue, which will break the
// main thread back out and start shutting down the thread pools.
_FindDeps.put(new Q("targets",' ',qs));
// --- Now spin on the _FindDeps queue in the Main thread (only),
// processing tasks to produce any dependent tasks. Tasks can be added by
// worker threads asynchronously.
Thread.currentThread().setPriority(Thread.currentThread().getPriority()+1);
while( true ) {
final Q q = _FindDeps.take(); // Blocking call to get tasks.
if( q == ALL_DONE_SENTINEL )
break;
q.find_deps();
}
} catch( RejectedExecutionException e ) {
} finally {
// --- All Done!
TPE.shutdown();
System.out.flush();
System.err.flush();
}
// End of main
}
// --- StreamEater ---------------------------------------------------------
// Used to 'eat' the output stream from a remote process and store it in a
// local ByteArrayOutputStream.
static private class StreamEater extends Thread {
final private InputStream _is;
final public ByteArrayOutputStream _buf = new ByteArrayOutputStream();
private IOException _e;
StreamEater( InputStream is ) { _is = is; start(); }
public void run() {
byte[] buf = new byte[1024];
try {
int len;
while( (len=_is.read(buf)) != -1 ) {
_buf.write(buf,0,len);
}
} catch( IOException e ) {
_e = e; // Catch it for later, we're in the wrong thread
}
}
public void close() throws IOException, InterruptedException {
// called from the main thread on the StreamEater object, but not in the
// StreamEater thread.
join();
if( _e != null ) throw _e; // Rethrow any exception in the main thread
}
}
// --- sys_exec ------------------------------------------------------------
// Run the command string as a new system process. Throw an error if the
// return value is not zero, or any number of other errors happen. On an
// error, all process output is dumped to System.out (stdout). On success
// the output is buffered and the caller can decide how to dump.
static ByteArrayOutputStream sys_exec( String exec, boolean die_on_fail ) {
if( exec.length() == 0 ) return null; // Vacuously works for empty commands
// The standard 'exec' call does not handle quoted strings very
// nicely; this makes it hard to e.g. pass a quoted string to a
// 'sh' shell thus allowing multiple commands in a single step.
String[] execs = null;
int x = exec.indexOf('"');
if( x != -1 && exec.charAt(x-1)==' ' ) { // exec String contains quotes?
// nothing yet
ArrayList<String> toks = new ArrayList<String>();
int tok=0;
for( int i=0; i<exec.length(); i++ ) {
char c = exec.charAt(i);
if( c == ' ' || c == '"' ) {
if( tok<i ) toks.add(exec.substring(tok,i));
tok=i+1; // next token starts after this whitespace
}
if( c == '"' ) {
i++;
while( exec.charAt(i) != '"' ) i++;
toks.add(exec.substring(tok,i));
tok = i+1;
}
}
if( tok<exec.length() ) toks.add(exec.substring(tok,exec.length()));
execs = new String[toks.size()];
toks.toArray(execs);
System.out.println("split into chunks: "+execs.length);
System.out.println(exec);
}
// Now run the command string in a seperate process. Buffer all output,
// so that error output from parallel processes can be dumped out without
// interleaving. Also if the command finishes without any errors and we
// are not running very-verbose then we don't dump the commands output.
StreamEater err = null, out = null;
// This try/catch block will dump any output from the process before make dies
try {
Process p = null;
// This try/catch block will catch any I/O errors and turn them into BuildErrors
try {
// Run the 'exec' String in a seperate process.
p = execs == null ? RUN.exec(exec) : RUN.exec(execs);
err = new StreamEater(p.getErrorStream()); // Start StreamEater threads
out = new StreamEater(p.getInputStream());
final int status = p.waitFor();
if( status != 0 )
throw new BuildError("Status "+status+" from "+exec);
out.close(); // catch runaway StreamEater thread
err.close(); // catch runaway StreamEater thread
} catch( IOException e ) {
if( err == null ) System.out.println(""+e);
throw new BuildError("IOException from "+exec);
} catch( InterruptedException e ) {
throw new BuildError("Interrupted while waiting on "+exec);
} finally {
if( p != null ) p.destroy(); // catch runaway process
}
} catch( BuildError be ) {
// Build-step choked. Dump any output
if( out != null ) try { out._buf.writeTo(System.out); } catch( IOException e ) { throw new BuildError(e.toString()); }
if( err != null ) try { err._buf.writeTo(System.out); } catch( IOException e ) { throw new BuildError(e.toString()); }
if( die_on_fail ) { // For nested builds
System.out.flush();
System.err.flush();
System.exit(0);
}
throw be; // Rethrow after dumping output
}
return out._buf; // No errors? Then here is the buffered output
}
// Compute the base file name for a CPP file.
// Silently chokes for non-CPP files.
static final String basename( final String name ) {
final String cppname = name.substring(name.lastIndexOf('/')+1);
final String basename = cppname.substring(0,cppname.length()-4);
return basename;
}
// --- A dependency --------------------------------------------------------
static private class Q implements Comparable, Runnable {
// A table of all dependencies & target files in the world
static ConcurrentHashMap<String,Q> FILES = new ConcurrentHashMap<String,Q>();
// Basic definition of a dependency
final String _target; // Target file name
final char _src_sep; // Standard string seperator used between dependent file names
// I assume that calling lastModified() is a modestly expensive OS call.
// I *know* that some OS's report file timestamps rounded down badly, to
// the nearest 1 second on linux.
long _modtime; // Cache of _dst.lastModified() (or System.CTM for -n builds)
int _priority; // hint for build-order speed
int _cum_prior; // Cumlative priority from here to root
// These next 5 fields need to be atomically updated.
// They are updated and read concurrently by many threads.
// The _srcs array is updated by 'extra_check' for ".o" files - we read
// the matching ".P" file for a list of dependent ".hpp" files. It never
// otherwise changes. No other thread should be reading it until the
// sync'd extra_check returns - and then it should bounce over to the main
// thread for a re-check of dependencies.
Q[] _srcs; // Array of dependent files; not final because HPP dependencies get auto-added later
// Cleared by _extra_check so that main knows to re-inspect hpp lists.
File _dst; // Actual OS file; set once during find_deps, cleared by extra_check
// Count of _ready_children. This field changes when
// (1) the _srcs change, hence changing the number of children
// (2) any child changes state
int _ready_children; // Count of ready children
// Valid states are-
// - null - never inspected
// - "done" - all children are "done" and this build-step fired if needed
// - "extra_check" - extra deps added; do not attempt to add again
// - "failed"
String _state;
// Parent dependences of this dep. Changed by a child extra_step.
final Vector<Q> _parents = new Vector<Q>();
// --- Constructor for a list of source dependencies
Q( String target, char src_sep, Q[] srcs ) {
_target = target;
_src_sep = src_sep;
_srcs = srcs;
// Basic sanity checking
if( target.indexOf('%') != -1 )
throw new IllegalArgumentException("dependency target has a '%': "+target);
// Install the target/dependency mapping in a global flat table
Q old = FILES.put(_target,this);
if( old != null )
throw new IllegalArgumentException("More than one dependency for target "+
target+((_srcs.length > 0) ? (" with source "+_srcs[0]._target):""));
// Set any childs' parent-pointers to me
for( Q src : _srcs ) {
synchronized(src) {
src._parents.add(this);
}
}
}
// --- Constructor for a root file; no dependencies
static final private Q[] NONE = new Q[0];
Q( String target ) {
this(target,' ',NONE);
}
// --- Factory for a single dependency
static Q Q1( String target, Q src ) {
Q qs[] = new Q[1];
qs[0] = src;
return new Q(target,' ',qs);
}
// Special version for dynamically added targets with no deps (ala system
// include files): does a putIfAbsent into FILES.
private Q( String target, boolean f ) { _target = target; _src_sep = ' '; _srcs = NONE; }
static Q new_dynamic( String target ) {
Q q = FILES.get(target);
if( q != null ) return q; // Quick cutout
q = new Q(target,false);
FILES.putIfAbsent(target,q); // returns OLD value in table
return FILES.get(target); // Return current table contents
}
// --- addDep
// A handful of files need some #include deps "hand added" instead of using
// the auto-discovery mechanism.
synchronized Q addDep( Q ... deps ) {
Q[] srcs = new Q[_srcs.length+deps.length];
System.arraycopy(_srcs,0,srcs,0,_srcs.length);
System.arraycopy( deps,0,srcs,_srcs.length,deps.length);
_srcs = srcs;
for( Q dep : deps )
synchronized(dep) { dep._parents.add(this); }
return this;
}
// --- find_deps
// One-shot per Q, make sure each _src has _dst File.
// Sync'd to cover setting _dst & reading _ready_children count
synchronized void find_deps() throws InterruptedException {
if( _dst == null ) { // First time thru only
if( this instanceof QLinkerOption ) {
_dst = new File(TOP,"");
_modtime = 1;
} else {
_dst = _target.charAt(0)=='/' // Absolute path?
? new File(_target) // Then use it absolutely
: new File(TOP,_target); // Else assume TOP relative
_modtime = _dst.lastModified(); // Cache OS time
// Zero-length files are almost always errors sometimes caused by
// hitting ^C at a bad moment. Just assume they need to be built.
if( _dst.length() == 0 ) _modtime = 0; // Pretend zero-length files don't exist
}
_priority = 0;
if( _modtime==0 ) // if file does not exist
_priority += 99999999; // do it first
if( _target.endsWith("P") ) // If file creates more work
_priority += 59999999; // do it 2nd
_priority += _dst.length(); // Otherwise do slower (bigger) files before faster files
_cum_prior = _priority; // Add in your parent's priority also
for( Q p : _parents ) // Also include all parents' priorities
_cum_prior += p._cum_prior;
if( _modtime == 0 && _srcs.length == 0 )
throw new BuildError("Source file "+_target+" is missing, used by at least "+_parents.get(0)._target);
} else if( _state != "extra_check" ) { // Tossed onto finddeps extra times?
// _dst already set, so already ran finddeps
return; // Nothing to do here
}
// Put children on as well
for( Q src : _srcs ) {
synchronized(src) {
if( src._dst == null || src._state == "extra_check" )
_FindDeps.put(src);
else
src._cum_prior += _cum_prior;
}
}
// Put trivially ready things on the WorkQueue
if( _state == null && _ready_children == _srcs.length )
TPE.execute(this);
}
// Make a single String with all sources, pre-pended with the top-level
// path and seperated by the 'sep' char.
String flat_src( char sep ) {
String s = "";
if( _srcs.length==0 ) return s;
for( int i=0; i<_srcs.length-1; i++ ) {
if( _srcs[i]._target.charAt(0)!='/' &&
!(_srcs[i] instanceof QLinkerOption) )
s += TOP_PATH_SLASH+"/";
s += _srcs[i]._target+sep;
}
if( _srcs[_srcs.length-1]._target.charAt(0)!='/' )
s += TOP_PATH_SLASH+"/";
s += _srcs[_srcs.length-1]._target;
return s;
}
// The void 'do_it' function, with no output. Override this to do
// a real build-step. Also print a 1-liner on what the step is
// doing, WITH printing a newline in a single output write.
protected ByteArrayOutputStream do_it( ) {
return null;
}
// Override if your build-step adds any dependencies
// Return 1 - added child deps that need to be checked
// Return 2 - force build step to happen
protected int extra_check() {
return 0;
}
// Building priorities encoded here
// 1- missing files (probably a failed prior build-step with syntax errors
// 2- jobs making more work (.P files, ADLC, or JVMTI XML)
// 3- big jobs
// Lower priorities are pulled from the work queue first
public int compareTo(Object o) {
return ((Q)o)._cum_prior - _cum_prior;
}
public void findDeps_queue() {
try {
_FindDeps.put(this); // Find'em all...
} catch( InterruptedException e ) {
throw new Error(e); // Rethrow as an unchecked exception - we're dead
}
}
// --- Do the build-step, as needed
public String build_step( final int xc ) {
// Cleaning? Nuke target and return
if( _clean ) {
if( _srcs.length == 0 ) return "done"; // Do not remove source files
if( !_dst.exists() ) return "done"; // Already removed
if( this == _build_c ) return "done"; // Highly annoying to delete own class file
System.out.println("rm "+_target);
if( !_justprint ) _dst.delete();
return "done";
}
// See if all is up-to-date. Collect out-of-date filenames. Collect
// youngest source file (output file produced by this build step should
// end up newer than the youngest source file).
long last_src = 0;
String newer = null;
for( Q src : _srcs ) {
if( last_src < src._modtime )
last_src = src._modtime; // Latest source time
if( _modtime < src._modtime ) { // Out of date?
if( newer == null ) { // No filenames yet?
newer = src._target; // Collect 1st filename
} else { // 2nd or later filename
newer += " "+src._target; // Collect filenames
}
}
}
if( xc <= 1 && newer == null ) { // Found no out-of-date source files?
if( _verbose > 1 ) {
if( _srcs.length != 0 ) {
System.out.println("-- " + _target + " > { "+flat_src(' ')+" } : already up to date");
} else {
System.out.println("-- " + _target + " is a source file : already up to date");
}
}
return "done";
}
// Else out-of-date and must build
// ---
// Files out of date; must do this build step
if( _verbose > 0 ) {
if( _modtime == 0 ) System.out.println("-- " + _target+ " is missing");
else System.out.println("-- " + _target+ " <= { "+newer+" }"+
(newer==null?", forced build step because of new dependencies":""));
}
// About to attempt to make the file; force any needed directories
File target_file = new File(_target);
File parent_dir = target_file.getParentFile();
if (parent_dir != null) parent_dir.mkdirs();
try {
// Do the build step. Capture (and currently ignore) and standard
// output from a successful build step. Failed build-steps always
// dump their stdout+stderr.
ByteArrayOutputStream buf = do_it();
} catch( BuildError be ) { // Catch obvious build failures
// Failed; make sure target is deleted (except for build.class)
if( this != _build_c ) // Highly annoying to delete own class file
_dst.delete();
if( !_keepontrucking ) { // single error is fatal
try { Thread.sleep(1000); } catch( InterruptedException e ) { }
TPE.shutdown();
System.out.flush();
System.err.flush();
System.exit(-1);
}
return "failed";
}
if( _justprint ) { // No expectation of any change
_modtime = last_src+1; // Force modtime update
return "done";
}
// Double-check that the source files were not modified by the
// build-step. It's a fairly common error if file-names get swapped,
// etc. This exception is uncaught, so it aborts everything. It
// basically indicate a broken build file - the build-step is changing
// the wrong file.
for( Q src : _srcs )
if( !(src instanceof QLinkerOption) &&
src._modtime != src._dst.lastModified() )
throw new IllegalArgumentException("Timestamp for source file "+src._target+
" apparently changed by building "+_target+
" last recorded time="+src._modtime+
" and now the filesystem reports="+src._dst.lastModified());
// Double-check that this step made progress. Again, failure here is
// likely a build-step failure to modify the correct file.
long x = _dst.lastModified();
int sleep=100;
while( _modtime == x && sleep >0 ) {
System.out.println("Timestamp for "+_target+" not changed by building; time="+x);
try { Thread.sleep(1); } catch( InterruptedException e ) { };
sleep--;
}
_modtime = x;
long now = System.currentTimeMillis();
while( now < _modtime ) {
System.out.println("Timestamp for "+_target+" moved "+(_modtime-now)+"ms into the future by building; sleeping until the Future is Now");
try { Thread.sleep(_modtime-now); } catch( InterruptedException e ) { };
now = System.currentTimeMillis();
}
if( _modtime < last_src )
throw new IllegalArgumentException("Timestamp for "+_target+" not changed by building "+_target);
// Invariant: last_src <= _modtime <= now
// For very fast build-steps, the target may be updated to a time equal
// to the input file times after rounding to the file-system's time
// precision - which might be as bad as 1 whole second. Assume the
// build step worked, but give the result an apparent time just past the
// src file times to make later steps more obvious.
if( !_allow_timestamp_ties ) {
while( x == last_src ) { // Aaahh, we have 'tied' in the timestamps!!!
// Sleep/spin until the OS's version of a rounded timestamp shows real progress
try { Thread.sleep(1); } catch( InterruptedException e ) { };
now = System.currentTimeMillis();
_dst.setLastModified(now); // Pretend file was made 'right NOW!'
x = _dst.lastModified(); // Reload, after OS rounding
}
if( _modtime == last_src )
System.out.println("Yawners... had to sleep "+(System.currentTimeMillis()-_modtime)+" msec to get timestamp to advance");
}
_modtime = x; // Record apparent mod-time
return "done";
}
// --- What happens 'FutureTask.get' is called on a Q?
public void run() {
if( _parents.size() == 0 ) { // Ready to build the top-level fake target?
_state = "done";
ALL_DONE_SENTINEL.findDeps_queue();
return;
}
// Assert we never been run before, or only run thru 'extra_check'
String st;
synchronized(this) { st = _state; }
assert st == "extra_check" || st == null : "1Running "+_target+" with st="+st+" and rdy="+_ready_children+":"+_srcs.length;
assert _ready_children == _srcs.length : "2Running "+_target+" with st="+st+" and rdy="+_ready_children+":"+_srcs.length;
int xc = 0; // Is build-step forced? (generally by a missing file?)
if( st == null ) { // Not ready extra-step
try {
xc = extra_check(); // Producing extra dependencies?
} catch( Exception e ) {
System.err.println(e.getMessage());
TPE.shutdown();
System.out.flush();
System.err.flush();
System.exit(-1);
}
if( xc == 1 ) return; // No more work here, until deps are all found & built
}
// See if any child failed
String state = null;
for( Q src : _srcs ) { // Assert all children already done
String cstate;
synchronized(src) { cstate= src._state;}
assert cstate == "done" || cstate == "failed" : "Running "+_target+" but child "+src._target+" has state="+cstate;
if( cstate == "failed" )
state = "failed";
}
// Do build step (if we aint dead yet)
if( state == null ) // No failed children?
state = build_step(xc); // Get new state from build_step
// Change state under lock, but also clone parent list. When the lock
// releases, other parents may be added and they need to handle the
// exposed _state (i.e., they just added a 'done' child so they better
// update their ready_children count.
Vector<Q> pclone;
synchronized(this) {
_state = state;
pclone = new Vector<Q>(_parents);
}
// Inform all parents that this child is ready
for( Q p : pclone )
p.child_is_ready(this);
}
// --- child_is_ready
// Some child completed successfully.
// Check _dst under lock;
synchronized void child_is_ready(Q c) {
assert _ready_children < _srcs.length : " "+_target+" "+_ready_children+"<"+_srcs.length+ " child="+c._target;
_ready_children++;
// Happens on parents (with ready children) not involved in any
// top-level build target - they become ready to build, but no target
// needs them.
if( _dst == null ) return;
if( _ready_children == _srcs.length ) {
try {
TPE.execute(this);
} catch( RejectedExecutionException ree ) {
// ignore if shutting down
}
}
}
};
// --- A dependency with an exec string ------------------------------------
// Mostly just a normal dependency; it "execs" a String to do the build-step.
static private class QS extends Q {
final String _exec;
String _parsed_exec;
// --- Constructor for a list of source dependencies
QS( String target, String exec, char src_sep, Q ... srcs ) {
super(target, src_sep,srcs);
_exec = exec;
for( int i=_exec.indexOf('%'); i!= -1; i = _exec.indexOf('%',i+1) ) {
if( false ) {
} else if( _exec.startsWith("dst",i+1) ) {
} else if( _exec.startsWith("src",i+1) ) {
} else if( _exec.startsWith("top",i+1) ) {
} else
throw new IllegalArgumentException("dependency exec has unknown pattern: "+_exec.substring(i));
}
}
QS( String target, String exec, Q src ) {
this(target,exec,' ',src);
}
// --- parse_exec
// The _exec String contains normal text, plus '%src' and '%dst' strings.
String parse_exec() {
if( _parsed_exec == null ) {
if( _srcs.length > 0 ) _parsed_exec = _exec.replaceAll("%src0",_srcs[0]._target);
if( _srcs.length > 1 ) _parsed_exec = _parsed_exec.replaceAll("%src1",_srcs[1]._target);
if( _srcs.length > 2 ) _parsed_exec = _parsed_exec.replaceAll("%src2",_srcs[2]._target);
_parsed_exec = _parsed_exec
.replaceAll("%dst",_target)
.replaceAll("%src",flat_src(_src_sep))
.replaceAll("%top",TOP_PATH_SLASH);
}
return _parsed_exec;
}
protected ByteArrayOutputStream do_it( ) {
final String exec = parse_exec();
System.out.println(exec); // Print 1-liner on what the step is doing
return _justprint ? null : sys_exec(exec, false);
}
}
// --- A dependency for a C++ compile --------------------------------------
// The source is a foo.P file; read it for more dependencies.
// Add the dependencies in 'extra_check'.
// The 'doit' step just changes the default printout from QS - otherwise
// it just does a normal string exec.
static private class QC extends QS {
// Given a path to a C++ file (and a compile string), build a foo.o
// dependency to build from a foo.P file.
static QC gen( String tpath, String flavor, String exec, String basename, String ext, Q ... extras ) {
final String target = tpath+flavor+basename+".o";
final String Pname = tpath+"incls/"+basename+ext;
final Q src = FILES.get(Pname);
if( src == null ) throw new IllegalArgumentException("Missing dep for "+Pname+"\n");
if( extras!=null && extras.length>0 )
src.addDep(extras);
return new QC(target,exec,src);
}
private QC( String target, String exec, Q src ) { super(target,exec,src ); }
// Given a list of C++ files (and a compile string), build an array of foo.o
// dependencies to build, from the list of C++ files.
static Q[] gen_all( Q[] cs, Q[] cps, Q[] cos, String tpath, String flavor, String exec, Q ... extras ) {
final Q os[] = new Q[cs.length+cps.length+cos.length];
int j=0;
for( int i=0; i<cs.length; i++ )
os[j+i] = gen( tpath, flavor, exec+" "+cs [i]._target, basename(cs [i]._target), ".PP", extras );
j = cs.length;
for( int i=0; i<cps.length; i++ )
os[j+i] = gen( tpath, flavor, exec+" "+cps[i]._target, basename(cps[i]._target), ".PP", extras );
j = cs.length+cps.length;
for( int i=0; i<cos.length; i++ )
os[j+i] = gen( tpath, flavor, exec+" "+cos[i]._target, basename(cos[i]._target), ".PP", extras );
return os;
}
// Override the default non-verbose printout.
protected ByteArrayOutputStream do_it( ) {
final String exec = parse_exec();
if( _verbose > 0 ) System.out.println(exec); // Print 1-liner on what the step is doing
else System.out.println("Compiling "+_target);
return _justprint ? null : sys_exec(exec, false);
}
// Read the .P file for extra dependencies
protected int extra_check() {
Q pfile=null;
for( Q x : _srcs ) {
if( x._target.endsWith("P") ) {
pfile=x;
break;
}
}
if( pfile==null ) throw new BuildError("Missing P file dep for "+_target);
try {
// Read & parse the deps file
final File deps = new File(pfile._target);
final int len = (int)deps.length();
final char[] cbuf = new char[len];
if( len != new FileReader(deps).read(cbuf,0,len) )
throw new IOException("Unexpected short read");
// Split the string based on:
// ' ' - blank
// '\' - Backslash. Must be encoded as 4 backslashes in the split string
// '\n' - newline.
final String[] ss = new String(cbuf).split("[ \\\\\n:]+");
// The first String in ss should be of the form "foo.o".
if( ss.length < 1 || !_target.endsWith(ss[0]) )
throw new IllegalArgumentException("Expected first dep of "+pfile._target+" to refer to "+_target+"; badly formed .PP file; please delete it");
// The 2nd String should be of the form TOP+".../foo.cpp"
String srcname="";
if( ss.length < 2 || !(srcname=(TOP_PATH_SLASH+"/"+pfile._srcs[0]._target)).endsWith(ss[1]) )
throw new IllegalArgumentException("Expected second dep to refer to "+srcname+" but found "+ss[1]+"; badly formed .PP file; please delete "+pfile._target);
// Copy the initial _srcs into a HashMap, to remove dup strings from
// the dependency file
final HashMap<String,Q> srcs = new HashMap<String,Q>();
for( Q s : _srcs )
srcs.put(s._target,s);
// The remaining Strings will be proper dependencies. They either:
// - start with 'src' and are a relative name and must be in the global FILES list, or
// - start with TOP_PATH_SLASH, then 'src' and are treated as above, or
// - they start with '/' and refer to a system include file, or
// - start with 'acapulco_port' and refer to a ported OS include file,
// - start with 'sandbox' and refer to an OS include file,
// - start with 'j2se6' and refer to a mini-JRE include file,
for( int i=2; i<ss.length; i++ ) {
String s = ss[i];
if( s.startsWith("/") || s.startsWith("acapulco_port/") || s.startsWith("../") || s.startsWith("j2se6/") ) {
srcs.put(s,Q.new_dynamic(s)); // sandbox or system .h files are just assumed valid
} else if( s.startsWith("src/") ) { // these should exist in build.java, for some kind of safety
Q dep = Q.FILES.get(s);
String fname = TOP_PATH_SLASH+"/"+s;
boolean file_found = new File(fname).canRead();
if( dep == null ) { // Source file not mentioned in build.java
if( !file_found ) { // File not found?
if( _verbose > 0 )
System.out.println("--- File "+fname+" not found, forcing rebuild");
// File not found, and not in build.java - so dep file is
// wrong; force a recompile of the C++ program. It should
// fail (after all an include file is missing). If the C++
// file is edited to remove the missing include file, that
// should trigger a rebuild of the dep file - which will no
// long mention the missing include file.
return 2; // force build step
}
// Dep file mentions a name that is not in build.java, but the
// file still exists - assume it is a missing dependence in the
// build file.
throw new IllegalArgumentException("build.java does not have a dependence for file "+s);
} else if( !file_found ) {
// Dep file and build.java both mention a file that does not exist.
// Probably the file was removed and build.java should be cleaned up.
throw new IllegalArgumentException("build.java has a dependence for missing file "+fname);
}
srcs.put(s,dep);
} else {
throw new IllegalArgumentException("Dependency filename does not start with '/' or 'sandbox' or 'src' or 'j2se6' "+s);
}
}
// Anything change?
if( srcs.size() == _srcs.length ) return 0;
final Q qsrcs[] = srcs.values().toArray(_srcs); // Update _srcs list; more deps found so it grew
// Source list changed; update it, and the parent/child relations and counts
// 'this' is locked
synchronized(this) { // Lock self; no updating _ready_children
_state = "extra_check"; // Change state: we'll need an extra go'round in find_deps
_srcs = qsrcs; // Change list of children
_ready_children = 0; // Recompute readiness; some children are ready and some are not
for( Q src : qsrcs ) {
synchronized(src) {
src._parents.add(this);
if( src._state == "done" || src._state == "failed" )
_ready_children++;
}
}
if( _ready_children == qsrcs.length )
return 0; // All new children all ready to go!
findDeps_queue(); // Else must FindDep'em all...
return 1; // Added new deps!!!
}
} catch( FileNotFoundException e ) {
if( _justprint || _clean ) return 0; // Just printing - so no new deps discovered
throw new IllegalArgumentException("make is busted: did not spot missing file: "+e);
} catch( IOException e ) { // Some I/O issue?
throw new BuildError(e.toString()); // Rethrow as a BuildError
}
} // extra_check
}
// --- A dependency for an archive -----------------------------------------
static private class QA extends QS {
QA( String target, String exec, char src_sep, Q ... srcs ) { super(target,exec,src_sep,srcs); }
// Override the default non-verbose printout.
protected ByteArrayOutputStream do_it( ) {
final String exec = parse_exec();
if( _verbose > 0 ) System.out.println(exec); // Print 1-liner on what the step is doing
else System.out.println("Archiving "+_target);
return _justprint ? null : sys_exec(exec, false);
}
}
// --- A dependency for a link ---------------------------------------------
static private class QL extends QS {
QL( String target, String exec, char src_sep, Object ... srcs ) {
super(target,exec,src_sep,flatten_to_Q(srcs));
}
static Q[] flatten_to_Q( Object[] srcs ) {
int sz=0;
for( Object o : srcs )
sz += (o instanceof Q[]) ? ((Q[])o).length : 1;
Q qs[] = new Q[sz];
int i=0;
for( Object o : srcs )
if( o instanceof Q[] ) {
Q[] sqs = (Q[])o;
System.arraycopy(sqs,0,qs,i,sqs.length);
i += sqs.length;
} else {
qs[i++] = (Q)o;
}
return qs;
}
// Override the default non-verbose printout.
protected ByteArrayOutputStream do_it( ) {
final String exec = parse_exec();
if( _verbose > 0 ) System.out.println(exec); // Print 1-liner on what the step is doing
else System.out.println("Linking "+_target);
return _justprint ? null : sys_exec(exec, false);
}
}
// --- A bogus dependency for adding a linker option in the middle ---------
static private class QLinkerOption extends Q {
QLinkerOption( String opt ) { super(opt); }
public String build_step( final int xc ) { return "done"; }
}
// --- Strip and Sign a Binary, in 1 step ---------
static private class QStripSign extends Q {
private QStripSign( String dst, Q[] srcs ) { super(dst,' ',srcs); }
public static QStripSign make( String dst, Q src ) { Q[] qs = {src}; return new QStripSign(dst,qs); }
protected ByteArrayOutputStream do_it( ) {
final String exec0 = AZSTRIP+" -d -o "+_target+" "+_srcs[0]._target;
if( _verbose > 0 ) System.out.println(exec0); // Print 1-liner on what the step is doing
else System.out.println("Stripping "+_target);
ByteArrayOutputStream bas0 = _justprint ? null : sys_exec(exec0, false);
final String exec1 = ELFSIGN+" "+_target;
if( _verbose > 0 ) System.out.println(exec1); // Print 1-liner on what the step is doing
else System.out.println("Signing "+_target);
ByteArrayOutputStream bas1 = _justprint ? null : sys_exec(exec1, false);
return bas1;
}
}
// --- Construct foo.P dependencies from all foo.cpp files -----------------
// Find all 'cpp' files in the FILES list. For each src/.../foo.cpp, create
// a 'path/incls/foo.P' dependency. The dependency will cause the foo.P
// file to be made from the 'bld' string if the foo.cpp file changes. A
// foo.P file lists all the other '#include' files used by foo.cpp.
static private class QP extends QS {
private QP( final String target, final String bld, char src_sep, final Q ... srcs ) { super(target,bld,src_sep,srcs); }
private QP( final String target, final String bld, final Q src ) { super(target,bld,src); }
static void build_P_deps( String path, String bld ) {
for( String key : Q.FILES.keySet() ) {
if( key.endsWith("cpp") ) {
final String basename = basename(key);
final String Pname = basename+".PP";
Q pp = new QP(path + "incls/"+Pname,bld,' ',FILES.get(key));
}
}
}
// Override the default non-verbose printout.
protected ByteArrayOutputStream do_it( ) {
final String exec = parse_exec();
if( _verbose > 1 ) System.out.println(exec); // Print 1-liner on what the step is doing
else System.out.println("Depending "+_target);
return _justprint ? null : sys_exec(exec, false);
}
}
// --- A dependency, just 'touch'ing the target ----------------------------
// Mostly just a normal dependency
static private class Q_touch extends Q {
Q_touch( final String target, final Q ... srcs ) { super(target,' ',srcs); }
protected ByteArrayOutputStream do_it( ) {
System.out.println("touch "+_target); // 1-liner of build-step
if( _justprint ) return null;
File f = new File(TOP_PATH_SLASH+"/"+_target);
try {
f.delete();
f.createNewFile();
// You would think that to delete & create the file would update the
// lastMod time accurately, but on linux at least it appears it can be
// created at least 1 msec in the past.
long t = System.currentTimeMillis();
f.setLastModified(t);
} catch( IOException e ) {
throw new BuildError("Unable to make file "+_target+": "+e.toString());
}
return null; // No output from a 'touch'
}
}
// =========================================================================
// --- The Dependencies ----------------------------------------------------
// =========================================================================
// The build-self dependency every project needs
static final Q _build_j = new Q("build/build.java");
static final Q _build_c = new QS("build/build.class", JAVAC + " -cp build %src",_build_j);
// --- Some tools
static final String AZ_SWTOOLS_GCC_TXU_DIR = "/home/swrelease/swtools/1.04.0422/linux/bin";
static final String AZ_SWTOOLS_GCC_NXU_DIR = "/home/buildmaster/sw/gcc/4.3.0/linux/nxu_64/bin";
static final String GCC_DEFINES = "-DJDK_VERSION_STR=\"1.6.0_99999\" ";
static final String GCC_FLAGS = "-fno-rtti -fno-exceptions -pipe -fmessage-length=0 " + GCC_DEFINES;
//static final String GCC_NXU = "/home/buildmaster/gcc4.3.2/build.gcc/nxu_64-linux-gnu/bin/g++ -Di86pc " + GCC_FLAGS;
//static final String GC_NXU = "/home/buildmaster/gcc4.3.2/build.gcc/nxu_64-linux-gnu/bin/gcc -pipe -fmessage-length=0 -Wall -Di86pc " + GCC_DEFINES;
static final String GCC_NXU = AZ_SWTOOLS_GCC_NXU_DIR + "/g++ -fno-strict-aliasing -Di86pc -DAZPROF_NO_OPENSSL -DAZPROF_NO_EVENTS " + GCC_FLAGS;
static final String GC_NXU = AZ_SWTOOLS_GCC_NXU_DIR + "/gcc -fno-strict-aliasing -pipe -fmessage-length=0 -Wall -Di86pc " + GCC_DEFINES;
static final String GCC_TXU = AZ_SWTOOLS_GCC_TXU_DIR + "/azg++ -Wa,-xarch=vega2 " + GCC_FLAGS;
static final String GC_TXU = AZ_SWTOOLS_GCC_TXU_DIR + "/azgcc -Wa,-xarch=vega2 " + GCC_FLAGS;
static final String AZSTRIP = AZ_SWTOOLS_GCC_TXU_DIR + "/azstrip";
static final String AZAR = AZ_SWTOOLS_GCC_TXU_DIR + "/azar";
static final String ELFSIGN = SANDBOX+"/linux/bin/i686/elfsign -k "+SANDBOX+"/linux/keys.private/binpriXX.pem ";
// --- Some HotSpot CPU-specific source files
static final String CPU_TXU = "src/cpu/txu/vm/";
static final Q _assembler_txu_cpp = new Q(CPU_TXU+"assembler_txu.cpp");
static final Q _assembler_txu_hpp = new Q(CPU_TXU+"assembler_pd.hpp");
static final Q _bytecodes_txu_cpp = new Q(CPU_TXU+"bytecodes_txu.cpp");
static final Q _bytecodes_txu_hpp = new Q(CPU_TXU+"bytecodes_pd.hpp");
static final Q _bytes_txu_hpp = new Q(CPU_TXU+"bytes_pd.hpp");
static final Q _c1_globals_txu_hpp = new Q(CPU_TXU+"c1_globals_pd.hpp");
static final Q _c2_globals_txu_hpp = new Q(CPU_TXU+"c2_globals_pd.hpp");
static final Q _constants_txu_hpp = new Q(CPU_TXU+"constants_pd.hpp");
static final Q _copy_txu_cpp = new Q(CPU_TXU+"copy_txu.cpp");
static final Q _copy_txu_hpp = new Q(CPU_TXU+"copy_pd.hpp");
static final Q _debug_txu_cpp = new Q(CPU_TXU+"debug_txu.cpp");
static final Q _disassembler_txu_cpp = new Q(CPU_TXU+"disassembler_txu.cpp");
static final Q _disassembler_txu_hpp = new Q(CPU_TXU+"disassembler_pd.hpp");
static final Q _frame_txu_cpp = new Q(CPU_TXU+"frame_txu.cpp");
static final Q _frame_txu_hpp = new Q(CPU_TXU+"frame_pd.hpp");
static final Q _frame_txu_inline_hpp = new Q(CPU_TXU+"frame_pd.inline.hpp");
static final Q _global_defs_txu_hpp = new Q(CPU_TXU+"globalDefinitions_pd.hpp");
static final Q _globals_txu_hpp = new Q(CPU_TXU+"globals_pd.hpp");
static final Q _gpgc_traps_txu_hpp = new Q(CPU_TXU+"gpgc_traps_pd.hpp");
static final Q _heapRef_txu_hpp = new Q(CPU_TXU+"heapRef_pd.hpp");
static final Q _heapRef_txu_inline_hpp = new Q(CPU_TXU+"heapRef_pd.inline.hpp");
static final Q _icache_txu_cpp = new Q(CPU_TXU+"icache_txu.cpp");
static final Q _icache_txu_hpp = new Q(CPU_TXU+"icache_pd.hpp");
static final Q _interp_masm_txu_cpp = new Q(CPU_TXU+"interp_masm_txu.cpp");
static final Q _interp_masm_txu_hpp = new Q(CPU_TXU+"interp_masm_pd.hpp");
static final Q _interpreterRT_txu_cpp = new Q(CPU_TXU+"interpreterRT_txu.cpp");
static final Q _interpreterRT_txu_hpp = new Q(CPU_TXU+"interpreterRT_pd.hpp");
static final Q _interpreter_txu_cpp = new Q(CPU_TXU+"interpreter_txu.cpp");
static final Q _interpreter_txu_hpp = new Q(CPU_TXU+"interpreter_pd.hpp");
static final Q _javaFrameAnchor_txu_hpp = new Q(CPU_TXU+"javaFrameAnchor_pd.hpp");
static final Q _jniTypes_txu_hpp = new Q(CPU_TXU+"jniTypes_pd.hpp");
static final Q _lvb_txu_hpp = new Q(CPU_TXU+"lvb_pd.hpp");
static final Q _nativeInst_txu_hpp = new Q(CPU_TXU+"nativeInst_pd.hpp");
static final Q _nativeInst_txu_cpp = new Q(CPU_TXU+"nativeInst_txu.cpp");
static final Q _objectRef_txu_cpp = new Q(CPU_TXU+"objectRef_txu.cpp");
static final Q _objectRef_txu_hpp = new Q(CPU_TXU+"objectRef_pd.hpp");
static final Q _objectRef_txu_inline_hpp = new Q(CPU_TXU+"objectRef_pd.inline.hpp");
static final Q _pauselessTraps_txu_hpp = new Q(CPU_TXU+"pauselessTraps_pd.hpp");
static final Q _refsHierarchy_txu_hpp = new Q(CPU_TXU+"refsHierarchy_pd.hpp");
static final Q _register_txu_cpp = new Q(CPU_TXU+"register_txu.cpp");
static final Q _register_txu_hpp = new Q(CPU_TXU+"register_pd.hpp");
static final Q _relocInfo_txu_hpp = new Q(CPU_TXU+"relocInfo_pd.hpp");
static final Q _shared_txu_cpp = new Q(CPU_TXU+"shared_txu.cpp");
static final Q _sharedRuntime_txu_cpp = new Q(CPU_TXU+"sharedRuntime_txu.cpp");
static final Q _stackRef_txu_cpp = new Q(CPU_TXU+"stackRef_txu.cpp");
static final Q _stackRef_txu_hpp = new Q(CPU_TXU+"stackRef_pd.hpp");
static final Q _stackRef_txu_inline_hpp = new Q(CPU_TXU+"stackRef_pd.inline.hpp");
static final Q _stubGenerator_txu_cpp = new Q(CPU_TXU+"stubGenerator_txu.cpp");
static final Q _stubRoutines_txu_cpp = new Q(CPU_TXU+"stubRoutines_txu.cpp");
static final Q _stubRoutines_txu_hpp = new Q(CPU_TXU+"stubRoutines_pd.hpp");
static final Q _templateTable_txu_cpp = new Q(CPU_TXU+"templateTable_txu.cpp");
static final Q _templateTable_txu_hpp = new Q(CPU_TXU+"templateTable_pd.hpp");
static final Q _tickProfiler_txu_cpp = new Q(CPU_TXU+"tickProfiler_txu.cpp");
static final Q _thread_txu_hpp = new Q(CPU_TXU+"thread_pd.hpp");
static final Q _vm_version_txu_cpp = new Q(CPU_TXU+"vm_version_txu.cpp");
static final Q _vm_version_txu_hpp = new Q(CPU_TXU+"vm_version_pd.hpp");
static final Q _vtableStubs_txu_cpp = new Q(CPU_TXU+"vtableStubs_txu.cpp");
static final String CPU_NXU = "src/cpu/nxu/vm/";
static final Q _assembler_nxu_cpp = new Q(CPU_NXU+"assembler_nxu.cpp");
static final Q _assembler_nxu_hpp = new Q(CPU_NXU+"assembler_pd.hpp");
static final Q _bytecodes_nxu_cpp = new Q(CPU_NXU+"bytecodes_nxu.cpp");
static final Q _bytecodes_nxu_hpp = new Q(CPU_NXU+"bytecodes_pd.hpp");
static final Q _bytes_nxu_hpp = new Q(CPU_NXU+"bytes_pd.hpp");
static final Q _c1_globals_nxu_hpp = new Q(CPU_NXU+"c1_globals_pd.hpp");
static final Q _c2_globals_nxu_hpp = new Q(CPU_NXU+"c2_globals_pd.hpp");
static final Q _constants_nxu_hpp = new Q(CPU_NXU+"constants_pd.hpp");
static final Q _copy_nxu_cpp = new Q(CPU_NXU+"copy_nxu.cpp");
static final Q _copy_nxu_hpp = new Q(CPU_NXU+"copy_pd.hpp");
static final Q _debug_nxu_cpp = new Q(CPU_NXU+"debug_nxu.cpp");
static final Q _disassembler_nxu_cpp = new Q(CPU_NXU+"disassembler_nxu.cpp");
static final Q _disassembler_nxu_hpp = new Q(CPU_NXU+"disassembler_pd.hpp");
static final Q _frame_nxu_cpp = new Q(CPU_NXU+"frame_nxu.cpp");
static final Q _frame_nxu_hpp = new Q(CPU_NXU+"frame_pd.hpp");
static final Q _frame_nxu_inline_hpp = new Q(CPU_NXU+"frame_pd.inline.hpp");
static final Q _global_defs_nxu_hpp = new Q(CPU_NXU+"globalDefinitions_pd.hpp");
static final Q _globals_nxu_hpp = new Q(CPU_NXU+"globals_pd.hpp");
static final Q _gpgc_traps_nxu_hpp = new Q(CPU_NXU+"gpgc_traps_pd.hpp");
static final Q _heapRef_nxu_hpp = new Q(CPU_NXU+"heapRef_pd.hpp");
static final Q _heapRef_nxu_inline_hpp = new Q(CPU_NXU+"heapRef_pd.inline.hpp");
static final Q _icache_nxu_cpp = new Q(CPU_NXU+"icache_nxu.cpp");
static final Q _icache_nxu_hpp = new Q(CPU_NXU+"icache_pd.hpp");
static final Q _interp_masm_nxu_cpp = new Q(CPU_NXU+"interp_masm_nxu.cpp");
static final Q _interp_masm_nxu_hpp = new Q(CPU_NXU+"interp_masm_pd.hpp");
static final Q _interpreterRT_nxu_cpp = new Q(CPU_NXU+"interpreterRT_nxu.cpp");
static final Q _interpreterRT_nxu_hpp = new Q(CPU_NXU+"interpreterRT_pd.hpp");
static final Q _interpreter_nxu_cpp = new Q(CPU_NXU+"interpreter_nxu.cpp");
static final Q _interpreter_nxu_hpp = new Q(CPU_NXU+"interpreter_pd.hpp");
static final Q _javaFrameAnchor_nxu_hpp = new Q(CPU_NXU+"javaFrameAnchor_pd.hpp");
static final Q _jniTypes_nxu_hpp = new Q(CPU_NXU+"jniTypes_pd.hpp");
static final Q _lvb_nxu_hpp = new Q(CPU_NXU+"lvb_pd.hpp");
static final Q _nativeInst_nxu_hpp = new Q(CPU_NXU+"nativeInst_pd.hpp");
static final Q _nativeInst_nxu_cpp = new Q(CPU_NXU+"nativeInst_nxu.cpp");
static final Q _objectRef_nxu_cpp = new Q(CPU_NXU+"objectRef_nxu.cpp");
static final Q _objectRef_nxu_hpp = new Q(CPU_NXU+"objectRef_pd.hpp");
static final Q _objectRef_nxu_inline_hpp = new Q(CPU_NXU+"objectRef_pd.inline.hpp");
static final Q _pauselessTraps_nxu_hpp = new Q(CPU_NXU+"pauselessTraps_pd.hpp");
static final Q _refsHierarchy_nxu_hpp = new Q(CPU_NXU+"refsHierarchy_pd.hpp");
static final Q _register_nxu_cpp = new Q(CPU_NXU+"register_nxu.cpp");
static final Q _register_nxu_hpp = new Q(CPU_NXU+"register_pd.hpp");
static final Q _relocInfo_nxu_hpp = new Q(CPU_NXU+"relocInfo_pd.hpp");
static final Q _shared_nxu_cpp = new Q(CPU_NXU+"shared_nxu.cpp");
static final Q _sharedRuntime_nxu_cpp = new Q(CPU_NXU+"sharedRuntime_nxu.cpp");
static final Q _stackRef_nxu_cpp = new Q(CPU_NXU+"stackRef_nxu.cpp");
static final Q _stackRef_nxu_hpp = new Q(CPU_NXU+"stackRef_pd.hpp");
static final Q _stackRef_nxu_inline_hpp = new Q(CPU_NXU+"stackRef_pd.inline.hpp");
static final Q _stubGenerator_nxu_cpp = new Q(CPU_NXU+"stubGenerator_nxu.cpp");
static final Q _stubRoutines_nxu_cpp = new Q(CPU_NXU+"stubRoutines_nxu.cpp");
static final Q _stubRoutines_nxu_hpp = new Q(CPU_NXU+"stubRoutines_pd.hpp");
static final Q _templateTable_nxu_cpp = new Q(CPU_NXU+"templateTable_nxu.cpp");
static final Q _templateTable_nxu_hpp = new Q(CPU_NXU+"templateTable_pd.hpp");
static final Q _tickProfiler_nxu_cpp = new Q(CPU_NXU+"tickProfiler_nxu.cpp");
static final Q _thread_nxu_hpp = new Q(CPU_NXU+"thread_pd.hpp");
static final Q _vm_version_nxu_cpp = new Q(CPU_NXU+"vm_version_nxu.cpp");
static final Q _vm_version_nxu_hpp = new Q(CPU_NXU+"vm_version_pd.hpp");
static final Q _vtableStubs_nxu_cpp = new Q(CPU_NXU+"vtableStubs_nxu.cpp");
// --- Some HotSpot OS-specific source files
static final String INCLUDES_AZTEK = " -I "+SANDBOX+"/aztek/include/";
static final String OS_AZTEK = "src/os/aztek/vm/";
static final Q _attachListener_aztek_cpp = new Q(OS_AZTEK+"attachListener_aztek.cpp");
static final Q _c1_globals_aztek_hpp = new Q(OS_AZTEK+"c1_globals_os.hpp");
static final Q _c2_globals_aztek_hpp = new Q(OS_AZTEK+"c2_globals_os.hpp");
static final Q _externalProfiler_aztek_cpp = new Q(OS_AZTEK+"externalProfiler_aztek.cpp");
static final Q _global_defs_aztek_hpp = new Q(OS_AZTEK+"globalDefinitions_os.hpp");
static final Q _globals_aztek_hpp = new Q(OS_AZTEK+"globals_os.hpp");
static final Q _hpi_aztek_cpp = new Q(OS_AZTEK+"hpi_aztek.cpp");
static final Q _hpi_aztek_hpp = new Q(OS_AZTEK+"hpi_os.hpp");
static final Q _jvm_aztek_cpp = new Q(OS_AZTEK+"jvm_aztek.cpp");
static final Q _jvm_aztek_h = new Q(OS_AZTEK+"jvm_os.h");
static final Q _mutex_aztek_cpp = new Q(OS_AZTEK+"mutex_aztek.cpp");
static final Q _osThread_aztek_cpp = new Q(OS_AZTEK+"osThread_aztek.cpp");
static final Q _osThread_aztek_hpp = new Q(OS_AZTEK+"osThread_os.hpp");
static final Q _os_aztek_cpp = new Q(OS_AZTEK+"os_aztek.cpp");
static final Q _os_aztek_hpp = new Q(OS_AZTEK+"os_os.hpp");
static final Q _os_aztek_inline_hpp = new Q(OS_AZTEK+"os_os.inline.hpp");
static final Q _thread_aztek_inline_hpp = new Q(OS_AZTEK+"thread_os.inline.hpp");
static final Q _vmError_aztek_cpp = new Q(OS_AZTEK+"vmError_aztek.cpp");
static final String INCLUDES_ACAPULCO_PORT = " -I acapulco_port/acapulco/include/";
static final String INCLUDES_ACAPULCO = " -I "+SANDBOX+"/aztek/include/";
static final String OS_ACAPULCO = "src/os/acapulco/vm/";
static final Q _attachListener_acapulco_cpp = new Q(OS_ACAPULCO+"attachListener_acapulco.cpp");
static final Q _c1_globals_acapulco_hpp = new Q(OS_ACAPULCO+"c1_globals_os.hpp");
static final Q _c2_globals_acapulco_hpp = new Q(OS_ACAPULCO+"c2_globals_os.hpp");
static final Q _externalProfiler_acapulc




