r4838@macbookpro: aamine | 2009-05-13 01:23:44 +0900

* net/loveruby/cflat/utils/CommandUtils.java: accept a list of string instead of CommandArg.
 * net/loveruby/cflat/sysdep/Linker.java: ditto.
 * net/loveruby/cflat/sysdep/LinkerOptions.java: ditto.
 * net/loveruby/cflat/sysdep/GNULinker.java: ditto.
 * net/loveruby/cflat/sysdep/AssemblerOptions.java: ditto.
 * net/loveruby/cflat/sysdep/GNUAssembler.java: ditto.
 * net/loveruby/cflat/utils/CommandArgStr.java -> compiler/LdOption.java
 * net/loveruby/cflat/utils/CommandArg.java -> compiler/LdArg.java
 * net/loveruby/cflat/compiler/SourceFile.java: CommandArg -> LdArg.
 * net/loveruby/cflat/compiler/Compiler.java: ditto.
 * net/loveruby/cflat/compiler/Options.java: ditto.
 


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4209 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2009-05-12 18:24:46 +00:00
parent 5576b83389
commit 9c8af78a97
13 changed files with 164 additions and 169 deletions

View File

@ -1,3 +1,30 @@
Wed May 13 01:22:12 2009 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/utils/CommandUtils.java: accept a list of
string instead of CommandArg.
* net/loveruby/cflat/sysdep/Linker.java: ditto.
* net/loveruby/cflat/sysdep/LinkerOptions.java: ditto.
* net/loveruby/cflat/sysdep/GNULinker.java: ditto.
* net/loveruby/cflat/sysdep/AssemblerOptions.java: ditto.
* net/loveruby/cflat/sysdep/GNUAssembler.java: ditto.
* net/loveruby/cflat/utils/CommandArgStr.java ->
compiler/LdOption.java
* net/loveruby/cflat/utils/CommandArg.java -> compiler/LdArg.java
* net/loveruby/cflat/compiler/SourceFile.java: CommandArg ->
LdArg.
* net/loveruby/cflat/compiler/Compiler.java: ditto.
* net/loveruby/cflat/compiler/Options.java: ditto.
Mon May 11 03:17:32 2009 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/Compiler.java: objectify assembler.

View File

@ -197,13 +197,13 @@ public class Compiler {
}
private void generateExecutable(Options opts) throws IPCException {
opts.linker(errorHandler)
.generateExecutable(opts.exeFileName(), opts.ldOptions());
opts.linker(errorHandler).generateExecutable(
opts.exeFileName(), opts.ldArgs(), opts.ldOptions());
}
private void generateSharedLibrary(Options opts) throws IPCException {
opts.linker(errorHandler)
.generateSharedLibrary(opts.soFileName(), opts.ldOptions());
opts.linker(errorHandler).generateSharedLibrary(
opts.soFileName(), opts.ldArgs(), opts.ldOptions());
}
private void writeFile(String path, String str)

View File

@ -0,0 +1,6 @@
package net.loveruby.cflat.compiler;
interface LdArg {
String toString();
boolean isSourceFile();
}

View File

@ -1,9 +1,9 @@
package net.loveruby.cflat.utils;
package net.loveruby.cflat.compiler;
public class CommandArgStr implements CommandArg {
class LdOption implements LdArg {
private String arg;
public CommandArgStr(String arg) {
LdOption(String arg) {
this.arg = arg;
}

View File

@ -3,15 +3,16 @@ import net.loveruby.cflat.parser.LibraryLoader;
import net.loveruby.cflat.type.TypeTable;
import net.loveruby.cflat.asm.*;
import net.loveruby.cflat.sysdep.*;
import net.loveruby.cflat.sysdep.X86Linux;
import net.loveruby.cflat.utils.CommandArg;
import net.loveruby.cflat.utils.ErrorHandler;
import net.loveruby.cflat.exception.*;
import java.util.*;
import java.io.*;
import java.util.List;
import java.util.ListIterator;
import java.util.ArrayList;
import java.util.Arrays;
import java.io.PrintStream;
class Options {
CompilerMode mode;
CompilerMode mode = CompilerMode.Link;
LibraryLoader loader = new LibraryLoader();
Platform platform = new X86Linux();
String outputFileName;
@ -20,6 +21,8 @@ class Options {
CodeGeneratorOptions genOptions = new CodeGeneratorOptions();
AssemblerOptions asOptions = new AssemblerOptions();
LinkerOptions ldOptions = new LinkerOptions();
List<LdArg> ldArgs;
List<SourceFile> sourceFiles;
CompilerMode mode() {
return mode;
@ -45,29 +48,20 @@ class Options {
return getOutputFileName(".so");
}
static private final String DEFAULT_OUTPUT_FILE_NAME = "a.out";
private String getOutputFileName(String newExt) {
if (outputFileName != null) {
return outputFileName;
}
List<SourceFile> srcs = sourceFiles();
if (srcs.size() == 1) {
return srcs.get(0).linkedFileName(this, newExt);
if (sourceFiles.size() == 1) {
return sourceFiles.get(0).linkedFileName(this, newExt);
}
else {
return "a.out";
return DEFAULT_OUTPUT_FILE_NAME;
}
}
private List<SourceFile> sourceFiles() {
List<SourceFile> result = new ArrayList<SourceFile>();
for (CommandArg arg : ldOptions.args()) {
if (arg.isSourceFile()) {
result.add((SourceFile)arg);
}
}
return result;
}
String outputFileName() {
return this.outputFileName;
}
@ -108,13 +102,21 @@ class Options {
return ldOptions;
}
List<String> ldArgs() {
List<String> result = new ArrayList<String>();
for (LdArg arg : ldArgs) {
result.add(arg.toString());
}
return result;
}
boolean isGeneratingSharedLibrary() {
return ldOptions.generatingSharedLibrary;
}
/** Returns List<SourceFile>. */
List<SourceFile> parse(List<String> argsList) {
List<SourceFile> srcs = new ArrayList<SourceFile>();
sourceFiles = new ArrayList<SourceFile>();
ldArgs = new ArrayList<LdArg>();
ListIterator<String> args = argsList.listIterator();
while (args.hasNext()) {
String arg = args.next();
@ -166,7 +168,7 @@ class Options {
asOptions.addArg(nextArg(arg, args));
}
else if (arg.equals("-static")) {
ldOptions.addArg(arg);
addLdArg(arg);
}
else if (arg.equals("-shared")) {
ldOptions.generatingSharedLibrary = true;
@ -175,18 +177,18 @@ class Options {
ldOptions.generatingPIE = true;
}
else if (arg.equals("--readonly-plt")) {
ldOptions.addArg("-z");
ldOptions.addArg("combreloc");
ldOptions.addArg("-z");
ldOptions.addArg("now");
ldOptions.addArg("-z");
ldOptions.addArg("relro");
addLdArg("-z");
addLdArg("combreloc");
addLdArg("-z");
addLdArg("now");
addLdArg("-z");
addLdArg("relro");
}
else if (arg.startsWith("-L")) {
ldOptions.addArg("-L" + getOptArg(arg, args));
addLdArg("-L" + getOptArg(arg, args));
}
else if (arg.startsWith("-l")) {
ldOptions.addArg("-l" + getOptArg(arg, args));
addLdArg("-l" + getOptArg(arg, args));
}
else if (arg.equals("-nostartfiles")) {
ldOptions.noStartFiles = true;
@ -200,11 +202,11 @@ class Options {
}
else if (arg.startsWith("-Wl,")) {
for (String opt : parseCommaSeparatedOptions(arg)) {
ldOptions.addArg(opt);
addLdArg(opt);
}
}
else if (arg.equals("-Xlinker")) {
ldOptions.addArg(nextArg(arg, args));
addLdArg(nextArg(arg, args));
}
else if (arg.equals("-v")) {
verbose = true;
@ -225,33 +227,42 @@ class Options {
}
}
else {
// source file
addSourceFile(srcs, arg);
ldArgs.add(new SourceFile(arg));
}
}
// args has more arguments when "--" is appeared.
while (args.hasNext()) {
addSourceFile(srcs, args.next());
ldArgs.add(new SourceFile(args.next()));
}
if (srcs.isEmpty()) parseError("no input file");
if (mode == null) {
mode = CompilerMode.Link;
sourceFiles = selectSourceFiles(ldArgs);
if (sourceFiles.isEmpty()) {
parseError("no input file");
}
if (! isLinkRequired() && outputFileName != null && srcs.size() > 1) {
parseError("-o option requires only 1 input not on linking");
if (outputFileName != null
&& sourceFiles.size() > 1
&& ! isLinkRequired()) {
parseError("-o option requires only 1 input (except linking)");
}
return srcs;
return sourceFiles;
}
private void parseError(String msg) {
throw new OptionParseError(msg);
}
private void addSourceFile(List<SourceFile> srcs, String sourceName) {
SourceFile src = new SourceFile(sourceName);
srcs.add(src);
// Original argument order does matter when linking.
ldOptions.addArg(src);
private void addLdArg(String arg) {
ldArgs.add(new LdOption(arg));
}
private List<SourceFile> selectSourceFiles(List<LdArg> args) {
List<SourceFile> result = new ArrayList<SourceFile>();
for (LdArg arg : args) {
if (arg.isSourceFile()) {
result.add((SourceFile)arg);
}
}
return result;
}
private String getOptArg(String opt, ListIterator<String> args) {

View File

@ -1,66 +1,72 @@
package net.loveruby.cflat.compiler;
import net.loveruby.cflat.utils.CommandArg;
import java.io.File;
// package private
class SourceFile implements CommandArg {
class SourceFile implements LdArg {
private String originalName;
private String currentName;
public SourceFile(String name) {
SourceFile(String name) {
this.originalName = name;
this.currentName = name;
}
public String name() {
public boolean isSourceFile() {
return true;
}
public String toString() {
return currentName;
}
String name() {
return originalName();
}
public String originalName() {
String originalName() {
return this.originalName;
}
public String currentName() {
String currentName() {
return this.currentName;
}
public void setCurrentName(String name) {
void setCurrentName(String name) {
this.currentName = name;
}
public boolean isCflatSource() {
boolean isCflatSource() {
return extName(currentName).equals(".cb");
}
public boolean isAssemblySource() {
boolean isAssemblySource() {
return extName(currentName).equals(".s");
}
public boolean isObjectFile() {
boolean isObjectFile() {
return extName(currentName).equals(".o");
}
public boolean isSharedLibrary() {
boolean isSharedLibrary() {
return extName(currentName).equals(".so");
}
public boolean isStaticLibrary() {
boolean isStaticLibrary() {
return extName(currentName).equals(".a");
}
public boolean isExecutable() {
boolean isExecutable() {
return extName(currentName).equals("");
}
public String asmFileName(Options opts) {
String asmFileName(Options opts) {
return or(opts.outputFileNameFor(CompilerMode.Compile), replaceExt(".s"));
}
public String objFileName(Options opts) {
String objFileName(Options opts) {
return or(opts.outputFileNameFor(CompilerMode.Assemble), replaceExt(".o"));
}
public String linkedFileName(Options opts, String newExt) {
String linkedFileName(Options opts, String newExt) {
return or(opts.outputFileName, replaceExt(newExt));
}
@ -90,12 +96,4 @@ class SourceFile implements CommandArg {
if (idx < 0) return "";
return path.substring(idx);
}
public boolean isSourceFile() {
return true;
}
public String toString() {
return currentName;
}
}

View File

@ -1,18 +1,12 @@
package net.loveruby.cflat.sysdep;
import net.loveruby.cflat.utils.CommandArg;
import net.loveruby.cflat.utils.CommandArgStr;
import java.util.List;
import java.util.ArrayList;
public class AssemblerOptions {
public boolean verbose = false;
List<CommandArg> args = new ArrayList<CommandArg>();
List<String> args = new ArrayList<String>();
public void addArg(String a) {
args.add(new CommandArgStr(a));
}
public void addArg(CommandArg a) {
args.add(a);
}
}

View File

@ -1,7 +1,5 @@
package net.loveruby.cflat.sysdep;
import net.loveruby.cflat.utils.CommandUtils;
import net.loveruby.cflat.utils.CommandArg;
import net.loveruby.cflat.utils.CommandArgStr;
import net.loveruby.cflat.utils.ErrorHandler;
import net.loveruby.cflat.exception.IPCException;
import java.util.List;
@ -16,16 +14,12 @@ class GNUAssembler implements Assembler {
public void assemble(String srcPath, String destPath,
AssemblerOptions opts) throws IPCException {
List<CommandArg> cmd = new ArrayList<CommandArg>();
cmd.add(arg("as"));
List<String> cmd = new ArrayList<String>();
cmd.add("as");
cmd.addAll(opts.args);
cmd.add(arg("-o"));
cmd.add(arg(destPath));
cmd.add(arg(srcPath));
cmd.add("-o");
cmd.add(destPath);
cmd.add(srcPath);
CommandUtils.invoke(cmd, errorHandler, opts.verbose);
}
private CommandArg arg(String a) {
return new CommandArgStr(a);
}
}

View File

@ -1,7 +1,5 @@
package net.loveruby.cflat.sysdep;
import net.loveruby.cflat.utils.CommandUtils;
import net.loveruby.cflat.utils.CommandArg;
import net.loveruby.cflat.utils.CommandArgStr;
import net.loveruby.cflat.utils.ErrorHandler;
import net.loveruby.cflat.exception.IPCException;
import java.util.List;
@ -20,56 +18,52 @@ class GNULinker implements Linker {
this.errorHandler = errorHandler;
}
public void generateExecutable(
String destPath, LinkerOptions opts) throws IPCException {
List<CommandArg> cmd = new ArrayList<CommandArg>();
cmd.add(arg("ld"));
cmd.add(arg("-dynamic-linker"));
cmd.add(arg(DYNAMIC_LINKER));
public void generateExecutable(String destPath,
List<String> args, LinkerOptions opts) throws IPCException {
List<String> cmd = new ArrayList<String>();
cmd.add("ld");
cmd.add("-dynamic-linker");
cmd.add(DYNAMIC_LINKER);
if (opts.generatingPIE) {
cmd.add(arg("-pie"));
cmd.add("-pie");
}
if (! opts.noStartFiles) {
cmd.add(arg(opts.generatingPIE
cmd.add(opts.generatingPIE
? C_RUNTIME_START_PIE
: C_RUNTIME_START));
cmd.add(arg(C_RUNTIME_INIT));
: C_RUNTIME_START);
cmd.add(C_RUNTIME_INIT);
}
cmd.addAll(opts.args);
cmd.addAll(args);
if (! opts.noDefaultLibs) {
cmd.add(arg("-lc"));
cmd.add(arg("-lcbc"));
cmd.add("-lc");
cmd.add("-lcbc");
}
if (! opts.noStartFiles) {
cmd.add(arg(C_RUNTIME_FINI));
cmd.add(C_RUNTIME_FINI);
}
cmd.add(arg("-o"));
cmd.add(arg(destPath));
cmd.add("-o");
cmd.add(destPath);
CommandUtils.invoke(cmd, errorHandler, opts.verbose);
}
public void generateSharedLibrary(
String destPath, LinkerOptions opts) throws IPCException {
List<CommandArg> cmd = new ArrayList<CommandArg>();
cmd.add(arg("ld"));
cmd.add(arg("-shared"));
public void generateSharedLibrary(String destPath,
List<String> args, LinkerOptions opts) throws IPCException {
List<String> cmd = new ArrayList<String>();
cmd.add("ld");
cmd.add("-shared");
if (! opts.noStartFiles) {
cmd.add(arg(C_RUNTIME_INIT));
cmd.add(C_RUNTIME_INIT);
}
cmd.addAll(opts.args);
cmd.addAll(args);
if (! opts.noDefaultLibs) {
cmd.add(arg("-lc"));
cmd.add(arg("-lcbc"));
cmd.add("-lc");
cmd.add("-lcbc");
}
if (! opts.noStartFiles) {
cmd.add(arg(C_RUNTIME_FINI));
cmd.add(C_RUNTIME_FINI);
}
cmd.add(arg("-o"));
cmd.add(arg(destPath));
cmd.add("-o");
cmd.add(destPath);
CommandUtils.invoke(cmd, errorHandler, opts.verbose);
}
private CommandArg arg(String a) {
return new CommandArgStr(a);
}
}

View File

@ -1,7 +1,10 @@
package net.loveruby.cflat.sysdep;
import net.loveruby.cflat.exception.IPCException;
import java.util.List;
public interface Linker {
void generateExecutable(String destPath, LinkerOptions opts) throws IPCException;
void generateSharedLibrary(String destPath, LinkerOptions opts) throws IPCException;
void generateExecutable(String destPath,
List<String> args, LinkerOptions opts) throws IPCException;
void generateSharedLibrary(String destPath,
List<String> args, LinkerOptions opts) throws IPCException;
}

View File

@ -1,8 +1,4 @@
package net.loveruby.cflat.sysdep;
import net.loveruby.cflat.utils.CommandArg;
import net.loveruby.cflat.utils.CommandArgStr;
import java.util.List;
import java.util.ArrayList;
public class LinkerOptions {
public boolean generatingSharedLibrary = false;
@ -10,17 +6,4 @@ public class LinkerOptions {
public boolean noStartFiles = false;
public boolean noDefaultLibs = false;
public boolean verbose = false;
List<CommandArg> args = new ArrayList<CommandArg>();
public void addArg(String a) {
args.add(new CommandArgStr(a));
}
public void addArg(CommandArg a) {
args.add(a);
}
public List<CommandArg> args() {
return this.args;
}
}

View File

@ -1,6 +0,0 @@
package net.loveruby.cflat.utils;
public interface CommandArg {
public String toString();
public boolean isSourceFile();
}

View File

@ -5,13 +5,13 @@ import java.util.ArrayList;
import java.io.*;
abstract public class CommandUtils {
static public void invoke(List<CommandArg> cmdArgs,
static public void invoke(List<String> cmdArgs,
ErrorHandler errorHandler, boolean debug) throws IPCException {
if (debug) {
dumpCommand(cmdArgs);
}
try {
String[] cmd = getStrings(cmdArgs);
String[] cmd = cmdArgs.toArray(new String[] {});
Process proc = Runtime.getRuntime().exec(cmd);
proc.waitFor();
passThrough(proc.getInputStream());
@ -32,20 +32,11 @@ abstract public class CommandUtils {
}
}
static private String[] getStrings(List<CommandArg> list) {
String[] result = new String[list.size()];
int idx = 0;
for (CommandArg arg : list) {
result[idx++] = arg.toString();
}
return result;
}
static private void dumpCommand(List<CommandArg> args) {
static private void dumpCommand(List<String> args) {
String sep = "";
for (CommandArg arg : args) {
for (String arg : args) {
System.out.print(sep); sep = " ";
System.out.print(arg.toString());
System.out.print(arg);
}
System.out.println("");
}