PageRenderTime 355ms CodeModel.GetById 181ms app.highlight 19ms RepoModel.GetById 152ms app.codeStats 1ms

/src/org/ooc/frontend/drivers/Driver.java

http://github.com/nddrylliog/ooc
Java | 214 lines | 163 code | 41 blank | 10 comment | 38 complexity | 2ac840b805899b65d508e29a2c6edfe9 MD5 | raw file
  1package org.ooc.frontend.drivers;
  2
  3import java.io.File;
  4import java.io.IOException;
  5import java.util.ArrayList;
  6import java.util.Collection;
  7import java.util.HashSet;
  8import java.util.List;
  9import java.util.Set;
 10
 11import org.ooc.frontend.BuildParams;
 12import org.ooc.frontend.model.Import;
 13import org.ooc.frontend.model.Include;
 14import org.ooc.frontend.model.Module;
 15import org.ooc.frontend.model.Use;
 16import org.ooc.frontend.model.Include.Mode;
 17import org.ooc.frontend.pkgconfig.PkgConfigFrontend;
 18import org.ooc.frontend.pkgconfig.PkgInfo;
 19import org.ooc.middle.UseDef;
 20import org.ooc.middle.UseDef.Requirement;
 21import org.ooc.utils.FileUtils;
 22import org.ooc.utils.ProcessUtils;
 23import org.ooc.utils.ShellUtils;
 24
 25/**
 26 * Drives the compilation process, e.g. chooses in which order
 27 * files are compiled, optionally checks for timestamps and stuff.
 28 * Great fun.
 29 * 
 30 * @author Amos Wenger
 31 */
 32public abstract class Driver {
 33
 34	public BuildParams params;
 35	
 36	public Driver(BuildParams params) {
 37		super();
 38		this.params = params;
 39	}
 40
 41	public abstract int compile(Module module, String outName) throws Error,
 42			IOException, InterruptedException;
 43	
 44	protected void copyLocalHeaders(Module module, BuildParams params, HashSet<Module> done) {
 45		
 46		if(done.contains(module)) return;
 47		done.add(module);
 48		for(Include inc: module.getIncludes()) {
 49			if(inc.getMode() == Mode.LOCAL) {
 50				try {
 51					File file = params.sourcePath.getFile(module.getPrefixLessPath()).getParentFile();
 52					
 53					File target = new File(params.outPath, inc.getPath() + ".h");
 54					target.getParentFile().mkdirs();
 55					FileUtils.copy(new File(file, inc.getPath() + ".h"),
 56						target);
 57				} catch(Exception e) { e.printStackTrace(); }
 58			}
 59		}
 60		
 61		for(Import imp: module.getAllImports()) {
 62			copyLocalHeaders(imp.getModule(), params, done);
 63		}
 64		
 65	}
 66	
 67	protected void addDeps(Module module, Set<Module> toCompile, Set<String> done) {
 68		
 69		toCompile.add(module);
 70		done.add(module.getPath());
 71		
 72		params.compiler.addObjectFile(new File(params.outPath, module.getPath(".c")).getPath());
 73		
 74		for(Import imp: module.getAllImports()) {
 75			if(!done.contains(imp.getModule().getPath())) {
 76				addDeps(imp.getModule(), toCompile, done);
 77			}
 78		}
 79		
 80	}
 81	
 82	protected Collection<String> getFlagsFromUse(Module module, boolean doLinking) throws IOException, InterruptedException {
 83
 84		Set<String> list = new HashSet<String>();
 85		Set<Module> done = new HashSet<Module>();
 86		getFlagsFromUse(module, list, done, new HashSet<UseDef>(), doLinking);
 87		return list;
 88		
 89	}
 90
 91	protected void getFlagsFromUse(Module module, Set<String> flagsDone,
 92			Set<Module> modulesDone, Set<UseDef> usesDone, boolean doLinking) throws IOException, InterruptedException {
 93
 94		if(modulesDone.contains(module)) return;
 95		modulesDone.add(module);
 96		
 97		for(Use use: module.getUses()) {
 98			UseDef useDef = use.getUseDef();
 99			getFlagsFromUse(useDef, flagsDone, usesDone, doLinking);
100		}
101		
102		for(Import imp: module.getAllImports()) {
103			getFlagsFromUse(imp.getModule(), flagsDone, modulesDone, usesDone, doLinking);
104		}
105		
106	}
107
108	private void getFlagsFromUse(UseDef useDef, Set<String> flagsDone,
109			Set<UseDef> usesDone, boolean doLinking) throws IOException, InterruptedException {
110		
111		if(usesDone.contains(useDef)) return;
112		usesDone.add(useDef);
113		if(doLinking) {
114			compileNasms(useDef.getLibs(), flagsDone);
115		}
116		
117		for(String pkg: useDef.getPkgs()) {
118			PkgInfo info = PkgConfigFrontend.getInfo(pkg);
119			for(String cflag: info.cflags) {
120				if(!flagsDone.contains(cflag)) {
121					flagsDone.add(cflag);
122				}
123			}
124			if(doLinking) {
125				for(String library: info.libraries) {
126					// FIXME lazy
127					String lpath = "-l"+library;
128					if(!flagsDone.contains(lpath)) {
129						flagsDone.add(lpath);
130					}
131				}
132			}
133		}
134		for(String includePath: useDef.getIncludePaths()) {
135			 // FIXME lazy too.
136			String ipath = "-I"+includePath;
137			if(!flagsDone.contains(ipath)) {
138				flagsDone.add(ipath);
139			}
140		}
141		
142		for(String libPath: useDef.getLibPaths()) {
143			 // FIXME lazy too.
144			String lpath = "-L"+libPath;
145			if(!flagsDone.contains(lpath)) {
146				flagsDone.add(lpath);
147			}
148		}
149		
150		for(Requirement req: useDef.getRequirements()) {
151			getFlagsFromUse(req.getUseDef(), flagsDone, usesDone, doLinking);
152		}
153		
154	}
155	
156	public void compileNasms(List<String> nasms, Collection<String> list) throws IOException, InterruptedException {
157		
158		boolean has = false;
159		if(nasms.isEmpty()) return;
160		
161		List<String> reallyNasms = new ArrayList<String>();
162		for(String nasm: nasms) {
163			if(nasm.endsWith(".s")) {
164				reallyNasms.add(nasm);
165				has = true;
166			}
167		}
168		
169		if(has) {
170			if(params.verbose) {
171				System.out.println("Should compile nasms "+reallyNasms);
172			}
173			List<String> command = new ArrayList<String>();
174			command.add(findExec("nasm").getPath());
175			command.add("-f");
176			command.add("elf");
177			command.addAll(reallyNasms);
178			
179			ProcessBuilder builder = new ProcessBuilder(command);
180			Process process = builder.start();
181			ProcessUtils.redirectIO(process);
182			int code = process.waitFor();
183			if(code != 0) {
184				System.err.println("nasm failed, aborting compilation process");
185				System.exit(code);
186			}
187			
188			for(String nasm: nasms) {
189				if(nasm.endsWith(".s")) {
190					list.add(nasm.substring(0, nasm.length() - 1) + "o");
191				} else {
192					list.add(nasm);
193				}
194			}
195		} else {
196			list.addAll(nasms);
197		}
198		
199	}
200	
201	protected File findExec(String name) throws Error {
202		
203		File execFile = ShellUtils.findExecutable(name);
204		if(execFile == null) {
205			execFile = ShellUtils.findExecutable(name+".exe");
206		}
207		if(execFile == null) {
208			throw new Error(name+" not found :/");
209		}
210		return execFile;
211		
212	}
213	
214}