Go 编译静态库 给ios,windows,macos,android,linux使用
Posted 小米渣的逆袭
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go 编译静态库 给ios,windows,macos,android,linux使用相关的知识,希望对你有一定的参考价值。
ios ios只能在mac下编译
先上go代码
package main
// #include <stdlib.h>
// #include <sys/types.h>
// static void callLogger(void *func, const char *msg)
//
// ((void(*)(const char *))func)(msg);
//
import "C"
import (
"fmt"
"unsafe"
)
var loggerFunc unsafe.Pointer
//export test
func test(a int) int
n := a + 5
fmt.Printf("结果=%d\\n", n)
if uintptr(loggerFunc) != 0
message := C.CString(fmt.Sprintf("输出结果等于:%d", n))
C.callLogger(loggerFunc, message)
return n
//export setLogger
func setLogger(loggerFn uintptr)
loggerFunc = unsafe.Pointer(loggerFn)
func main()
test(5)
cd到Go目录下
执行命令
export CFLAGS="-arch arm64 -miphoneos-version-min=9.0 -isysroot "$(xcrun -sdk iphoneos --show-sdk-path)
export CGO_LDFLAGS="-arch arm64 -miphoneos-version-min=9.0 -isysroot "$(xcrun -sdk iphoneos --show-sdk-path)
CGO_ENABLED=1 GOARCH=arm64 GOOS=darwin CC="clang $CFLAGS $CGO_LDFLAGS" go build -tags ios -ldflags=-w -trimpath -v -o "testiphone.a" -buildmode c-archive
模拟器版本
export CFLAGS="-arch x86_64 -miphoneos-version-min=9.0 -isysroot "$(xcrun -sdk iphonesimulator --show-sdk-path)
export CGO_LDFLAGS="-arch x86_64 -miphoneos-version-min=9.0 -isysroot "$(xcrun -sdk iphonesimulator --show-sdk-path)
CGO_ENABLED=1 GOARCH=amd64 GOOS=darwin CC="clang $CFLAGS $CGO_LDFLAGS" go build -tags ios -ldflags=-w -trimpath -v -o "testsimulator.a" -buildmode c-archive
这样就生成了文件test.a test.h文件
找个ios工程测试
上一个编译脚本,自动编译模拟器版本和真机版本
#!/bin/sh
export LANG=en_US.UTF-8
baseDir=$(cd "$(dirname "$0")"; pwd)
rm -f testsimulator.a
rm -f testiphone.a
rm -f test.a
rm -f test.h
rm -f testiphone.h
rm -f testsimulator.h
export CFLAGS="-arch arm64 -miphoneos-version-min=9.0 -isysroot "$(xcrun -sdk iphoneos --show-sdk-path)
export CGO_LDFLAGS="-arch arm64 -miphoneos-version-min=9.0 -isysroot "$(xcrun -sdk iphoneos --show-sdk-path)
CGO_ENABLED=1 GOARCH=arm64 GOOS=darwin CC="clang $CFLAGS $CGO_LDFLAGS" go build -tags ios -ldflags=-w -trimpath -v -o "testiphone.a" -buildmode c-archive
cp $baseDir/testiphone.h $baseDir/test.h
export CFLAGS="-arch x86_64 -miphoneos-version-min=9.0 -isysroot "$(xcrun -sdk iphonesimulator --show-sdk-path)
export CGO_LDFLAGS="-arch x86_64 -miphoneos-version-min=9.0 -isysroot "$(xcrun -sdk iphonesimulator --show-sdk-path)
CGO_ENABLED=1 GOARCH=amd64 GOOS=darwin CC="clang $CFLAGS $CGO_LDFLAGS" go build -tags ios -ldflags=-w -trimpath -v -o "testsimulator.a" -buildmode c-archive
lipo -create $baseDir/testiphone.a $baseDir/testsimulator.a -output $baseDir/test.a
lipo -info $baseDir/test.a
Windows版本 window只能编译DLL,并且在Windows下才能编译
i386
i386首先可以简化一个概念,i386=Intel 80386。其实dui386通常被用来作为对Intel(英zhi特尔)32位微dao处理器的统称。
AMD64
AMD64,又称“x86-64”或“x64”,是一种64位元的电脑处理器架构。它是建基于现有32位元的x86架构,由AMD公司所开发,应用AMD64指令集的自家产品有Athlon 64、Athlon 64 FX、Athlon 64 X2、Turion 64、Opteron及最新的Sempron处理器。
GOOS指目标操作系统:
darwin mac
freebsd
linux
windows
android
dragonfly
netbsd
openbsd
plan9
solaris
GOARCH指的是目标处理器的架构:
arm
arm64
386 32位
amd64 64位
ppc64
ppc64le
mips64
mips64le
s390x
首先安装 mingw-w64-install.exe mingw下载地址
SET CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ GOOS=windows GOARCH=amd64
go build -o test.dll -buildmode=c-shared test.go
写一个c程序试试
有个问题,FreeLibrary时程序退出时会崩溃。。不知道为什么
上一个windows编译bat
@echo off
if exist output rd /s /q output
md output
md output\\x86
md output\\x86_64
setlocal
set TMP_PATH=%PATH%
:build
set CGO_ENABLED=1
set CGO_CFLAGS=-O3 -Wall -Wno-unused-function -Wno-switch -std=gnu11 -DWINVER=0x0601
call :build_plat 386 32 x86
call :build_plat amd64 64 x86_64
goto :eof
:build_plat
set GOARCH=%~1
set PATH=C:\\mingw\\mingw%~2\\bin;%TMP_PATH%
go build -buildmode=c-shared -ldflags="-w -s" -trimpath -v -o output\\%~3\\uukcp.dll
MacOS 在mac下编译
mac系统下和ios类似
export CFLAGS="-mmacosx-version-min=10.9 -isysroot "$(xcrun -sdk macosx --show-sdk-path)
export CGO_LDFLAGS="-mmacosx-version-min=10.9 -isysroot "$(xcrun -sdk macosx --show-sdk-path)
CGO_ENABLED=1 GOARCH=amd64 GOOS=darwin CC="clang $CFLAGS $CGO_LDFLAGS" go build -tags macosx -ldflags=-w -trimpath -v -o "test.a" -buildmode c-archive
#CGO_ENABLED=1 GOARCH=amd64 GOOS=darwin CC="clang $CFLAGS $CGO_LDFLAGS" go build -tags macosx -ldflags=-w -trimpath -v -o "$OUTPUT/libuukcp.dylib" -buildmode c-shared
写个mac工程试试
Android 在mac下编译(windows上没试),在mac上装的android studio测试
先上脚本 需要注意不同版本的ndk 和 arm架构 现在以小米mix3 arm64-v8a架构为例
arm64
#编译android版本功能
rootPath=$(cd "$(dirname "$0")"; pwd)
rm -f $rootPath/libtest.h
rm -f $rootPath/libtest.so
export GOARCH=arm64
export GOOS=android
export CGO_ENABLED=1
export CC=/Users/wjr/Library/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android21-clang
go build -tags macos -ldflags=-w -trimpath -v -o "libtest.so" -buildmode c-shared
arm
#编译android版本功能
rootPath=$(cd "$(dirname "$0")"; pwd)
rm -f $rootPath/libtest.h
rm -f $rootPath/libtest.so
export GOARCH=arm
export GOOS=android
export CGO_ENABLED=1
export CC=/Users/wjr/Library/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/bin/armv7a-linux-androideabi21-clang
go build -tags macos -ldflags=-w -trimpath -v -o "libtest.so" -buildmode c-shared
编译目录下防止一个jni.c
#include <jni.h>
#include <stdlib.h>
extern int test(int n);
JNIEXPORT jint JNICALL Java_com_go_test_GoUtils_test(JNIEnv *env, jobject c,jint n)
return test(n);
其中包名是com.go.test 类名是GoUtils 方法名是test 执行命令编译命令,他会顺带把jni.c一起编译
生成libtest.so文件
现在写一个android工程测试,拷贝libtest.so到程序目录程序libs目录下 这里以arm64-v8a为例
build. gradle增加
在java目录右键新建一个package com.go.test 在新建一个类名GoUtils
因为我们的so是libtest.so 所以
System.loadLibrary("test");
在定义一个方法
public static native int test(int n);
然后写代码测试
Go 增加一些引用头文件
// #cgo LDFLAGS: -llog
// #cgo LDFLAGS: -L./lib -lpiico_cc
// #include <android/log.h>
linux 下编译
由于没有机器的原因,本人在windows虚拟机上装的centos 7 64
装GO环境自己网上看吧
rootPath=$(pwd)
echo $rootPath
OUTPUT=$rootPath/output
echo $OUTPUT
rm -drf $OUTPUT
mkdir $OUTPUT
go build -tags linux -ldflags=-w -trimpath -v -o "$OUTPUT/uukcp.so" -buildmode c-shared
本人遇到的2个坑
1. 由于本人机器上 centos 7默认是gcc编译器是4.8.5,导致编译不过,出现
Error:‘for’ loop initial declarations are only allowed in C99 mode
解决办法,升级gcc 至最新版本,看到如下链接
CentOS 7升级gcc版本至11.2.1_Higer2008的博客-CSDN博客
升级完成以后 版本变成11.2.1
2. 本人在windows上写的脚本拷贝到linux上编译,由于windows上有回车换行默认有\\r\\n
在linux上总是异常,最好在linux上写好脚本在编译
以上是关于Go 编译静态库 给ios,windows,macos,android,linux使用的主要内容,如果未能解决你的问题,请参考以下文章
go 工具链目前[不支持编译 windows 下的动态链接库]解决方案
Go交叉编译 Build(Mac/linux/Windows)
Go交叉编译 Build(Mac/linux/Windows)
Mac OS X10.10_xcode6.1_ios8.1环境下,编译lame静态库libmp3lame.a,支持arm64 armv7s x86_64 i386 armv7指令集