68

I have a project that provides a library (exports some funcs) and also must provide a command-line interface (there must be an executable file).

Example of directory structure:

whatever.io/
    myproject/
        main.go
        myproject.go

The go compiler needs the package main and func main to start execution. My library needs the package myproject where I put stuff on it. This is what the go tool says when I am building another project that tries to import myproject:

main.go:5:2: found packages myproject (myproject.go) and main (main.go) in $GOPATH/src/whatever.io/myproject

So I believe there is no way to do it.

Should I move the library or the CLI to another package?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
xrash
  • 921
  • 1
  • 7
  • 9

4 Answers4

37

Just move your packages inside a new folder within the same directory of main.go. Remember to import the new package from the reference of the $GOPATH.

Example:

user@user:~/p/go/test/so-multipack$ ls -R
.:
a  main.go

./a:
a.go
user@user:~/p/go/test/so-multipack$ cat main.go 
package main

import (
    "../so-multipack/a"
)
func main(){
    a.Hello()
}
user@user:~/p/go/test/so-multipack$ cat a/a.go 
package a
import (
    "fmt"
)
func Hello(){
    fmt.Println("hello from a")
}
user@user:~/p/go/test/so-multipack$ go run main.go 
hello from a
user@user:~/p/go/test/so-multipack$ go build 
user@user:~/p/go/test/so-multipack$ ls
a  main.go  so-multipack
user@user:~/p/go/test/so-multipack$ 

Useful link:

go build vs go build file.go

Community
  • 1
  • 1
Larry Battle
  • 9,008
  • 4
  • 41
  • 55
  • @xrash, but please consider changing the import in the code of your command to `whatever.io/myproject` -- do not use relative imports (see, [this discussion](http://stackoverflow.com/q/10687627/720999), for one example, and the pointers it contains). – kostix Dec 06 '13 at 17:28
  • Relative paths are ok only if the each package is within their own directory and are referenced from the GOPATH. Otherwise `go build` might fail. – Larry Battle Dec 06 '13 at 18:11
  • It sounds so easy so simple... yet not when you take somebody's .proto files for example and try to build GO files :\ – Martin Kosicky Nov 22 '17 at 12:09
31

You cannot have two packages per directory, hence the error. So the solution as @Larry Battle said to move your myproject.go to a new directory.

From How to write go code

Go code must be kept inside a workspace. A workspace is a directory hierarchy with three directories at its root:

src contains Go source files organized into packages (one package per directory),

pkg contains package objects, and

bin contains executable commands.

Akavall
  • 82,592
  • 51
  • 207
  • 251
18

In most cases, no. However, there is an exception for unit tests.

Working Example:

Here are 2 different packages (mypackage and mypackage_test) in 1 directory (mypackage). The compiler will not complain about this.

mypackage folder:

mypackage/
  foo.go
  foo_test.go

mypackage/foo.go:

package mypackage

func Add(a int, b int) int {
    return a + b
}

mypackage/foo_test.go:

package mypackage_test

// Unit tests...

Rules:

  1. The 2 packages must have the following names:
  • NameOfPackage
  • NameOfPackage + _test
  1. The names of the files in the _test package must end with _test.go

If you're receiving a confusing compiler error along the lines of found packages "foo" and "bar", you've probably broken one or more of these rules.

To clarify rule 1: it is idiomatic for packages (other than main) to have the same name as the directory that contains the files for that directory. But this is not actually a rule that Go's compiler or runtime enforces.

Telemachus
  • 19,459
  • 7
  • 57
  • 79
byxor
  • 5,930
  • 4
  • 27
  • 44
  • unittest "package" code is not compiled into the non-unittest package code. So there is no packaging conflict. – colm.anseo Mar 11 '19 at 15:57
  • But Go Testing says - To write a new test suite, create a file whose name ends _test.go that contains the ) functions as described here. Put the file in the same package as the one being tested. – codenio Sep 05 '19 at 01:34
  • 1
    @AananthK The documentation is slightly outdated; it's missing some information about the `_test` package idiom. Here is a [github issue](https://github.com/golang/go/issues/25223) discussing the piece of documentation you quoted. – byxor Sep 05 '19 at 09:08
  • Thanks for the info @byxor – codenio Sep 05 '19 at 14:58
8

You can't have two golang files in one directory with two packages. So you need to move main.go out of myproject.

the directory structure before move

whatever.io/
    go.mod
    myproject/
        main.go
        myproject.go

After move

whatever.io/
    go.mod
    main.go
    myproject/
        myproject.go

And you need to change your main.go's import path. If the module name is aaa

Before

import "aaa"

Need change to this

import "aaa/myproject"
milkice
  • 455
  • 6
  • 10