Golang Dep: having multiple binaries in one source tree - go

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)

Related

What is the use of pkg directory in Go?

If we have bin directory already where executables go then what is the need of pkg directory? Please explain.
The pkg directory contains Go package objects compiled from src directory Go source code packages, which are then used, at link time, to create the complete Go executable binary in the bin directory.
We can compile a package once, but link that object into many executables. For example, the fmt package appears in almost every Go program. It's compiled once but linked many times, a big saving.
~/go/pkg
From How to Write Go Code, we know ~/go/pkg can store third party library. For example:
Create two file main.go and go.mod:
//main.go
package main
import (
"fmt"
"github.com/google/go-cmp/cmp"
)
func main() {
fmt.Println(cmp.Diff("Hello World", "Hello Go"))
}
//go.mod
module example.com/user/hello
go 1.13
Install a third party library
$ ls ~/go/pkg/mod/github.com/google/
...
$ go install example.com/user/hello
go: finding github.com/google/go-cmp v0.5.2
go: downloading github.com/google/go-cmp v0.5.2
go: extracting github.com/google/go-cmp v0.5.2
$ ls ~/go/pkg/mod/github.com/google/
... go-cmp#v0.5.2
$ ls ~/go/pkg/mod/github.com/google/go-cmp#v0.5.2
And then, you will see a lot of go files, not compile files.
$ ls ~/go/pkg/mod/github.com/google/go-cmp#v0.5.2/cmp/
... example_test.go options.go ...
pkg in user project
This pkg is a directory/package of user project. You can see it as Library and it's OK to use by external applications. For more things, you can check here.
You put your source code in src directory while pkg is the directory that holds compilation output of your actual source code. If you use multiple libraries/packages you will have different output with extension .a for each one, A linker should be responsible for linking and combining all of them together to produce one final executable in bin directory.
As pkg and bin are more specific to the machine or operating system into which you build your actual source code so it is not recommended to share both of them, your repo should have only your actual code.
A side note, if you plan to use docker containers, pkg dir should be ignored as we may build the source code in windows for example while you import/mount your code into linux container; at this time pkg will have compiled files that are only valid for windows

Go build multiple/nested packages?

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.

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.

Yocto: Where is the source for my project?

I recently discovered Yocto. I'm able to successfully build an image using the command bitbake fsl-image-gui. But now, I would like to browse the code, the project specific code and the Kernel code for the fsl-image-gui but I cannot figure how ?
Where is the source code when I build my Yocto project and how could I browse it ?
There are two halves of the Yocto setup:
The sources/ directory, containing the bitbake recipes and supporting configuration, and
The build/ directory, where the actual builds take place.
Each of the bitbake recipes (i.e. *.bb files found in a structure under the sources/ directory) that you run should be constrained to a directory structure like:
build/
tmp/
work/
< platform name >/
< recipe name >/
< version >/
...juicy stuff here...
Underneath the < version >/ directory, you should find a structure like:
build/
image/
package/
packages-split/
temp/
your_unpacked_source_directory/
...and others
...where your_unpacked_source_directory is determined by the directory structure contained in the downloaded and unpacked source. (e.g. as contained in the .tgz file)
All of the build logs and scripts generated during the build are contained in the temp/ directory.
The package/ directory contains all of the files that are to be packaged as a result of this recipe. The packages-split/ divides the files into their separate packages, e.g. base package, -dev package, -dbg package, -staticdev package.
Well, have you looked around in the build tree?
You'll have a downloads directory, in which all downloaded tarballs are stored, as well as all cloned repositories.
The actual unpacking and building takes place in subdirectories under build/tmp/work/<arch>/.

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.

Resources