diff --git a/internal/pkg/buildcfg/confgen/gen.go b/internal/pkg/buildcfg/confgen/gen.go index d492e4bf32..163610a14d 100644 --- a/internal/pkg/buildcfg/confgen/gen.go +++ b/internal/pkg/buildcfg/confgen/gen.go @@ -30,20 +30,62 @@ type Define struct { // WriteLine writes a line of configuration. func (d Define) WriteLine() (s string) { - s = "const " + d.Words[1] + " = " + d.Words[2] - - if len(d.Words) > 3 { + if len(d.Words) == 3 && len(d.Words[2]) == 1 { + s = "const " + d.Words[1] + " = " + d.Words[2] + } else { + s = d.Words[2] + for _, w := range d.Words[3:] { + s += " + " + w + } + s = "var " + d.Words[1] + " = RelocatePath(" + s + ")" } - for _, w := range d.Words[3:] { - s += " + " + w - } return s } var confgenTemplate = template.Must(template.New("").Parse(`// Code generated by go generate; DO NOT EDIT. package buildcfg -{{ range $i, $d := . }} + +import ( + "os" + "path/filepath" + "strings" +) + +func RelocatePath(original string) (string) { + if ! strings.HasPrefix(original, "{{.Prefix}}") { + return original + } + + executablePath, err := os.Executable() + if err != nil { + panic(err) + } + prefix := filepath.Dir(executablePath) + + switch filepath.Base(executablePath) { + case "singularity": + // PREFIX/bin/singularity + prefix = filepath.Dir(prefix) + case "starter": + // PREFIX/libexec/singularity/bin/starter + prefix = filepath.Dir(filepath.Dir(filepath.Dir(prefix))) + case "bash_completion": + return original + default: + panic("Unrecognized executable: " + executablePath) + } + + relativePath, err := filepath.Rel("{{.Prefix}}", original) + if err != nil { + panic(err) + } + + result := filepath.Join(prefix, relativePath) + return result +} + +{{ range $i, $d := .Defines }} {{$d.WriteLine -}} {{end}} `)) @@ -64,12 +106,22 @@ func main() { header := []Define{} s := bufio.NewScanner(bytes.NewReader(inFile)) + prefix := "" for s.Scan() { d := parseLine(s.Text()) if len(d.Words) > 2 && d.Words[0] == "#define" { + if d.Words[1] == "PREFIX" { + if len(d.Words) != 3 { + panic("Expected PREFIX to contain 3 elements") + } + prefix = d.Words[2] + } header = append(header, d) } } + if prefix == "" { + panic("Failed to find value of PREFIX") + } if goBuildTags := os.Getenv("GO_BUILD_TAGS"); goBuildTags != "" { d := Define{ @@ -82,5 +134,12 @@ func main() { header = append(header, d) } - confgenTemplate.Execute(outFile, header) + data := struct { + Prefix string + Defines []Define + }{ + prefix[1 : len(prefix)-1], + header, + } + confgenTemplate.Execute(outFile, data) } diff --git a/internal/pkg/plugin/meta.go b/internal/pkg/plugin/meta.go index 079ab3cc06..b22114a578 100644 --- a/internal/pkg/plugin/meta.go +++ b/internal/pkg/plugin/meta.go @@ -20,7 +20,7 @@ import ( "github.com/sylabs/singularity/pkg/sylog" ) -const ( +var ( // rootDir is the root directory for the plugin // installation, typically located within LIBEXECDIR. rootDir = buildcfg.PLUGIN_ROOTDIR