Go build multiple/nested packages? - go

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.

Related

Where is the go project working directory when using modules?

I am trying to download, make some tweaks and build a golang project from GitHub. The project's instructions are:
go get github.com/<vendor>/<projectName>
cd src/github.com/<vendor>/<projectName>
go build .
That used to work in the past — before enabling Go Modules.
Now I have GO111MODULE=on (go version go1.15.4 linux/amd64). When running the first command, go downloads the project as a module and all its dependencies.
But then there is no src/github.com/<vendor>/<projectName> folder anymore. Moreover, the is no folder named <projectName> anywhere in the system.
Instead, there is folder pkg/mod/github.com/<vendor> which contains the project folder with weird symbols in its name (exclamation marks etc.) and version identifiers.
How do I get the project folder available for making tweaks and builds?
As pointed by #Volker, good old git clone should be used.
It turns out that it should be used instead of go get github.com/<vendor>/<projectName> (no idea why the project vendor recommends that):
git clone git://github.com/<vendor>/<projectName>
cd <projectName>
go get ./...
# do tweaks here
go build .
If your goal is tweaks, the easiest way it use to use go mod vendor.
https://golang.org/ref/mod#go-mod-vendor
The go mod vendor command constructs a directory named vendor in the main module's root directory that contains copies of all packages needed to support builds and tests of packages in the main module

Golang Dep: having multiple binaries in one source tree

Having the following Go project layout with shared library functions in lib and several binaries in cmd using these library functions and having external dependencies:
root
|
lib
cmd
|
binary1
|
main.go
binary2
|
main.go
...
Searching for a simple way to handle project dependencies with dep tool. What is the expected usage pattern: having multiple Gopkg.* files in each binaryX directory or using a pair of Gopkg.toml and Gopkg.lock files for all these binaries? In the second case how would we compile these binaries knowing that vendor directory will be in project root instead of binaryX directories?
Normally, you'd just have a single root/vendor directory that all your various deps that are referenced by the lib and cmd code
When compiling, just do it like normal.
go install ./cmd/...
(or however you want to build)

Building Golang project properly

I have a project structure that looks like so:
I was planning on just using a shell script (build.sh) to set GOPATH and build the project.
I am not sure how to build a Golang project properly, my short term goal is to just to build the packages in the src directory and put the binaries into the bin directory.
I am not sure what go build command can do that, I have tried a few things.
So first my question is - is this a reasonable project structure and second, how can I compile my src directory to bin?
What I have gives me the following error:
can't load package: package .: no buildable Go source files in /home/oleg/WebstormProjects/oresoftware/stack-server
So I believe I need to tell Go to look in the src directory, because Go is only looking for .go files in the project root, but I am not sure how to do that.
If it matters, the main.go file has a package name of "main".
GOPATH=$PROJECT_DIR && cd $PROJECT_DIR && go install main
Also move your main.go file into src/main/main.go.
This will produce a bin/main executable.
If you have multiple executables you wanna build, you have to put each main.go file into a separate folder/package. The name of the generated executable is taken from the directory name the file is inside. The package name of the main.go files must always be main if it should create a binary.
To compile multiple executables you have to use:
GOPATH=$PROJECT_DIR && cd $PROJECT_DIR && go install ...
The ... matches all folders/packages.

Correct directory structure for a Go Project?

I'm relatively new to Go and I've recently created a project that's going up on GitHub. I've tried to follow guides but there's a pressing question of why my binaries end up in src/?
My layout is like this:
ssm/ - Name of project
LICENSE
README.md
src/ - Source Code
files.go - All my source code is here.
src - The compiled binary ends up here
bin/ - Binaries
I set my $GOPATH to ~/Documents/Programming/Go/. From my gopath, I can't type go build ssm because it cannot find package. If I cd into the directory, it complains it can't load package: package .: no Go source files.
I have to actually go into src and compile there, which means the binary isn't in bin/.
What am I doing wrong?
See https://code.google.com/p/go-wiki/wiki/GithubCodeLayout
To be compatible with go get, your project's package name needs to be fully-qualified under the github.com domain:
$GOPATH/
src/github.com/<user>/ssm/
.git
LICENSE
README.md
files.go
bin/
Note that the base of the git repository (.git) is not the same as the $GOPATH.
Also, go build <package> will output a compiled executable to the current directory. If you want the exe to go to bin/, use go install <package> instead.
Your go code you can kept in a workspace. A workspace contains many source files (git, hg, svm, etc.). The Go tool understand the layout. We don't require Makefile or build.xml here. The basic directory layout is everything. If in any case if you are going to change the file layout, accordingly you need to change the build.
This is the general structure you can follow,
$GOPATH/
src/
github.com/username/repo/
mypkg/
mysrc1.go
mysrc2.go
cmd/mycmd/
main.go
bin/
mycmd
And, this is the standard workspace
$GOPATH/
bin/fixhub # installed binary
pkg/darwin_amd64/ # compiled archives
code.google.com/p/goauth2/oauth.a
github.com/...
src/ # source repositories
code.google.com/p/goauth2/
.hg
oauth # used by package go-github
...
github.com/
golang/lint/... # used by package fixhub
.git
google/go-github/... # used by package fixhub
.git
dsymonds/fixhub/
.git
client.go
cmd/fixhub/fixhub.go # package main
go get fetch many repositories whereas go install builds a binary out of them. It's convenient and easy to go for go development quickly. And, everyone in the go community follows the same. This puts src, bin and pkg into the home directory. And, $HOME/bin is already in our path before creating our workspace.

How to compile Go program consisting of multiple files?

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.

Resources