func getPackage(pkgpath string) (*gobuild.Package, error) { var ctx gobuild.Context = gobuild.Default ctx.GOARCH = GOARCH ctx.GOOS = GOOS ctx.BuildTags = append(ctx.BuildTags[:], "llgo") //ctx.Compiler = "llgo" // Attempt to find an overlay package path, // which we'll use in ReadDir below. overlayentries := make(map[string]bool) overlaypkgpath := llgoPkgPrefix + pkgpath overlaypkg, err := ctx.Import(overlaypkgpath, "", gobuild.FindOnly) if err != nil { overlaypkg = nil } // ReadDir is overridden to return a fake ".s" // file for each ".ll" file in the directory. ctx.ReadDir = func(dir string) (fi []os.FileInfo, err error) { fi, err = ioutil.ReadDir(dir) if err != nil { return nil, err } entries := make(map[string]os.FileInfo) for _, info := range fi { entries[info.Name()] = info } // Overlay all files in the overlay package dir. // If we find any .ll files, replace the suffix // with .s. if overlaypkg != nil { fi, err = ioutil.ReadDir(overlaypkg.Dir) } if err == nil { // Check for .ll files in the overlay dir if // we have one, else in the standard package dir. for _, info := range fi { name := info.Name() if strings.HasSuffix(name, ".ll") { name = name[:len(name)-3] + ".s" info = &renamedFileInfo{info, name} } overlayentries[name] = true entries[name] = info } } fi = make([]os.FileInfo, 0, len(entries)) for _, info := range entries { fi = append(fi, info) } return fi, nil } // OpenFile is overridden to return the contents // of the ".ll" file found in ReadDir above. The // returned ReadCloser is wrapped to transform // LLVM IR comments to use "//", as expected by // go/build when looking for build tags. ctx.OpenFile = func(path string) (io.ReadCloser, error) { base := filepath.Base(path) overlay := overlayentries[base] if overlay { if overlaypkg != nil { path = filepath.Join(overlaypkg.Dir, base) } if strings.HasSuffix(path, ".s") { path := path[:len(path)-2] + ".ll" var r io.ReadCloser var err error r, err = os.Open(path) if err == nil { r = build.NewLLVMIRReader(r) } return r, err } } return os.Open(path) } pkg, err := ctx.Import(pkgpath, "", 0) if err != nil { return nil, err } else { if overlaypkg == nil { overlaypkg = pkg } for i, filename := range pkg.GoFiles { pkgdir := pkg.Dir if overlayentries[filename] { pkgdir = overlaypkg.Dir } pkg.GoFiles[i] = path.Join(pkgdir, filename) } for i, filename := range pkg.CFiles { pkgdir := pkg.Dir if overlayentries[filename] { pkgdir = overlaypkg.Dir } pkg.CFiles[i] = path.Join(pkgdir, filename) } for i, filename := range pkg.SFiles { pkgdir := pkg.Dir if overlayentries[filename] { pkgdir = overlaypkg.Dir filename = filename[:len(filename)-2] + ".ll" } else { err := fmt.Errorf("No matching .ll file for %q", filename) return nil, err } pkg.SFiles[i] = path.Join(pkgdir, filename) } } return pkg, nil }