Take a look at this directory structure:
/root
/bar
go.mod
go.sum
main.go
main_test.go
/foo
go.mod
go.sum
main.go
main_test.go
I'd like to debug root/foo/main.go using the delve debugger from the command line. I've tried building the binary using go build, and then using dlv debug <binary> with errors like:
can't load package: package foo is not in GOROOT (/usr/local/opt/go/libexec/src/foo)
exit status 1
Any thoughts?
Your root has two different modules in it, foo and bar. You can't use go build from root to build them, because go build doesn't support nested or multiple modules. You have to run it from the directory go.mod is in, or any of its child directories.
Since Delve simply calls go build for you, the same applies with dlv debug. Try to cd into foo first, and then run dlv debug.
Related
Using Go version go1.17.1 linux/amd64 on my CentOS 7. GOPATH and GOROOT are set in my .bashrc in the order:
export GOPATH="${HOME}/.go"
export GOROOT="/usr/local/go"
export PATH="$PATH:${GOPATH}/bin:${GOROOT}/bin"
Got my project in /home/wsb/_projects/local/parlance:
[wsb#localhost local]$ pwd
/home/wsb/_projects/local
[wsb#localhost local]$ tree
.
└── parlance/
└── main.go
└── utils.go
From the terminal, using go get stores src in /home/wsb/.go/pkg/mod/cache... folder
[wsb#localhost parlance]$ go get -v -u github.com/gorilla/mux
go: downloading github.com/gorilla/mux v1.8.0
github.com/gorilla/mux
[wsb#localhost parlance]$ go build main.go
main.go:3:8: no required module provides package github.com/gin-gonic/gin: go.mod file not found in current directory or any parent directory; see 'go help modules'
[wsb#localhost parlance]$
[root#localhost /]# find -iname gin
./home/wsb/.go/pkg/mod/cache/download/github.com/gin-gonic/gin
Why would it throw error on build?
Using go mod is the key here for managing packages for any particular projects.
go mod is used for installing and tracking external packages outside of packages in GOPATH.
From within existing project root directory parlance we initialize go mod using:
[wsb#localhost parlance]$ go mod parlance
It creates two files within the project root directory: go.mod and go.sum.
Now we can go get any module we will use specifically for our project.
go get github.com/gin-gonic/gin
go get github.com/gofiber/fiber/v2
This creates external package requirement details in go.mod and their respective checksum in go.sum file.
Finally, we can build/run our package like
go build main.go
go run main.go
Following is how the source files are organized
✘-1 ~/Go/src/github.com/krmahadevan/packages
18:24 $ tree .
.
├── sample_main.go
└── sample_one.go
0 directories, 2 files
Here's how the source code looks like:
sample_one.go
package main
var data map[string]string
func init() {
data = make(map[string]string, 0)
}
sample_main.go
package main
import "fmt"
func main() {
data["foo"] = "bar"
fmt.Println(data)
}
Now when I attempt at running sample_main.go I get errors stating that data is undefined.
18:24 $ go run sample_main.go
# command-line-arguments
./sample_main.go:6:2: undefined: data
./sample_main.go:7:14: undefined: data
✘-2 ~/Go/src/github.com/krmahadevan/packages
But when I build the code into a binary and then execute it, it runs fine.
✔ ~/Go/src/github.com/krmahadevan/packages
18:27 $ go build
✔ ~/Go/src/github.com/krmahadevan/packages
18:28 $ ./packages
map[foo:bar]
✔ ~/Go/src/github.com/krmahadevan/packages
I would like to understand why is this behavior ?
Environment:
18:31 $ go version
go version go1.11.4 darwin/amd64
The closest I found was this post : Golang : command-line-arguments undefined: variable
But this post talks about scoped variables that are defined in main.
But my problem statement involves variables defined in another go file and accessed in the main method.
To understand why, read the go command documentation:
Command go
Compile and run Go program
Usage:
go run [build flags] [-exec xprog] package [arguments...]
Run compiles and runs the named main Go package. Typically the package
is specified as a list of .go source files, but it may also be an
import path, file system path, or pattern matching a single known
package, as in 'go run .' or 'go run my/cmd'.
Compile packages and dependencies
Usage:
go build [-o output] [-i] [build flags] [packages]
Build compiles the packages named by the import paths, along with
their dependencies, but it does not install the results.
If the arguments to build are a list of .go files, build treats them
as a list of source files specifying a single package.
For more about specifying packages, see 'go help packages'. For more
about where packages and binaries are installed, run 'go help gopath'.
go run: Typically the package is specified as a list of .go source files.
For your go run example, list the files:
go run sample_main.go sample_one.go
To fix it, just run the following command:
Windows: go run * or go build *
Unix: go run . or go build .
You are going to run it inside the folder of the files you want to use.
I just started writing Go today (so 0 experience), and wonder if Go supports any form of "building all source files" like what mvn install does.
My project structure is
src
`-github.com
`-myproject
|- package1
| `- main.go
`- package2
|- lib1_used_by_main.go
`- lib2_used_by_main.go
When I do
cd src/github.com/myproject
go build
this fails with no buildable Go source files in src/github.com/myproject, which is kind of right, because all source files are in subpackages.
Is there a command to build all subpackages, without listing each of them explicitly?
After you cd to the base directory, use go build ./... Note that there are 3 periods as it is an ellipsis. This will recursively build all subdirectories. Of course you can always do go build path/to/my/base/... from wherever without needing to cd to the directory.
This is very useful for those who use an IDE that relies on the go/pkg directory, such as SublimeText3 with GoSublime. Making changes to a dependency package won't update the autocompletes until you build the package, which places it in the go/pkg directory.
My own projects are broken into a multiple package structure, so I frequently have to go build ./... to update my autocompletion.
I have a single file in the main package called main.go. Because the code isn't reusable I want to separate part of the code in a different file but in the same package.
How do I split the contents of main.go into multiple files without creating a separate package?
I want a directory structure like this:
ls foo
# output:
main.go
bar.go
File: bar.go
package main
import "fmt"
func Bar() {
fmt.Println("Bar")
}
File: main.go
package main
func main() {
Bar()
}
When I run go run main.go, it gives me:
# command-line-arguments
./main.go:4:2: undefined: Bar
Update 26th July 2019 (for go >=1.11)
go run .
Will work on windows as well.
Original answer (for non windows environments)
The code actually works. The problem was that instead of running go run main.go I should run:
go run *.go
Update August 2018, with Go 1.11, a section "Run" states:
The go run command now allows a single import path, a directory name or a pattern matching a single package.
This allows go run pkg or go run dir, most importantly go run .
Original answer Jan. 2015
As mentioned in "How to compile Go program consisting of multiple files?", go run expects a list of files, since it "compiles and runs the main package comprising the named Go source files".
So you certainly can split your main package in several files with go run.
That differs from go build/go install which expect package names (and not go filenames).
A simple go build would produce an executable named after the parent folder.
Note that, as illustrated by this thread, a go run *.go wouldn't work in a Windows CMD session, since the shell doesn't do wildcard expansion.
In my opinion, the best answer to this question is hidden in the comments to the top answer.
Just run this:
go run .
This will run all the files in main package, but will not give an error message like
go run: cannot run *_test.go files (main_test.go)
Kudos to #BarthesSimpson
As mentioned, you can say go run *.go but for Windows you can just list the script files (since *.go won't work) - go run main.go other.go third.go
The first method to do so will be to run
go run *.go
The another method is to generate an exe file
go build
Then run that .exe file
./filename.exe
Multiple options
go run .
go run *.go
make run using Makefile where, add any of the above command as build target.
for testing
go test ./...
make test using Makefile with go test ./... as build target
For Windows install Cygwin and use it instead of command prompt. "go run *.go" will work then.
If you are trying to run multiple files on localhost using gorilla mux in go as per latest version(1.11). Try using any of the following 2 commands.
go install && FolderName -port 8081 .
go build && ./FolderName -port 8081.
Make sure that you are in the source folder ie go/src/FolderName before executing the command in the Terminal.
I have a small program that consists of three files, all belonging to the same package (main). But when I do go build main.go the build doesn't succeed. When it was just one file (main.go), everything worked fine.
Now that I took some effort to separate the code, it looks like the compiler is unable to find the stuff that was taken out of main.go and put into these two other files (that reside in the same directory as the main.go). Which results in undefined 'type' errors.
How to compile this program that consists of multiple files?
New Way (Recommended):
Please take a look at this answer.
Old Way:
Supposing you're writing a program called myprog :
Put all your files in a directory like this
myproject/go/src/myprog/xxx.go
Then add myproject/go to GOPATH
And run
go install myprog
This way you'll be able to add other packages and programs in myproject/go/src if you want.
Reference : http://golang.org/doc/code.html
(this doc is always missed by newcomers, and often ill-understood at first. It should receive the greatest attention of the Go team IMO)
When you separate code from main.go into for example more.go, you simply pass that file to go build/go run/go install as well.
So if you previously ran
go build main.go
you now simply
go build main.go more.go
As further information:
go build --help
states:
If the arguments are a list of .go files,
build treats them as a list of source files specifying a single package.
Notice that go build and go install differ from go run in that the first two state to expect package names as arguments, while the latter expects go files. However, the first two will also accept go files as go install does.
If you are wondering: build will just build the packages/files, install will produce object and binary files in your GOPATH, and run will compile and run your program.
Since Go 1.11+, GOPATH is no longer recommended, the new way is using Go Modules.
Say you're writing a program called simple:
Create a directory:
mkdir simple
cd simple
Create a new module:
go mod init github.com/username/simple
# Here, the module name is: github.com/username/simple.
# You're free to choose any module name.
# It doesn't matter as long as it's unique.
# It's better to be a URL: so it can be go-gettable.
Put all your files in that directory.
Finally, run:
go run .
Alternatively, you can create an executable program by building it:
go build .
# then:
./simple # if you're on xnix
# or, just:
simple # if you're on Windows
For more information, you may read this.
Go has included support for versioned modules as proposed here since 1.11. The initial prototype vgo was announced in February 2018. In July 2018, versioned modules landed in the main Go repository.
In Go 1.14, module support is considered ready for production use, and all users are encouraged to migrate to modules from other dependency management systems.
You could also just run
go build
in your project folder myproject/go/src/myprog
Then you can just type
./myprog
to run your app
It depends on your project structure. But most straightforward is:
go build -o ./myproject ./...
then run ./myproject.
Suppose your project structure looks like this
- hello
|- main.go
then you just go to the project directory and run
go build -o ./myproject
then run ./myproject on shell.
or
# most easiest; builds and run simultaneously
go run main.go
suppose your main file is nested into a sub-directory like a cmd
- hello
|- cmd
|- main.go
then you will run
go run cmd/main.go
You can use
go build *.go
go run *.go
both will work also you may use
go build .
go run .
Yup! That's very straight forward and that's where the package strategy comes into play. there are three ways to my knowledge.
folder structure:
GOPATH/src/
github.com/
abc/
myproject/
adapter/
main.go
pkg1
pkg2
warning: adapter can contain package main only and sun directories
navigate to "adapter" folder. Run:
go build main.go
navigate to "adapter" folder. Run:
go build main.go
navigate to GOPATH/src
recognize relative path to package main, here "myproject/adapter". Run:
go build myproject/adapter
exe file will be created at the directory you are currently at.