Skip to content

Commit

Permalink
Add CGO MakeFile
Browse files Browse the repository at this point in the history
  • Loading branch information
iheron committed Nov 18, 2024
1 parent 263f42a commit c884183
Show file tree
Hide file tree
Showing 3 changed files with 238 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ main
Tunnel.framework
tunnel.aar
tunnel-sources.jar
*.tar.gz
41 changes: 41 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ BUILD=go build -ldflags "-s -w -X main.Version=$(VERSION)"
BUILD_DIR=build
BIN_NAME=nkn-tunnel
MAIN=bin/main.go
LIB_NAME:=libnkntunnel
LIB_SRC_FILE:=lib/libnkntunnel.go
LIB_BUILD_DIR:=$(BUILD_DIR)/lib

ifdef GOARM
BIN_DIR=$(GOOS)-$(GOARCH)v$(GOARM)
else
Expand Down Expand Up @@ -65,3 +69,40 @@ android:
gomobile bind -target=android -ldflags "-s -w" github.com/nknorg/nkn-tunnel github.com/nknorg/nkn-tuna-session github.com/nknorg/ncp-go github.com/nknorg/tuna github.com/nknorg/nkn-sdk-go github.com/nknorg/nkngomobile
mv tunnel.aar tunnel-sources.jar $(BUILD_DIR)/android/
${MAKE} zip BIN_DIR=android

.PHONY: lib
lib:
rm -rf $(BUILD_DIR)/lib
mkdir -p $(BUILD_DIR)/lib

for target in \
"darwin arm64 darwin-arm64 .dylib clang" \
"windows amd64 win-amd64 .dll x86_64-w64-mingw32-gcc " \
"linux amd64 linux-amd64 .so x86_64-linux-musl-gcc"; \
do \
set -- $$target; \
GOOS=$$1 GOARCH=$$2 PLATFORM=$$3 EXT=$$4 CC=$$5; \
echo "Building for $$GOOS/$$GOARCH..."; \
BUILD_OUTPUT=$(LIB_BUILD_DIR)/$$GOOS_$$PLATFORM/$(LIB_NAME)$$EXT; \
mkdir -p $(dir $$BUILD_OUTPUT); \
CGO_ENABLED=1 GOOS=$$GOOS GOARCH=$$GOARCH CC=$$CC go build -buildmode=c-shared \
-ldflags "-s -w -X main.Version=$(VERSION)" \
-o $$BUILD_OUTPUT $(LIB_SRC_FILE); \
if [ $$? -ne 0 ]; then \
echo "Failed to build $$GOOS/$$GOARCH"; \
exit 1; \
fi; \
echo "Successfully built $$GOOS/$$GOARCH"; \
done

CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 CC=clang go build -buildmode=c-archive -ldflags "-s -w -X main.Version=$(VERSION)" -o $(LIB_BUILD_DIR)/ios-arm64/$(LIB_NAME).a $(LIB_SRC_FILE)
CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 CC=clang go build -buildmode=c-archive -ldflags "-s -w -X main.Version=$(VERSION)" -o $(LIB_BUILD_DIR)/ios-amd64/$(LIB_NAME).a $(LIB_SRC_FILE)
mkdir -p $(LIB_BUILD_DIR)/ios
lipo -create -output $(LIB_BUILD_DIR)/ios/libnkntunnel.a $(LIB_BUILD_DIR)/ios-amd64/libnkntunnel.a $(LIB_BUILD_DIR)/ios-arm64/libnkntunnel.a
cp $(LIB_BUILD_DIR)/ios-arm64/$(LIB_NAME).h $(LIB_BUILD_DIR)/ios/$(LIB_NAME).h
@echo "All platforms built successfully. Output in $(LIB_BUILD_DIR)/"

.PHONY: package_lib
package_lib: lib
cd $(BUILD_DIR) && rm -f lib.tar.gz && tar -czf lib.tar.gz lib
@echo "Library package created: $(BUILD_DIR)/lib.tar.gz"
196 changes: 196 additions & 0 deletions lib/libnkntunnel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
package main

/*
#include <stdlib.h>
*/
import "C"
import (
"encoding/hex"
"github.com/nknorg/ncp-go"
"github.com/nknorg/nkn-sdk-go"
ts "github.com/nknorg/nkn-tuna-session"
tunnel "github.com/nknorg/nkn-tunnel"
"github.com/nknorg/nkngomobile"
"log"
"os"
"strings"
"sync"
)

var (
instanceTunnel *tunnel.Tunnel
tunnelMutex sync.Mutex
logMutex sync.Mutex

logFilePath string
logFile *os.File
logToFile bool

DefaultTunaMaxPrice = "0.01"
DefaultTunaMinFee = "0.00001"
DefaultTunaFeeRatio = 0.1
)

func initLogger() error {
if logFilePath == "" {
logToFile = false
log.SetOutput(os.Stdout)
return nil
}

var err error
logFile, err = os.OpenFile(logFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
logToFile = false
log.SetOutput(os.Stdout)
log.Println("Failed to open log file, defaulting to stdout:", err)
return err
}

log.SetOutput(logFile)
logToFile = true
log.Println("Log initialized, writing to file:", logFilePath)
return nil
}

func closeLogger() {
logMutex.Lock()
defer logMutex.Unlock()

if logFile != nil {
log.Println("Closing log file")
logFile.Close()
logFile = nil
logToFile = false
}
}

//export SetLogFilePath
func SetLogFilePath(path *C.char) {
logMutex.Lock()
defer logMutex.Unlock()

logFilePath = C.GoString(path)
initLogger()
}

//export StartNknTunnel
func StartNknTunnel(numClients C.int, seedRpcServers *C.char, seedHex *C.char, identifier *C.char, from *C.char, to *C.char, udp C.int, useTuna C.int, tunaMaxPrice *C.char, tunaMinFee *C.char, tunaFeeRatio C.float, verbose C.int) C.int {
tunnelMutex.Lock()
defer tunnelMutex.Unlock()

if instanceTunnel != nil {
log.Println("Closing existing tunnel before starting a new one...")
instanceTunnel.Close()
instanceTunnel = nil
}

numClientsGo := int(numClients)
seedRpcServersGo := C.GoString(seedRpcServers)
seedHexGo := C.GoString(seedHex)
identifierGo := C.GoString(identifier)
fromGo := C.GoString(from)
toGo := C.GoString(to)
udpGo := udp != 0
useTunaGo := useTuna != 0
tunaMaxPriceGo := C.GoString(tunaMaxPrice)
tunaMinFeeGo := C.GoString(tunaMinFee)
tunaFeeRatioGo := float64(tunaFeeRatio)
verboseGo := verbose != 0

if seedHexGo == "" {
log.Println("Seed hex cannot be empty")
return 1
}

if tunaMaxPriceGo == "" {
tunaMaxPriceGo = DefaultTunaMaxPrice
}
if tunaMinFeeGo == "" {
tunaMinFeeGo = DefaultTunaMinFee
}
if tunaFeeRatioGo == 0 {
tunaFeeRatioGo = DefaultTunaFeeRatio
}

seedRpcServerList := strings.Split(seedRpcServersGo, ",")
seedRpcServerAddr := nkngomobile.NewStringArray(seedRpcServerList...)

var seed []byte
var err error

seed, err = hex.DecodeString(seedHexGo)
if err != nil {
log.Println("Invalid seed hex: ", err)
return 2
}
account, err := nkn.NewAccount(seed)
if err != nil {
log.Println("Failed to create account:", err)
return 3
}
clientConfig := &nkn.ClientConfig{
SeedRPCServerAddr: seedRpcServerAddr,
}
walletConfig := &nkn.WalletConfig{
SeedRPCServerAddr: seedRpcServerAddr,
}
sessionConfig := &ncp.Config{
MTU: int32(0),
}

var tsConfig *ts.Config
if useTunaGo {
tsConfig = &ts.Config{
NumTunaListeners: numClientsGo,
SessionConfig: sessionConfig,
TunaMaxPrice: tunaMaxPriceGo,
TunaMinNanoPayFee: tunaMinFeeGo,
TunaNanoPayFeeRatio: tunaFeeRatioGo,
}
}

config := &tunnel.Config{
NumSubClients: numClientsGo,
ClientConfig: clientConfig,
WalletConfig: walletConfig,
TunaSessionConfig: tsConfig,
UDP: udpGo,
Verbose: verboseGo,
}
t, err := tunnel.NewTunnel(account, identifierGo, fromGo, toGo, useTunaGo, config, nil)
if err != nil {
log.Println("Failed to create tunnel:", err)
return 4
}

instanceTunnel = t

go func() {
if err := t.Start(); err != nil {
log.Println("Tunnel failed to start:", err)
}
}()
log.Println("Tunnel started successfully")
return 0
}

//export CloseNknTunnel
func CloseNknTunnel() C.int {
tunnelMutex.Lock()
defer tunnelMutex.Unlock()

if instanceTunnel == nil {
log.Println("No tunnel to close")
return -1
}

instanceTunnel.Close()
instanceTunnel = nil
log.Println("Tunnel closed successfully")
return 0
}

func main() {
defer closeLogger()
}

0 comments on commit c884183

Please sign in to comment.