I’m trying to build a libtest.a with Go1.11.4 using cgo under linux/mips64le.
I make a simple Go file, this is test.go code:
package main
import(
“C”
“fmt”
)
func main() {
}
//export hello
func hello(){
fmt.Println(“Hello World”)
}
and I did:
CGO_ENABLED=1 go build -o libtest.a -buildmode=c-archive test.go
I get these very non-descriptive errors:
# internal/race
flag provided but not defined: -shared
usage: compile [options] file.go...
(... many options such like -K, -L, -M etc.)
# internal/cpu
(...following like above)
# errors
# runtime/internal/sys
# math/bits
# runtime/internal/atomic
# sync/atomic
# math
# unicode/utf8
# unicode
# runtime/cgo
How can I do it? I can not use cgo under mips64le? best regards
On my Mac, I build with:
GOOS=linux GOARCH=mips64le go build
It works well under mips64le(OS:NeoKylin).
Related
When I use flag package
// main.go
import (
...
"flag"
)
func main() {
...
flag.Parse()
switch flag.Arg(0) {
case "doSomething1":
...
case "doSomething2":
...
}
}
If doSomething1 argument print some error message for me, whatever I fix the source code, it can not remove the old error code and compile again.
// command-line
# go build ./main.go
# ./main doSomething1
# error doSomething1 can not work
-- I fix my code
# ./main doSomething1
# error doSomething1 can not work
-- the error message also show me again
-- I have to delete main and build again
# rm ./main
# go build ./main.go
# ./main.go doSomething1
# doSomething1 now can work
Go is a compiled language. When you run go build, it will compile your sources and create an executable binary. This is what you run when executing ./main doSomething1.
When you change your sources and run ./main doSomething1, you are not compiling again, you just run the previously built (and unchanged) binary.
To quickly test changes, use go run instead:
go run main.go doSomething1
That will always compile your sources, build a binary in a temporary folder, launch it and clear it once your app exits.
For details, see What does go build build?
I have a program in Go that I want to compile in a bunch of binaries, each having a const value defined differently. More clearly, I have something like that:
const wordLen = 6
type knowledge [wordLen]byte
Here, wordLen is associated with the value 6, but I want to have different binaries, with values ranging from 5 to 10. I could make it a variable, and then use a slice rather than an array, but that would have a huge performance impact on my soft (yes, I tried).
I would love to have some build tag on go build argument to indicate what the value of wordLen is for a given binary. So, what is the (as idiomatic as possible) way to do this ?
Yes, this is possible using Build Constraints.
You can supply a list of these constraints to go build using the -tags flag.
Example:
main.go
package main
import "fmt"
func main() {
fmt.Println(f)
}
foo.go
// +build foo
package main
const f = "defined in foo.go"
bar.go
// +build bar
package main
const f = "defined in bar.go"
Compiling the code with different tags will give different results:
$ go build -tags foo
$ ./main
defined in foo.go
$ go build -tags bar
$ ./main
defined in bar.go
It doesn't solve your exact problem but it may solve others so I add for compelteness that you can use the -ldflags option of the go compiler:
go build -ldflags "-X main.wordLen=6"
Its however has two downsides:
Only works for strings
Only works on vars
Here is test code m.go:
package main
var version string
func main() {
println("ver = ", version)
}
If I compile and link with go 1.5:
go tool compile m.go
go tool link -o m -X main.version="abc 123" m.o
Works fine.
But if I use build command with go 1.5:
go build -o m -ldflags '-X main.version="abc 123"' m.go
It will show help message, which means something wrong
If I change to 1.4 syntax:
go build -o m -ldflags '-X main.version "abc 123"' m.go
It works except a warning message:
link: warning: option -X main.version abc 123 may not work in future releases; use -X main.version=abc 123
If it has no space in parameter value, works fine:
go build -o m -ldflags '-X main.version=abc123' m.go
Because compile and link works fine, So I think it is not link part issue.
I compared go1.4 and go 1.5 source code of build, for ldflags part, looks nothing changed. Of cause I can use some spacial char to replace space then in program to change it back, but why? Is there something I missed? What is the right syntax to use -ldflags ? Thanks
From the documentation:
Note that before Go 1.5 this option took two separate arguments.
Now it takes one argument split on the first = sign.
Enclose the entire argument in quotes:
go build -o m -ldflags '-X "main.version=abc 123"' m.go
I use gccgo to compile my projects. here is my directory layout. I read this Q/A thread How to use custom packages in golang?
so followed this one
src/
+-fibo/
| +-fibo.go
+main.go
and here are the code listing
main.go
package main
import (
"os"
"fmt"
"strconv"
"src/fibo"
)
func main(){
if len(os.Args) < 2 {
fmt.Printf("ur input sucks\n")
}
num,_ := strconv.Atoi(os.Args[1])
fibo.Fibo(num)
}
fibo/fibo.go
package fibo
import "fmt"
func Fibo(num int) {
var a,b int
for i :=0; i< num; i++ {
a, b = b, a+b
fmt.Print(a, " ")
}
fmt.Print("\n")
}
but when I try to compile, i follwed usual gcc procedure. compile files separately and link them together into final executable. I get this error
.../go-lang-expts/src $ gccgo -c -ofibo/fibo.o fibo/fibo.go
.../go-lang-expts/src $ gccgo -c -omain.o main.go
main.go:7:10: error: import file ‘src/fibo’ not found
main.go:18:2: error: reference to undefined name ‘fibo’
.../go-lang-expts/src $
I am stuck here. I tried different combination of directory structures. none helped. what am I missing? is there any environment variable I should set, even for this??
It looks like you may not have set the GOPATH Environment Variable
From How to Write Go Code
The GOPATH environment variable specifies the location of your workspace. It is likely the only environment variable you'll need to set when developing Go code.
Given your current directory structure of
src/
+-fibo/
| +-fibo.go
+main.go
If your src directory is under GOPATH then you should be able to just do:
import "fibo"
in main.go.
See also "GOPATH environment variable" from The go command documentation.
This set of commands worked for me.
.../go-lang-expts/src $ gccgo -c -fgo-pkgpath=fibo -ofibo/fibo.o fibo/fibo.go
This will name the package fibo, so you will have to import it as such in main.go
import "fibo"
Now you can compile main.go by telling where fibo.o library is
.../go-lang-expts/src $ gccgo -c main.go -Ifibo
Then you need to link the two file to create an executable main
.../go-lang-expts/src $ gccgo -o main main.o fibo/fibo.o
I have just put together a Go package that is going to be a part in a fairly large system with a lot of shared packages. I was able to get it to compile by writing its Makefile such that the compiler is called with -I flags:
include $(GOROOT)/src/Make.inc
TARG=foobar
GOFILES=\
foobar.go\
foobar:
$(GC) -I$(CURDIR)/../intmath -I$(CURDIR)/../randnum foobar.go
include $(GOROOT)/src/Make.pkg
It compiles just fine, and being a good boy, I wrote a comprehensive set of tests. However, when I try to run the tests with gotest, I get a compile error:
$ gotest
rm -f _test/foobar.a
8g -o _gotest_.8 foobar.go foobar_test.go
foobar.go:4: can't find import: intmath
make: *** [_gotest_.8] Error 1
gotest: "C:\\msys\\bin\\sh.exe -c \"gomake\" \"testpackage\" \"GOTESTFILES=foobar_test.go\"" failed: exit status 2
So, the Go file itself will compile when I use the -I flags to tell it where to find the intmath and randnum packages, but gotest doesn't seem to use the Makefile.
Answering peterSO's question:
foobar.go's import section looks like this:
import (
"intmath"
"randnum"
"container/vector"
)
And the compile works fine as long as I have the -I flags going to the compiler. I have tried to use relative paths, like this:
import (
"../intmath"
"../randnum"
"container/vector"
)
but that just doesn't seem to work.
EDIT: answering further peterSO questions:
GOROOT is set to C:\Go the directory where I have all of the Go stuff -- aside from my source code -- installed. I was expecting the relative path to be relative to the directory in which the source file lives.
My source tree looks like this:
server/
foobar/
randnum/
intmath/
So, while I am open to a different, more Go-idiomatic directory structure, my instinct is to arrange them as peers.
Is there some way that I can nudge gotest into compiling foobar.go with the needed flags?
Create the Windows source code directory structure:
C:\server
C:\server\foobar
C:\server\intnum
For intnum.go:
package intnum
func IntNum() int {
return 42
}
Makefile:
include $(GOROOT)/src/Make.inc
TARG=server/intnum
GOFILES=\
intnum.go\
include $(GOROOT)/src/Make.pkg
Run:
$ cd c/server/intnum
$ make install
For foobar.go:
package foobar
import (
"math"
"server/intnum"
)
func FooBar() float64 {
return float64(intnum.IntNum()) * math.Pi
}
Makefile:
include $(GOROOT)/src/Make.inc
TARG=server/foobar
GOFILES=\
foobar.go\
include $(GOROOT)/src/Make.pkg
Run:
$ cd /c/server/foobar
$ make install
After the install, the intnum.a and foobar.a package files will be in the $GOROOT\pkg\windows_386\server (C:\Go\pkg\windows_386\server) directory`.