Compile Go tip with extra packages - go

I'd like to try out the exp/regexp package. Currently Go tip's ./all.bash command compiles including only exp/regexp/syntax. I've been looking around the makefiles and I see it builds a Make.deps but couldn't figure out how it selects the packages that are included. What should I change to build Go with exp/regexp?

Duh, it was right in front of my eyes! Add the package dir to src/pkg/Makefile:
DIRS=\
archive/tar\
archive/zip\
asn1\
...
exp/regexp\
...

Related

Understanding How to Build Go Source

I am confused about how to layout my Go project and then how to build it. I am reasonably new to Go and believe there was a time <1.13 where the GOPATH was important. I am using 1.14, so I believe I do not have to care about that and GOPATH is not set. I do not (for the moment) host my code on GitHub (which is something various articles assume). I have read a number of things, but it all leaves me more confused:
https://golang.org/cmd/go/#hdr-Compile_packages_and_dependencies
https://www.wolfe.id.au/2020/03/10/starting-a-go-project/
https://talks.golang.org/2014/organizeio.slide#1
I have laid out my project according to this: https://github.com/golang-standards/project-layout. (Except this project seems to use a Makefile. I do not want to write a Makefile. I believe this should all work without a Makefile. I really do not want to write a Makefile.)
Here is the structure:
/src
/cmd
main.go
/internal
helper.go
go.mod
go.mod looks like this:
module mycompany/mymodule
go 1.14
service.go looks as follows
package main // this has to be called 'main'
import (
"mycompany/mymodule/internal/helper"
)
func main () {
helper.greet("Jenny")
}
So, if I am in /src and I run build cmd/service.go I get
cmd/service.go:4:2: package mycompany/mymodule/internal/helper is not in GOROOT (/usr/local/Cellar/go/1.14.5/libexec/src/mycompany/mymodule/internal/helper)
Do I have to compile helper.go first? Manually? Surely not. go build surely should be able to build my entire project, right? Including all the dependencies. Could someone please tell me what I am missing?
When you run go build without specifying file path, it will look for the main function inside any .go files at current directory to start. It doesn't build entire project. But it wouldn't be a problem in this case.
You're importing wrong package. The package name to import must be mycompany/mymodule/internal not mycompany/mymodule/internal/helper.
And to invoke a function inside another package, it must be exposed to outside.
So you have to declare the function greet() as Greet()

go test fails with "can't load package build constraints exclude all Go files"

When I run this command
go test -tags integration $(go list ./... | grep -v /vendor/)
go fails with this for some packages that has all tests marked with // +build !integration
can't load package: build constraints exclude all Go files
Is there a way I can make go test ignore those packages in this case, instead of failing? Thanks
You will only get that error if all the files in the package are excluded by your build constraints, not just the test files. If that's what you want, just add a single package file with no code and the package will still be able to be loaded. For example, many packages put their package level docs in a separate file, which you could use to always have a valid package:
// Package foo does foo
package foo
For whatever it's worth : I was seeing similar errors while building my code. In my case, my main file had // +build go1.13 at the top of it and I was trying to get the file built using go1.12.x. Removing +build go1.13 fixed the issue.
The package you are importing might contain some source files with a conditional complication flag, which is a directive you may find at the top of the files like:
//+build linux darwin windows
package main
import "fmt"
func main() {
fmt.Println("hello")
}
The +build directive followed by one or multiple platforms indicates where this source code is supposed to be compiled on.
Therefore, you can simply try removing this directive to resolve the failure.
It worked for me.
Following on from snowfox's answer, if you can't remove the directive (becuase it was likely put there for a reason), you can still run the test by using the tag that was applied to that file (more info here).
If your file start looks like this:
//go:build bar
package foo
Then you can run the test by running go test ./foo_test.go --tags=bar

"undefined" function declared in another file?

I'm trying to write a basic go program that calls a function on a different file, but a part of the same package. However, it returns:
undefined: NewEmployee
Here is the source code:
main.go:
package main
func main() {
emp := NewEmployee()
}
employee.go:
package main
type Employee struct {
name string
age int
}
func NewEmployee() *Employee {
p := &Employee{}
return p
}
func PrintEmployee (p *Employee) {
return "Hello world!"
}
Please read "How to Write Go Code".
Use go build or go install within the package directory, or supply an import path for the package. Do not use file arguments for build or install.
While you can use file arguments for go run, you should build a package instead, usually with go run ., though you should almost always use go install, or go build.
I just had the same problem in GoLand (which is Intellij IDEA for Go) and worked out a solution. You need to change the Run kind from File to Package or Directory. You can choose this from a drop-down if you go into Run/Edit Configurations.
Eg: for package ~/go/src/a_package, use a Package path of a_package and a Directory of ~/go/src/a_package and Run kind of Package or Directory.
If you're using go run, do go run *.go. It will automatically find all go files in the current working directory, compile and then run your main function.
You can try one of the following:
Method 1:
Assume that your project name is MyProject
Go to your path, run go build
It will create an executable file as your project name ("MyProject")
Then run the executable using ./MyProject
You can do both steps at once by typing go build && ./MyProject. Go files of the package main are compiled to an executable.
Method 2:
Just run go run *.go. It won't create any executable but it runs.
go run . will run all of your files. The entry point is the function main() which has to be unique to the main package.
Another option is to build the binary with go build and run it.
If you want to call a function from another go file and you are using Goland, then find the option 'Edit configuration' from the Run menu and change the run kind from File to Directory. It clears all the errors and allows you to call functions from other go files.
you should use go modules now, if you are not following How to write go code
With go module you don't have to put the code in the $GOPATH/src. it can live in any other location as well.
You can move the code to different directory like /employee, To make it work Just under employee directory initialise the go module
go mod init example.com/employee
I ran into the same issue with Go11, just wanted to share how I did solve it for helping others just in case they run into the same issue.
I had my Go project outside $GOPATH, so I had to turned on GO111MODULE=on without this option turned on, it will give you this issue; even if you you try to build or test the whole package or directory it won't be solved without GO111MODULE=on
While this doesn't directly address the OP's specific issue, I thought I'd chime in with the solution to my "undefined" error: the file with the undefined method had a build constraint (build tag).
More specifically, I accidentally included a build constraint to remove testing files from my deployed application binary in a utility function file used by my deployed binary. So in the OP's example - if employee.go had a build constraints their go build command would need to include a -tags flag matching the constraint in in order to have the file included.
For more info read this blog post:
https://dave.cheney.net/tag/build-constraints
Took a while to drill down my own MRE for this, so hopefully it will help others, despite being brief:
This can also occur if your functions / structs are defined in a file that has import "C", which will be silently ignored if CGO_ENABLED=0 is in your go environment, leading to you staring at a two file package that somehow is unable to share between themselves.
In GoLand,
right click a directory
GoLand will give you the option for build it and run it
it will also create a run configuration draft for you
you can save with an option of the upper right dropdown
If you right clic a file, it shows you commands to run, debug, test that file.
If you right clic a directory, it will be the same for that "package", expecting a main.go file inside the directory
I had a nasty import "C" in one of my go files.
If your source folder is structured /go/src/blog (assuming the name of your source folder is blog).
cd /go/src/blog ... (cd inside the folder that has your package)
go install
blog
That should run all of your files at the same time, instead of you having to list the files manually or "bashing" a method on the command line.
Off topic but still :-)
Before:
func NewEmployee() *Employee {
p := &Employee{}
return p
}
After:
func NewEmployee() *Employee {
return &Employee{}
}
No need to create a new variable. Just return.

golang reference struct in same package in another file

How to reference MyStruct in another file in the same package or folder?
Currently I get undefined: MyStruct when go build lib/file_2.go. I can run go install with no error, should I just ignore the build error?
These are my files:
lib/file_1.go
...
package lib
...
type MyStruct struct{
}
....
lib/file_2.go
...
package lib
...
{
m MyStruct
}
....
Thanks
This command works for me
go run *.go
Actually this will compile all go file and run your main function. So this works well
You're asking the go tool to compile lib/file_1.go, you never mention lib/file_2.go so how is it supposed to know it should compile it?
From go help build:
Build compiles the packages named by the import paths,
along with their dependencies, but it does not install the results.
If the arguments are a list of .go files, build treats them as a list
of source files specifying a single package.
You should be able to use MyStruct directly, since it is in the same package as its definition.
If you have any issue, sometimes it can help (for an IDE like SublimeText + GoSublime, for instance) to do a go install before creating lib/file_2.go.
That way, lib/file_1.go is compiled and present in GOPATH/pkg, with lib/file_1.go definitions visible for lib/file_2.go to use during its compilation.
According to https://golang.org/doc/tutorial/getting-started, you should run:
go run .
You have to compile the multiple files using the build command first.
go build
Now you can see a build file got generated with the given name or the folder name in case of default. Then run the binary.
./binary_file_name

Build and reference my own local package in Go

I'm playing with Google Go and I'm having fun (!), but I'm having some problems with package subsystem.
I'm running Go 1.0.1 on Mac OS X Lion. I've build also various single file programs without problems (I've also build a small webapp using html/templates without problems and it compiles and runs without any error).
I've defined a "reusable" package (even.go):
package even
func Even(i int) bool {
return i % 2 == 0
}
func Odd(i int) bool {
return i % 2 == 1
}
and a consumer program (useeven.go):
package main
import (
"./even"
"fmt"
)
func main() {
a := 5
b := 6
fmt.Printf("%d is even %v?\n", a, even.Even(a))
fmt.Printf("%d is odd %v?\n", b, even.Odd(b))
}
But when I compile the "library" using
go build even.go
I got nothing... No errors, no message... What happens?
How should I do this?
The answer to your question, "How should I do this?" is explained in How to Write Go Code. It's really pretty important stuff and worth taking a look at.
The behavior of go build might seem puzzling, but is actually conventional for command line programs--no output means that the program ran successfully. So what did it do? For that your answer is in go help build
... Otherwise build compiles the packages but discards the results,
serving only as a check that the packages can be built.
What, you wanted more? Of course. "How to Write Go Code" explains good ways of doing this. For a quick fix to your program, I'll explain that the go command expects each package and each executable program to be in a separate directory. If you just make a directory called even, immediately under the location of useeven.go, and move even.go to it, then go run useeven.go should run just as you have it.
go build only generates an output file when it builds a "single main package". If you want to output a file for your other package you should use go install. That will build and install that package to your pkgs directory.
As noted in a comment by the OP, go build and go run useeven.go work fine, once you put even.go in its own folder: ./even/even.go. There is a bit of Go magic in the ./ (in the import) that makes the "local package" build automatically without requiring it to be installed anywhere.
useeven/
├── even
│   └── even.go
└── useeven.go
If you wanted to make this work without the magic ./, then the library need to be installed. A quick-and-dirty way (at the risk of polluting your library namespace) of making this work for your project is to simply register the library's source location by using a symbolic link like so (in this example GOPATH is ~/go):
[ useeven ]
$ ln -s $(pwd)/even ~/go/src
Now when you build the program, it automatically performs a go get even to install an up-to-date version of your library.
Note that this doesn't make go install* work for the library, it just makes doing that unnecessary.
There are more idiomatic ways of doing this, if you're not in a hurry: How to import local packages in go?
The reason that output is not being generated here is because you're running the
go build even.go
command on the package and not the main go file. Doing so on the package will check for errors on the package, but because it's not a main with an output, no success messages will be generated. If there are issues with the package's contents, errors will be displayed, otherwise if it compiles fine there will be no output
Instead, you should run:
go build useeven.go
To create the binary, then to execute the binary and get output from the program:
./useeven

Resources