I would like to know if it is possible to create 2 different executables on the same module,
main1.go -> main1.exe
main2.go -> main2.exe
root
-> main2.go
-> main1.go
the goal is to run Makefile, which will create 2 different executables.
Thanks
LATE_TARGET_HOOK=make_main
LATE_TARGET_HOOK=make_client
DS_CONF = ds.conf
export GOROOT := $(UV_golang_PKG)
export GOPROXY := http://****-product.****.com:****/artifactory/api/go/go
export GOSUMDB := off
export PATH := $(PATH):$(GOROOT)/bin
export VERSION := $(shell (cat $(SRCROOT)/VERSION))
GO =$(GOROOT)/bin/go
CONF_FILES = VERSION
include $(MODULEMK)
ifndef UV_BUILDNUMBER
UV_BUILDNUMBER = 0000
endif
make_main:
${GO} mod tidy
GOARCH=amd64 GOOS=linux CGO_CFLAGS=$(CGO_CFLAGS) CGO_LDFLAGS=$(CGO_LDFLAGS) $(GO) build $(BUILD_FLAGS) -o $(SRCROOT)/CMpub/bin/$(UV_O)/agentExporters .
make_client:
${GO} mod tidy
GOARCH=amd64 GOOS=linux CGO_CFLAGS=$(CGO_CFLAGS) CGO_LDFLAGS=$(CGO_LDFLAGS) $(GO) build $(BUILD_FLAGS) -o $(SRCROOT)/CMpub/bin/$(UV_O)/disableCollector .
but a single package cannot. Create a package for each executable.
How it is can be done?
By using different cmd packages inside your project, as I mentioned before.
This is described in details with "Packing multiple binaries in a Golang package " in 2018, by Ilija Eftimov
› tree
.
└── cmd
├── cookie
│ └── main.go
└── eight_ball
└── main.go
A go install ./... would find those main packages and compile/install them separately.
A more modern/different approach would be with "Getting started with multi-module workspaces": you could work on different modules (one per command) within the same workspace.
With multi-module workspaces, you can tell the Go command that you’re writing code in multiple modules at the same time and easily build and run code in those modules.
Related
I am trying to import local modules, but I am unable to import it using go mod. I initially built my project using go mod int github.com/AP/Ch2-GOMS
Note my environment is go1.14 and I am using VSCode as my editor.
This is my folder structure
Ch2-GOMS
│ ├── go.mod
│ ├── handlers
│ │ └── hello.go
│ └── main.go
My main.go code:
package main
import (
"log"
"net/http"
"os"
"github.com/AP/Ch2-GOMS/handlers" // This gives "could not import github.com/AP/Ch2-GOMS/handlers" lint error
)
func main() {
l := log.New(os.Stdout, "product-api", log.LstdFlags)
hh := handlers.NewHello(l)
sm := http.NewServeMux()
sm.Handle("/", hh)
http.ListenAndServe(":9090", nil)
}
I cannot see auto-complete for my local modules such as handlers.NewHello.
go build generated go.mod contents:
module github.com/AP/Ch2-GOMS
go 1.14
I am also getting You are neither in a module nor in your GOPATH. Please see https://github.com/golang/go/wiki/Modules for information on how to set up your Go project. warning in VScode, even though i have set GO111MODULE=on in my ~/.bashrc file
Read: Ian Lance Taylor's comment (Go's Core Team)
I know of three ways:
Method 1 (The best way):
# Inside
# Ch2-GOMS
# │ ├── go.mod
# │ ├── handlers
# │ │ └── hello.go
# │ └── main.go
# In Ch2-GOMS
go mod init github.com/AP/Ch2-GOMS
# In main.go
# Add import "github.com/AP/Ch2-GOMS/handlers"
# But, make sure:
# handlers/hello.go has a package name "package handlers"
You must be doing something wrong and that's why it's not working.
Method 2 (The good way):
# Inside
# Ch2-GOMS
# │ ├── go.mod
# │ ├── handlers
# │ │ └── hello.go
# │ └── main.go
# Inside the handlers package
cd Ch2-GOMS/handlers
go mod init github.com/AP/Ch2-GOMS/handlers # Generates go.mod
go build # Updates go.mod and go.sum
# Change directory to top-level (Ch2-GOMS)
cd ..
go mod init github.com/AP/Ch2-GOMS # Skip if already done
go build # Must fail for github.com/AP/Ch2-GOMS/handlers
vi go.mod
Inside Ch2-GOMS/go.mod and add the following line:
# Open go.mod for editing and add the below line at the bottom (Not inside require)
replace github.com/AP/Ch2-GOMS/handlers => ./handlers
# replace asks to replace the mentioned package with the path that you mentioned
# so it won't further look packages elsewhere and would look inside that's handlers package located there itself
Method 3 (The very quick hack way for the impatient):
Turn off Go Modules GO111MODULE=off
Remove go.mod file
# Check: echo $GOPATH
# If $GOPATH is set
mkdir -p $GOPATH/src/github.com/AP/Ch2-GOMS
cd $GOPATH/src/github.com/AP/Ch2-GOMS
# If $GOPATH is unset
mkdir -p ~/go/src/github.com/AP/Ch2-GOMS
cd ~/go/src/github.com/AP/Ch2-GOMS
# Now create a symbolic link
ln -s <full path to your package> handlers
Reason: During the build, the compiler first looks in vendor, then GOPATH, then GOROOT. So, due to the symlink, VSCode's go related tools will also work correctly due to the symlink provided as it relies on GOPATH (They don't work outside of GOPATH)
Below are the steps-
on main folder - go mod init
2.go mod tidy
3.go to the folder where main file is present
4.install the package via
go get <package name>
5.go build
Before above steps your project path should be
project path = GOPATH/src/<project_name>
Along with there should be 2 more folder parallel with src folder
src
pkg
bin
when ever you install any package it should be go inside pkg folder
and after doing go mod tidy there should be one file generated
go.mod
List item
go mod tidy alone at root folder did it for me
If you want to import local modules, you need to map the module path such that it can find the code in your local file system.
First use the go mod edit command to replace any imports to module to the local file
$ go mod edit -replace example.com/greetings=../greetings
The command specifies that example.com/greetings should be replaced with ../greetings for the purpose of locating the dependency. After you run the command, the go.mod file in the current directory should include a replace directive in its mod file
After that use the go mod tidy command to synchronize dependencies, adding those required by code where you imported but not yet traced by the current module
$ go mod tidy
Referred from the official documentation
I have multiple Go projects (and all of them are also Go modules) all in a folder. They are all HTTP servers and exchanging REST calls, thus, I need all of them up and running simultaneously.
So, for local testing purposes, I thought it would be reasonable to run all of them from the parent instead of moving all of the project root directories and running go run main.go in multiple terminals.
container_dir/
├── prj1/
│ ├── go.mod
│ ├── main.go
│ └── ...
├── prj2/
│ ├── go.mod
│ ├── main.go
│ └── ...
└── ...
Here are some some commands I have tried and the error messages for each time:
container_dir $ go run ./*/*.go
##ERROR: named files must all be in one directory; have ./prj1/ and ./prj2/
container_dir $ go run *.go
##ERROR: stat *.go: no such file or directory
container_dir $ go run ./prj1 ./prj2/
##ERROR: cannot find package "github.com/jackc/pgx/v4" in any of:
/usr/local/go/src/github.com/jackc/pgx/v4 (from $GOROOT)
/home/user/go/src/github.com/jackc/pgx/v4 (from $GOPATH)
cannot find package ...
So, I can give a final rephase for the question: How to run multiple go modules in sibling directories when they have some third party dependencies etc.?
P.S: As possible with Go modules suggest container_dir for my projects is in an arbitrary location and I expect no $GOPATH relevance.
Go version: 1.13.6
Don't use go run outside of tiny, playground-style tests
Source paths are a compile-time concern and are irrelevant at runtime - being in "sibling directories" doesn't mean anything when the program is running
go run runs a single program; just like building a program and running its executable binary (which is what go run does) runs a single program.
Looks like your go.mod stuff is having problems dude.
remember you can do replace inside it and reference your other application
module container_dir/prj2
go 1.13
require(
container_dir/prj1 v0.0.0
)
replace (
container_dir/prj1 => ../prj1
)
require is the path you import but it'll get switched to the relative path on build.
I'm setting up a new project using Go modules with this tutorial, and then trying to build it.
The module is located in a folder outside of the $GOPATH with the following structure:
example.com
├── my-project
├── ├── main
├── ├── ├── main.go
├── ├── go.mod
I've run go mod init example.com/my-project in directory example.com/my-project and created the go.mod file shown above.
main.go has basic contents:
package main
import (
"fmt"
)
func main(){
fmt.Println("Hello, world!")
}
After attempting to run go build in directory example.com/my-project, I receive the following error message:
can't load package: package example.com/my-project: unknown import path "example.com/my-project": cannot find module providing package example.com/my-project.
I've also attempted to run go build in directory /, outside of example.com/my-project, and I get similar, failing results:
can't load package: package .: no Go files in ...
I'm probably getting some basic thing wrong, so thanks for your patience and any help you can give.
no need for the directory main,
just move your main.go and go.mod to example.com/my-project and it will work.
Project root should look like:
.
├── go.mod
└── main.go
In my case it was that the variables GOMOD and GOWORK were taking other values different from the project I solved it by executing the command go env and verifying the values of those variables and deleting the files of that address.
Then I removed the go.mod and go.sum file from the project and ran the following commands again:
go mod init projectName
go mod tidy
go run ./...
And it worked perfectly.
I am creating a go project with version 1.12.1.
If I run GOPATH="$(pwd)/vendor:$(pwd)" GOBIN="$(pwd)/bin" go clean I get the following error:
can't load package: package github.com/marvincaspar/go-example: unknown import path "github.com/marvincaspar/go-example": cannot find module providing package github.com/marvincaspar/go-example
This is only for go clean, go run or go build works fine.
Here is the folder structure of main code:
.
├── Makefile
├── cmd
│ └── server
│ └── main.go
├── go.mod
├── go.sum
└── pkg
└── storage
└── mysql
└── storage.go
Here is how the go.mod file looks like:
module github.com/marvincaspar/go-example
go 1.12
require (
github.com/go-sql-driver/mysql v1.4.1
)
And finally the main.go file:
package main
import (
"fmt"
"os"
"github.com/marvincaspar/go-example/pkg/storage/mysql"
)
func main() {
if err := run(); err != nil {
fmt.Fprintf(os.Stderr, "%v", err)
os.Exit(1)
}
}
func run() error {
// init storage
s := mysql.NewStorage()
// do some other stuff...
}
Any ideas what I am doing wrong?
I generally use go get and go mod tidy for same. It works all the time.
go mod tidy
Normally this new project approach works for me:
go mod init <project_name>
go test
I have found that developing projects outside of GOROOT and GOPATH are much easier
Go build/install is trying to find main package in your root directory, it is not checking sub-directories (cmd/server) in your case. Hence you are getting package not found error.
To properly build your code, you can run:
go build github.com/marvincaspar/go-example/cmd/server
Similarly, to run your project, you will have to provide module-name/main-package-path:
go run github.com/marvincaspar/go-example/cmd/server
Go clean can be executed in same way, by providing module-name/path-with-main-package
go clean github.com/marvincaspar/go-example/cmd/server
or
GOPATH="$(pwd)/vendor:$(pwd)" GOBIN="$(pwd)/bin" go clean github.com/marvincaspar/go-example/cmd/server
However, as per https://blog.learngoprogramming.com/code-organization-tips-with-packages-d30de0d11f46, just put your source files into your project’s root. It’s better that way.
This can also happen if you are using workspaces. It seems like you can't use one package without workspaces if you are using others with workspaces.
So try going into your top level workspace and do
go work use ./problemPackage.
At least this worked for me.
To solve this problem you have to do few things, First, go to the project directory via the Terminal then run the following command ( If you are using git clone then go to the clone directory folder via Terminal and run the following command):
Step 1: sudo go mod init your-program.go
Step 2: sudo go mod tidy
Step 3: sudo go build your-program.go
Hi all I am fairly new to Golang, I am writing a toy client and server app just to learn the libraries.
But I have the project folder:
philipherron#Philips-iMac {~/workspace/gospace/src/github.com/redbrain/station} $ echo $GOPATH
/Users/philipherron/workspace/gospace
I wanted to have 2 binaries:
client.go
server.go
But when I build I get:
philipherron#Philips-iMac {~/workspace/gospace/src/github.com/redbrain/station} $ go build github.com/redbrain/station/
# github.com/redbrain/station
./server.go:5: main redeclared in this block
previous declaration at ./client.go:5
I guess this is because it looks like I am making to mains in the same package.
So I tried creating a client and a server subdir and have the binaries in each of those, but I get:
philipherron#Philips-iMac {~/workspace/gospace/src/github.com/redbrain/station} $ go build github.com/redbrain/station/client
go install github.com/redbrain/station/client: build output "client" already exists and is a directory
I guess this is because I have the layout of:
$ tree
.
├── client
│ └── client.go
└── server
└── server.go
2 directories, 4 files
Not sure how to get around this, it would just be nice to have the same client and server in the same directory but maybe this is against how I should be doing things in go?
just rename your .go files. The compiler is trying to write to 'client' but 'client' is already taken by the directory.
$ tree
.
├── client
│ └── main.go
└── server
└── main.go
2 directories, 4 files
And/Or create a script that outputs them with a different name go build -o client client/main.go
along with with separate packages as above, if you set the GOBIN=$GOPATH/bin then it will create client and server in the bin dir and it will not collide with dir names