2

I'm building the example program from github.com/tarm/serial.

Case 1: It builds ok if the above repo is checked out into $GOPATH/src/github.com/tarm/serial.

Case 2: If the repo is moved under $GOPATH/src/vendor/github.com/tarm/serial the go build command would complain cannot find package "github.com/tarm/serial.

Case 3: The other SO answers suggested to place it under ./vendor so that the package is at ./vendor/github.com/tarm/serial. That does not work either.

The go version is 1.10.4. I believe seeing pages that suggested case 2 or case 3 should work at different times in the past. Has something changed? Do you need to enable the vendor feature somehow?

Details:

The failed command

gotester:~/testdir$ go build uarttest_main.go
uarttest_main.go:5:9: cannot find package "github.com/tarm/serial" in any of:
    /home/gotester/bin/go/src/github.com/tarm/serial (from $GOROOT)
    /home/gotester/testdir/libs/src/github.com/tarm/serial (from $GOPATH)

The source code at ./:

gotester:~/testdir$ cat uarttest_main.go
package main

import (
        "log"
        "github.com/tarm/serial"
)

func main() {
        c := &serial.Config{Name: "COM45", Baud: 115200}
        s, err := serial.OpenPort(c)
        if err != nil {
                log.Fatal(err)
        }

        n, err := s.Write([]byte("test"))
        if err != nil {
                log.Fatal(err)
        }

        buf := make([]byte, 128)
        n, err = s.Read(buf)
        if err != nil {
                log.Fatal(err)
        }
        log.Printf("%q", buf[:n])
}

The ./vendor directory:

gotester:~/testdir$ tree --charset=ascii ./vendor
./vendor
`-- github.com
    `-- tarm
        `-- serial
            |-- basic_test.go
            |-- LICENSE
            |-- README.md
            |-- serial.go
            |-- serial_linux.go
            |-- serial_posix.go
            `-- serial_windows.go

3 directories, 7 files

If run this command now: mv ./vendor/github.com ./libs/src, the build will succeed.

minghua
  • 5,981
  • 6
  • 45
  • 71
  • A `vendor` directory goes inside the directory of another project, for vendoring dependencies of that project. Having it checked out into `GOPATH/src/vendor` doesn't make any sense. What are you actually trying to accomplish? – Adrian Sep 20 '18 at 20:46
  • I'm trying to avoid using packages checked out automatically by `go get` command. I'm assuming packages under the `vendor` directory need to be checked out separately and those are usually frozen to a certain hash. – minghua Sep 20 '18 at 21:08
  • 1
    If `testdir` is your project's root, it needs to be at `GOPATH/src/testdir`, not at `~/testdir`. Then, if you have your dependencies checked out into `GOPATH/src/testdir/vendor`, you'll get the behavior you're looking for. See [Getting started](https://golang.org/doc/install#testing). – Adrian Sep 20 '18 at 21:13
  • The solution: Move the current working directory into `GOPATH/src/` and the problem is solved. Not only the `./vendor` can be used, but also any `vendor` in the parents of the current directory will do. I believe the other posts suggest that even if the `./vendor` is out of `GOPATH/src` tree it should work, though that is not true for some reason in my tests. – minghua Sep 23 '18 at 19:42
  • An implied though is not to mix myproject with the third-party code. It would be best to put the third-party code into the `lib/src` directory, and `myproject` to another place out of the `lib/src` tree. Another [SO](https://stackoverflow.com/questions/37904258/some-questions-regarding-gopath) suggests to make a symbol link `myproject -> ../..`, that might be another option of a nicer solution. I'm just wondering... which would be a better solution. – minghua Oct 09 '18 at 06:51

1 Answers1

7

The Go toolchain expects your projects to be rooted in GOPATH/src. If testdir is your project's root, it needs to be at GOPATH/src/testdir, not at ~/testdir. Then, if you have your dependencies checked out into GOPATH/src/testdir/vendor, you'll get the behavior you're looking for. See Getting started.

Adrian
  • 42,911
  • 6
  • 107
  • 99
  • I know that it is recommended to set GOPATH to the top directory of your project that covers all the source code under the tree. Though GOPATH can be set to contains multiple parts each pointing to a directory, the vendor feature does rely on setting GOPATH to one part only. Is this understanding correct? – minghua Oct 09 '18 at 06:23
  • Or a different interpretation: The `GOPATH` really means only the first part in multiple paths. Is it? – minghua Oct 09 '18 at 06:47
  • https://github.com/golang-standards/project-layout#directories-you-shouldnt-have /src should not be the solution – rufreakde Dec 15 '22 at 10:27