Background: I wrote a feature(in packageA) and don't want anyone see my code. So I installed it into .a file(packageA.a). I use it by below method:
package main
import packageA
func main(){
packageA.Run()
}
Then I do
go tool compile -I lib/ main.go
It can work.
go tool link -o main -L main.o
But when I do this it doesn't work.
I wrote another feature(packageB) in $GOPATH/src/project/packageB
and update main.go
// main.go
package main
import (
"packageA"
_ "project/packageB"
)
func main(){
packageA.Run()
}
exec go tool compile -I lib/ main.go
but error can't find import "packageB"
my directory layout
project
main.go
lib/
packageA.a
packageB
xxx.go
Wanted to know if it's good practice to do that and what would be the best way to do that? go tool compile how to import .a file and source code?
Thanks sincerely in advance.
This is a great question, and required a bit of research on my part to answer.
I'm going to assume that your question is really just a minimal example for reproduction purposes, and that your REAL question is: "How do I compile a Go program against both source code and binary-only packages?"
Let's walk through this step by step
Phase 1: Generating your binary-only package.
You probably already have the binary-only package, so you can skip this step if you want, but it's helpful for setting context.
First, let's make sure your package names actually are correct for the folder structure. That means main.go has the following imports:
import (
"project/packageA"
"project/packageB"
)
Similarly, the source code in packageB (which in your example is dependent on packageA) uses import "project/packageB"
So what you want to have originally is a structure that looks like this:
$GOPATH/
src/
project/
main.go
packageA
xxx.go
packageB
xxx.go
And you want to compile packageA so that it's just a static binary. You can do this very simply by running go install .
from the packageA
directory.
You now have the following structure:
$GOPATH/
pkg/
$ARCH/
project/
packageA.a
src/
project/
main.go
packageA
xxx.go
packageB
xxx.go
Phase 2: Building main.go without the Go source for packageA
Your problem now is: how do I tell the Go compiler to look for both go source files in src
and linked binaries in pkg
?
The catch here is that if you just delete packageA, the Go compiler toolchain will be confused - it assumes by default that missing Go source code means the build has failed. So what you can do as of Go 1.7 is to provide a build flag to the compiler inside packageA that says "Hey! Don't use this source code, go use the linked binary for this instead!"
To do this, we want to replace the source code contents in packageA with a file that looks like the following:
//go:binary-only-package
package packageA
Now, all we need to do to build main.go
is just to use plain old go build main.go
and we're all done.