Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Cross Compiling and Language Interop oh my!

Cross Compiling Go Code in Weird Configurations for fun and (little) profit

This represents my experiments in getting Go to do different configuration things for our cross-platform environment

Building Go code for Target (no mixed code, just Go)

nick@bignick:~/demo/targetMe$ GOOS=linux GOARCH=arm GOARM=5 go build 
nick@bignick:~/demo/targetMe$ file targetMe
targetMe: ELF 32-bit LSB  executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped

Building C code in to Go with cross compiler

See also: https://github.com/golang/go/issues/12443#issuecomment-136906785 for useful information

nick@bignick:~/demo/$ CC=arm-poky-linux-gnueabi-gcc  CGO_CFLAGS="-march=armv7-a -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a8 --sysroot=/opt/poky/1.7.1/sysroots/cortexa8hf-vfp-neon-poky-linux-gnueabi" CGO_LDFLAGS=-v CGO_ENABLED=1 GOOS=linux GOARCH=arm GOARM=5 go build -o Foo_ARM *.go

Building Go code into C

nick@bignick:~/demo/cgodemo$ go build -buildmode=c-archive exportSyms.go 
nick@bignick:~/demo/cgodemo$ gcc -pthread useFromC.c exportSyms.a -o useFromC
nick@bignick:~/demo/cgodemo$ ./useFromC
10
2015/09/02 14:22:13 Hello World

Cross Compiling Go into Library for Compiling into Target app

nick@bignick:~/demo/cgodemo$ CC=arm-poky-linux-gnueabi-gcc  CGO_CFLAGS="-march=armv7-a -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a8 --sysroot=/opt/poky/1.7.1/sysroots/cortexa8hf-vfp-neon-poky-linux-gnueabi" CGO_ENABLED=1 GOOS=linux GOARCH=arm GOARM=5 go build  -buildmode=c-archive exportSyms.go
nick@bignick:~/demo/cgodemo$ $CC -pthread useFromC.c exportSyms.a -o useFromC
nick@bignick:~/demo/cgodemo$ file useFromC
useFromC: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=914408ad20be622e5205f93175e7c4d0337487e9, not stripped
nick@bignick:~/demo/cgodemo$ scp useFromC root@TARGET.local:/tmp/
...
root@TARGET:~# /tmp/useFromC 
10
2015/05/30 01:46:31 Hello World
package binding
// #include <stdlib.h>
// #include <stdio.h>
// #cgo LDFLAGS: -mfloat-abi=hard
/* void myprint(char* s) {
printf("%s", s);
}
*/
import "C"
func Random() int {
return int(C.random())
}
func PrintHello() {
C.myprint(C.CString("Hello\n"))
}
func Seed(i int) {
C.srandom(C.uint(i))
}
package main
import (
"C"
"fmt"
"log"
)
//export PrintInt
func PrintInt(x int) {
fmt.Println(x)
}
//export LogString
func LogString(s * C.char) {
log.Println(C.GoString(s))
}
func main() {}
package main
import (
"./binding"
"fmt"
)
func main() {
binding.PrintHello()
binding.Seed(1)
fmt.Println(binding.Random())
binding.Seed(2)
fmt.Println(binding.Random())
binding.Seed(3)
fmt.Println(binding.Random())
}
#include "exportSyms.h"
int main() {
PrintInt(10);
LogString("Hello World");
return 0;
}
@17twenty

This comment has been minimized.

Copy link
Owner Author

@17twenty 17twenty commented Sep 2, 2015

@17twenty

This comment has been minimized.

Copy link
Owner Author

@17twenty 17twenty commented Sep 22, 2015

char a1;            // type of a1 is C.char
char *a2;           // type of a2 is *C.char
char a3[1];         // type of a3 is [1]C.char
char a4[1][2];      // type of a4 is [1][2]C.char
char a5[1][2][3];   // type of a5 is [1][2][3]C.char
char *a6[1][2][3];  // type of a6 is [1][2][3]*C.char
char **a7[1][2][3]; // type of a7 is [1][2][3]**C.char
char ***a8[1][2];   // type of a8 is [1][2]***C.char
char *a9[1][2];     // type of a9 is [1][2]*C.char
char **a10[1];      // type of a0 is [1]**C.char
char *a11[1];       // type of a1 is [1]*C.char

void b1(char a1) {}             // as type C.char in _Cfunc_b1
void b2(char *a2) {}            // as type *C.char in _Cfunc_b2
void b3(char a3[1]) {}          // as type *C.char in _Cfunc_b3
void b4(char a4[1][2]) {}       // as type *[2]C.char in _Cfunc_b4
void b5(char a5[1][2][3]) {}    // as type *[2][3]C.char in _Cfunc_b5
void b6(char *a6[1][2][3]) {}   // as type *[2][3]*C.char in _Cfunc_b6
void b7(char **a7[1][2][3]) {}  // as type *[2][3]**C.char in _Cfunc_b7
void b8(char ***a8[1][2]) {}    // as type *[2]***C.char in _Cfunc_b8
void b9(char *a9[1][2]) {}      // as type *[2]*C.char in _Cfunc_b9
void b10(char **a10[1]) {}      // as type ***C.char in _Cfunc_b10
void b11(char *a11[1]) {}       // as type **C.char in _Cfunc_b11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.