all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Matthew Jordan <matthewjordandevops@yandex.com>
To: Andy Wingo <wingo@igalia.com>
Cc: guix-devel <guix-devel@gnu.org>
Subject: Re: [Patch] go@1.4
Date: Sun, 29 May 2016 14:48:00 -0400	[thread overview]
Message-ID: <87wpmcya3j.fsf@mailerver.i-did-not-set--mail-host-address--so-tickle-me> (raw)
In-Reply-To: <cuc60twu53g.fsf@igalia.com>

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	other threads:[~2016-05-29 18:49 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-28 19:39 [Patch] go@1.4 Matthew Jordan
2016-05-29 17:49 ` Andy Wingo
2016-05-29 18:48   ` Matthew Jordan [this message]
2016-06-02  7:54   ` Andy Wingo
2016-06-02 16:29     ` Matthew Jordan
2016-06-03  8:13       ` Andy Wingo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87wpmcya3j.fsf@mailerver.i-did-not-set--mail-host-address--so-tickle-me \
    --to=matthewjordandevops@yandex.com \
    --cc=guix-devel@gnu.org \
    --cc=wingo@igalia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.