guix-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Patch] address@hidden


From: Matthew Jordan
Subject: Re: [Patch] address@hidden
Date: Sun, 29 May 2016 14:48:00 -0400
User-agent: mu4e 0.9.13; emacs 24.5.1

Hi Andy,

And thanks for code snippet, I'll look at and see how I can integrate it
with the current patches.  I'm new to both go and guile, so there is
still much to learn.

Thanks again!

-- 
Matthew Jordan
Sent with my mu4e


Andy Wingo writes:

> Hi!
>
> I also took a look at this package over the weekend but was away from
> the internet.  It turns out that what is needed is to add "-rpath"
> invocations to Go itself.  The issue is that Go binaries are still
> dynamically linked to libgcc_s, but of course there is no useful default
> search path in which the run-time part of the dynamic linker will find
> libgcc_s.so.1.
>
> Here's a build phase that works for go-1.4:
>
>     (arguments
>      `(#:phases
>        (modify-phases %standard-phases
>          (delete 'configure)
>          (add-after 'patch-generated-file-shebangs 'chdir
>            (lambda _ (chdir "src")))
>          (add-before 'build 'prebuild
>            (lambda* (#:key inputs outputs #:allow-other-keys)
>              (define-syntax-rule (disable-go-tests ((file) test ...) ...)
>                (begin
>                  (substitute* file
>                    (((string-append "Test" test))
>                     (string-append "DisabledTest" test))
>                    ...)
>                  ...))
>              (let* ((gccgo  (assoc-ref inputs "gccgo"))
>                     (gcclib (string-append (assoc-ref inputs "gcc:lib") 
> "/lib"))
>                     (ld (string-append
>                          (assoc-ref inputs "glibc") "/lib"))
>                     (loader (car (find-files ld "^ld-linux.+")))
>                     (net-base (assoc-ref inputs "net-base"))
>                     (tzdata-path
>                      (string-append (assoc-ref inputs "tzdata") 
> "/share/zoneinfo"))
>                     (output (assoc-ref outputs "out")))
>                (substitute* "cmd/go/build.go"
>                  (("cgoldflags := \\[\\]string\\{\\}")
>                   (string-append "cgoldflags := []string{"
>                                  "\"-rpath=" gcclib "\""
>                                  "}"))
>                  (("ldflags := buildLdflags")
>                   (string-append
>                    "ldflags := buildLdflags\n"
>                    "ldflags = append(ldflags, \"-r\")\n"
>                    "ldflags = append(ldflags, \"" gcclib "\")\n")))
>                ;; Disabling net/ tests
>                (delete-file "net/multicast_test.go")
>                (delete-file "net/parse_test.go")
>                (delete-file "net/port_test.go")
>                (substitute* "os/os_test.go"
>                  (("/usr/bin") (getcwd))
>                  (("/bin/pwd") (which "pwd")))
>                (disable-go-tests
>                 (("os/os_test.go") "Hostname")
>                 (("net/net_test.go") "ShutdownUnix")
>                 (("net/dial_test.go") "DialTimeout")
>                 (("time/format_test.go") "ParseInSydney")
>                 (("os/exec/exec_test.go")
>                  "Echo" "CommandRelativeName" "CatStdin" "CatGoodAndBadFile"
>                  "ExitStatus" "Pipes" "StdinClose" "ExtraFiles")
>                 (("syscall/syscall_unix_test.go") "PassFD"))
>                (substitute* "net/lookup_unix.go"
>                  (("/etc/protocols") (string-append net-base 
> "/etc/protocols")))
>                (substitute* "time/zoneinfo_unix.go"
>                  (("/usr/share/zoneinfo/") tzdata-path))
>                (substitute* (find-files "cmd" "asm.c")
>                  (("/lib/ld-linux.*\\.so\\.[0-9]") loader)))))
>          (replace 'build
>            (lambda* (#:key inputs outputs #:allow-other-keys)
>              (let* ((gccgo  (assoc-ref inputs "gccgo"))
>                     (output (assoc-ref outputs "out")))
>                (setenv "CC" (which "gcc"))
>                (setenv "GOOS" "linux")
>                (setenv "GOROOT" (getcwd))
>                (setenv "GOROOT_BOOTSTRAP" gccgo)
>                (setenv "GOROOT_FINAL" output)
>                (setenv "CGO_ENABLED" "1")
>                (zero? (system* "sh" "all.bash")))))
>          (replace 'install
>            (lambda* (#:key outputs #:allow-other-keys)
>              (let* ((output (assoc-ref outputs "out"))
>                     (docs   (assoc-ref outputs "doc"))
>                     (tests  (assoc-ref outputs "tests")))
>                (copy-recursively "../test" tests)
>                (delete-file-recursively "../test")
>                (copy-recursively "../api" (string-append docs "/api"))
>                (delete-file-recursively "../api")
>                (copy-recursively "../doc" (string-append docs "/doc"))
>                (delete-file-recursively "../doc")
>                (copy-recursively "../" output)))))
>        #:tests? #f))
>
> Please feel free to take this as yours, if you like :)
>
> For go 1.5, it's more complicated because of the new ability in Go to
> make shared libraries.  I use this substitute* line:
>
>                  (substitute* "cmd/go/build.go"
>                  (("cgoldflags := \\[\\]string\\{\\}")
>                   (string-append "cgoldflags := []string{"
>                                  "\"-rpath=" gcclib "\""
>                                  "}"))
>                  (("ldflags = setextld\\(ldflags, compiler\\)")
>                   (string-append
>                    "ldflags = setextld(ldflags, compiler)\n"
>                    "ldflags = append(ldflags, \"-r\")\n"
>                    "ldflags = append(ldflags, \"" gcclib "\")\n"))
>                  (("\"-lgcc_s\", ")
>                   (string-append
>                    "\"-Wl,-rpath=" gcclib "\", \"-lgcc_s\", ")))
>
> But then tests fail:
>
>   ##### ../misc/cgo/testshared
>   --- FAIL: TestTrivialExecutable (0.07s)
>   shared_test.go:40: executing ./bin/trivial (trivial executable) failed exit 
> status 127:
>   ./bin/trivial: error while loading shared libraries: 
> libruntime,sync-atomic.so: cannot open shared object file: No such file or 
> directory
>   shared_test.go:305: ./bin/trivial does not have rpath 
> /tmp/guix-build-go-1.5.4.drv-6/go/pkg/linux_amd64_5577006791947779410_dynlink
>   --- FAIL: TestCgoExecutable (0.54s)
>   shared_test.go:40: executing ./bin/execgo (cgo executable) failed exit 
> status 127:
>   ./bin/execgo: error while loading shared libraries: 
> libruntime,sync-atomic.so: cannot open shared object file: No such file or 
> directory
>   --- FAIL: TestGopathShlib (0.14s)
>   shared_test.go:305: ./bin/exe does not have rpath 
> /tmp/guix-build-go-1.5.4.drv-6/go/pkg/linux_amd64_5577006791947779410_dynlink
>   shared_test.go:305: ./bin/exe does not have rpath 
> /tmp/guix-build-go-1.5.4.drv-6/testshared201992860/pkg/linux_amd64_5577006791947779410_dynlink
>   shared_test.go:40: executing ./bin/exe (executable linked to GOPATH 
> library) failed exit status 127:
>   ./bin/exe: error while loading shared libraries: libruntime,sync-atomic.so: 
> cannot open shared object file: No such file or directory
>   --- FAIL: TestTwoGopathShlibs (0.15s)
>   shared_test.go:40: executing ./bin/exe2 (executable linked to GOPATH 
> library) failed exit status 127:
>   ./bin/exe2: error while loading shared libraries: 
> libruntime,sync-atomic.so: cannot open shared object file: No such file or 
> directory
>   --- FAIL: TestABIChecking (0.09s)
>   shared_test.go:661: exe failed, but without line "abi mismatch detected 
> between the executable and libdep.so"; got output:
>   ./bin/exe: error while loading shared libraries: libruntime,sync-atomic.so: 
> cannot open shared object file: No such file or directory
>
> And indeed.  I modified the test to not delete the build dir and I find
> that while the runtime has the correct -rpath (as you can tell via ldd),
> the built executable does not:
>
> $ ldd bin/trivial
>   linux-vdso.so.1 (0x00007ffdd8bc4000)
>   libruntime,sync-atomic.so => not found
>   libgcc_s.so.1 => 
> /gnu/store/zzz0zjgyd7f515wmbnmb8i1kmrgwh7bq-gcc-4.9.3-lib/lib/libgcc_s.so.1 
> (0x00007f43898c3000)
>   libc.so.6 => 
> /gnu/store/8m00x5x8ykmar27s9248cmhnkdb2n54a-glibc-2.22/lib/libc.so.6 
> (0x00007f438951e000)
>   
> /gnu/store/8m00x5x8ykmar27s9248cmhnkdb2n54a-glibc-2.22/lib/ld-linux-x86-64.so.2
>  (0x00007f4389ad9000)
>   
> I actually had another modification locally to add a -rpath for libc
> too, in case you can't reproduce this.  Not sure.  Anyway I think what's
> going on is this, that in go's linker when you are doing a shared link,
> that it will set -rpath automatically so that the executable has the
> right rpath -- EXCEPT that if you specify the rpath manually on the
> command line, that it disables this behavior.  Most of the rpath logic
> is in cmd/go/build.go, but this bit is in the lower-level tool
> cmd/link/internal/ld.go:
>
>       if Linkshared {
>               seenDirs := make(map[string]bool)
>               seenLibs := make(map[string]bool)
>               addshlib := func(path string) {
>                       dir, base := filepath.Split(path)
>                       if !seenDirs[dir] {
>                               argv = append(argv, "-L"+dir)
>                               if !rpath.set {
>                                       argv = append(argv, "-Wl,-rpath="+dir)
>                               }
>                               seenDirs[dir] = true
>                       }
>                       base = strings.TrimSuffix(base, ".so")
>                       base = strings.TrimPrefix(base, "lib")
>                       if !seenLibs[base] {
>                               argv = append(argv, "-l"+base)
>                               seenLibs[base] = true
>                       }
>               }
>
> Note the "!rpath.set" condition.  Grrrrrrr.
>
> Anyway good luck :)  There's a better solution for go 1.4 at least!
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]