func main() { llvm.InitializeAllTargets() llvm.InitializeAllTargetMCs() llvm.InitializeAllTargetInfos() flag.Parse() if *version { displayVersion() } module, err := compileFiles(flag.Args()) if err == nil { defer module.Dispose() if exitCode == 0 { if *dump { module.Dump() } else { err := llvm.WriteBitcodeToFile(module.Module, os.Stdout) if err != nil { fmt.Println(err) } } } } else { //fmt.Printf("llg.Compile(%v) failed: %v", file.Name, err) report(err) } os.Exit(exitCode) }
func link(files []string) error { tempf, err := ioutil.TempFile("", "llgolink") if err != nil { return err } defer os.Remove(tempf.Name()) defer tempf.Close() // TODO? Fix order of modules to be based on package dependency. args := append([]string{"-o", tempf.Name()}, files...) err = exec.Command(llvmlink, args...).Run() if err != nil { return err } module, err := llvm.ParseBitcodeFile(tempf.Name()) if err != nil { return err } defer module.Dispose() f := os.Stdout if outfile != "-" { f, err = os.Create(outfile) if err != nil { return err } defer f.Close() } return llvm.WriteBitcodeToFile(module, f) }
func link(files []string) error { tempf, err := ioutil.TempFile("", "llgolink") if err != nil { return err } defer os.Remove(tempf.Name()) defer tempf.Close() args := append([]string{"-o", tempf.Name()}, files...) err = exec.Command(llvmlink, args...).Run() if err != nil { return err } module, err := llvm.ParseBitcodeFile(tempf.Name()) if err != nil { return err } defer module.Dispose() err = reorderGlobalConstructors(module) if err != nil { return err } f := os.Stdout if outfile != "-" { f, err = os.Create(outfile) if err != nil { return err } defer f.Close() } return llvm.WriteBitcodeToFile(module, f) }
func getRuntimeModuleFile() (string, error) { if runtimemodulefile != "" { return runtimemodulefile, nil } gofiles, llfiles, cfiles, err := getRuntimeFiles() if err != nil { return "", err } var runtimeModule *llgo.Module runtimeModule, err = compileFiles(testCompiler, gofiles, "runtime") defer runtimeModule.Dispose() if err != nil { return "", err } outfile := filepath.Join(tempdir, "runtime.bc") f, err := os.Create(outfile) if err != nil { return "", err } err = llvm.WriteBitcodeToFile(runtimeModule.Module, f) if err != nil { f.Close() return "", err } f.Close() for i, cfile := range cfiles { bcfile := filepath.Join(tempdir, fmt.Sprintf("%d.bc", i)) args := []string{"-c", "-emit-llvm", "-o", bcfile, cfile} if runtime.GOOS != "darwin" { // TODO(q): -g breaks badly on my system at the moment, // so is not enabled on darwin for now args = append([]string{"-g"}, args...) } cmd := exec.Command("clang", args...) cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { return "", fmt.Errorf("clang failed: %s", err) } llfiles = append(llfiles, bcfile) } if llfiles != nil { args := append([]string{"-o", outfile, outfile}, llfiles...) cmd := exec.Command("llvm-link", args...) output, err := cmd.CombinedOutput() if err != nil { err = fmt.Errorf("llvm-link failed: %s", err) fmt.Fprintf(os.Stderr, string(output)) return "", err } } runtimemodulefile = outfile return runtimemodulefile, nil }
func writeObjectFile(m *llgo.Module) error { var outfile *os.File switch *outputFile { case "-": outfile = os.Stdout default: var err error outfile, err = os.Create(*outputFile) if err != nil { return err } } return llvm.WriteBitcodeToFile(m.Module, outfile) }
func getRuntimeModule() (llvm.Module, error) { gofiles, llfiles, err := getRuntimeFiles() if err != nil { return llvm.Module{}, err } var runtimeModule *llgo.Module runtimeModule, err = compileFiles(testCompiler, gofiles, "runtime") if err != nil { return llvm.Module{}, err } if llfiles != nil { outfile, err := ioutil.TempFile("", "runtime.ll") if err != nil { runtimeModule.Dispose() return llvm.Module{}, err } defer func() { outfile.Close() os.Remove(outfile.Name()) }() err = llvm.WriteBitcodeToFile(runtimeModule.Module, outfile) if err != nil { runtimeModule.Dispose() return llvm.Module{}, err } runtimeModule.Dispose() o := outfile.Name() for _, llfile := range llfiles { cmd := exec.Command("llvm-link", "-o", o, o, llfile) output, err := cmd.CombinedOutput() if err != nil { err = fmt.Errorf("llvm-link failed: %s", err) fmt.Fprintf(os.Stderr, string(output)) return llvm.Module{}, err } } runtimeModule.Module, err = llvm.ParseBitcodeFile(o) if err != nil { return llvm.Module{}, err } } return runtimeModule.Module, nil }
func runMainFunction(m *llgo.Module) (output []string, err error) { runtimeModule, err := getRuntimeModuleFile() if err != nil { return } err = llvm.VerifyModule(m.Module, llvm.ReturnStatusAction) if err != nil { return nil, fmt.Errorf("Verification failed: %v", err) } bcpath := filepath.Join(tempdir, "test.bc") bcfile, err := os.Create(bcpath) if err != nil { return nil, err } llvm.WriteBitcodeToFile(m.Module, bcfile) bcfile.Close() cmd := exec.Command("llvm-link", "-o", bcpath, bcpath, runtimeModule) data, err := cmd.CombinedOutput() if err != nil { output = strings.Split(strings.TrimSpace(string(data)), "\n") return output, fmt.Errorf("llvm-link failed: %v", err) } exepath := filepath.Join(tempdir, "test") args := []string{"-pthread", "-o", exepath, bcpath} if runtime.GOOS != "darwin" { // TODO(q): -g breaks badly on my system at the moment, so is not enabled on darwin for now args = append([]string{"-g"}, args...) } cmd = exec.Command("clang++", args...) data, err = cmd.CombinedOutput() if err != nil { output = strings.Split(strings.TrimSpace(string(data)), "\n") return output, fmt.Errorf("clang++ failed: %v", err) } cmd = exec.Command(exepath) data, err = cmd.CombinedOutput() output = strings.Split(strings.TrimSpace(string(data)), "\n") return output, err }
func writeObjectFile(m *llgo.Module) error { var outfile *os.File switch *outputFile { case "-": outfile = os.Stdout default: var err error outfile, err = os.Create(*outputFile) if err != nil { return err } } err := llvm.VerifyModule(m.Module, llvm.ReturnStatusAction) if err != nil { return fmt.Errorf("Verification failed: %v", err) } return llvm.WriteBitcodeToFile(m.Module, outfile) }
func runMainFunction(m *llgo.Module) (output []string, err error) { runtimeModule, err := getRuntimeModuleFile() if err != nil { return } err = llvm.VerifyModule(m.Module, llvm.ReturnStatusAction) if err != nil { err = fmt.Errorf("Verification failed: %v", err) return } bcpath := filepath.Join(tempdir, "test.bc") bcfile, err := os.Create(bcpath) if err != nil { return nil, err } llvm.WriteBitcodeToFile(m.Module, bcfile) bcfile.Close() cmd := exec.Command("llvm-link", "-o", bcpath, bcpath, runtimeModule) cmd.Stderr = os.Stderr err = cmd.Run() if err != nil { return } exepath := filepath.Join(tempdir, "test") cmd = exec.Command("clang++", "-pthread", "-g", "-o", exepath, bcpath) cmd.Stderr = os.Stderr err = cmd.Run() if err != nil { return } cmd = exec.Command(exepath) data, err := cmd.Output() if err != nil { return } output = strings.Split(strings.TrimSpace(string(data)), "\n") return }