Browse Source

compile go code to static library & call via main.cpp

This allows CMake to manage the linkage of C/C++ libraries rather than an exponentially growing list of cgo directives based on build options
Grant Limberg 5 years ago
parent
commit
c8f640f3f2
4 changed files with 64 additions and 22 deletions
  1. 30 12
      CMakeLists.txt
  2. 13 6
      cmd/zerotier/zerotier.go
  3. 19 0
      main.cpp
  4. 2 4
      pkg/zerotier/node.go

+ 30 - 12
CMakeLists.txt

@@ -56,6 +56,7 @@ if(WIN32)
 else(WIN32)
 	if(APPLE)
 		message("++ Setting MacOS Compiler Flags ${CMAKE_BUILD_TYPE}")
+
 		add_compile_options(
 			-Wall
 			-Wno-deprecated
@@ -113,18 +114,35 @@ add_subdirectory(controller)
 add_subdirectory(osdep)
 add_subdirectory(serviceiocore)
 
-set(
-	zt_core
-	zt_osdep
-	zt_controller
-	zt_service_io_core
-)
+file(GLOB go_src 
+	${CMAKE_SOURCE_DIR}/cmd/*.go
+	${CMAKE_SOURCE_DIR}/cmd/cmd/*.go
+	${CMAKE_SOURCE_DIR}/pkg/zerotier/*.go)
 
-add_custom_target(zerotier ALL
-	WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
-	COMMAND rm -f ./build/zerotier && go build ${GO_BUILD_TAGS} -trimpath -ldflags -s -buildmode=pie -o ./build/zerotier cmd/zerotier/zerotier.go
-	BYPRODUCTS zerotier
+add_custom_command(
+	OUTPUT ${CMAKE_BINARY_DIR}/zerotier_cgo.h ${CMAKE_BINARY_DIR}/zerotier_cgo.a
+	COMMAND go build -buildmode=c-archive -o ${CMAKE_BINARY_DIR}/zerotier_cgo.a ${CMAKE_SOURCE_DIR}/cmd/zerotier/zerotier.go
+	IMPLICIT_DEPENDS go ${go_src}
+	COMMENT "Compiling Go Code..."
+)
+add_custom_target(
+	zerotier_cgo_target 
+	DEPENDS ${CMAKE_BINARY_DIR}/zerotier_cgo.a
+	SOURCES ${go_src}
+)
+add_library(zerotier_cgo STATIC IMPORTED GLOBAL)
+add_dependencies(zerotier_cgo zerotier_cgo_target)
+set_target_properties(
+	zerotier_cgo
+	PROPERTIES
+	IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/zerotier_cgo.a
+	INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_BINARY_DIR}
 )
-add_dependencies(zerotier zt_osdep zt_core zt_controller zt_service_io_core)
 
-set(ADDITIONAL_MAKE_CLEAN_FILES zerotier)
+add_executable(zerotier main.cpp)
+target_include_directories(zerotier PUBLIC ${CMAKE_BINARY_DIR})
+add_dependencies(zerotier zerotier_cgo zt_osdep zt_core zt_controller zt_service_io_core)
+target_link_libraries(zerotier zerotier_cgo zt_osdep zt_core zt_controller zt_service_io_core)
+if (APPLE)
+	target_link_libraries(zerotier "-framework CoreFoundation" "-framework Security")
+endif (APPLE)

+ 13 - 6
cmd/zerotier/zerotier.go

@@ -13,6 +13,8 @@
 
 package main
 
+import "C"
+
 import (
 	"flag"
 	"fmt"
@@ -28,15 +30,15 @@ import (
 )
 
 func getAuthTokenPaths(basePath string) (p []string) {
-	p = append(p,path.Join(basePath,"authtoken.secret"))
+	p = append(p, path.Join(basePath, "authtoken.secret"))
 	userHome, _ := os.UserHomeDir()
 	if len(userHome) > 0 {
 		if runtime.GOOS == "darwin" {
-			p = append(p,path.Join(userHome,"Library","Application Support","ZeroTier","authtoken.secret"))
-			p = append(p,path.Join(userHome,"Library","Application Support","ZeroTier","One","authtoken.secret"))
+			p = append(p, path.Join(userHome, "Library", "Application Support", "ZeroTier", "authtoken.secret"))
+			p = append(p, path.Join(userHome, "Library", "Application Support", "ZeroTier", "One", "authtoken.secret"))
 		}
-		p = append(p,path.Join(userHome,".zerotierauth"))
-		p = append(p,path.Join(userHome,".zeroTierOneAuthToken"))
+		p = append(p, path.Join(userHome, ".zerotierauth"))
+		p = append(p, path.Join(userHome, ".zeroTierOneAuthToken"))
 	}
 	return p
 }
@@ -45,10 +47,15 @@ func authTokenRequired(authToken string) {
 	if len(authToken) == 0 {
 		fmt.Println("FATAL: unable to read API authorization token from command line or any filesystem location.")
 		os.Exit(1)
+
 	}
 }
 
 func main() {
+}
+
+//export ZeroTierMain
+func ZeroTierMain() {
 	// Reduce Go's thread and memory footprint. This would slow things down if the Go code
 	// were doing a lot, but it's not. It just manages the core and is not directly involved
 	// in pushing a lot of packets around. If that ever changes this should be adjusted.
@@ -99,7 +106,7 @@ func main() {
 			tmp, _ := ioutil.ReadFile(p)
 			if len(tmp) > 0 {
 				authToken = string(tmp)
-				break;
+				break
 			}
 		}
 		if len(authToken) == 0 {

+ 19 - 0
main.cpp

@@ -0,0 +1,19 @@
+/*
+ * Copyright (c)2013-2020 ZeroTier, Inc.
+ *
+ * Use of this software is governed by the Business Source License included
+ * in the LICENSE.TXT file in the project's root directory.
+ *
+ * Change Date: 2024-01-01
+ *
+ * On the date above, in accordance with the Business Source License, use
+ * of this software will be governed by version 2.0 of the Apache License.
+ */
+/****/
+
+#include "zerotier_cgo.h"
+
+int main() {
+    ZeroTierMain();
+    return 0;
+}

+ 2 - 4
pkg/zerotier/node.go

@@ -14,10 +14,8 @@
 package zerotier
 
 // #cgo CFLAGS: -O3
-// #cgo darwin,!central LDFLAGS: ${SRCDIR}/../../build/serviceiocore/libzt_service_io_core.a ${SRCDIR}/../../build/core/libzt_core.a ${SRCDIR}/../../build/osdep/libzt_osdep.a ${SRCDIR}/../../build/controller/libzt_controller.a -lc++ -lpthread
-// #cgo darwin,central LDFLAGS: ${SRCDIR}/../../build/serviceiocore/libzt_service_io_core.a ${SRCDIR}/../../build/core/libzt_core.a ${SRCDIR}/../../build/osdep/libzt_osdep.a ${SRCDIR}/../../build/controller/libzt_controller.a ${SRCDIR}/../../build/lib/libredis++.a  /usr/local/lib/libhiredis.a /usr/local/opt/libpq/lib/libpq.a -lc++ -lpthread
-// #cgo linux,!central android,!central LDFLAGS: ${SRCDIR}/../../build/serviceiocore/libzt_service_io_core.a ${SRCDIR}/../../build/core/libzt_core.a ${SRCDIR}/../../build/osdep/libzt_osdep.a ${SRCDIR}/../../build/controller/libzt_controller.a -lstdc++ -lpthread -lm
-// #cgo linux,central android,central LDFLAGS: ${SRCDIR}/../../build/serviceiocore/libzt_service_io_core.a ${SRCDIR}/../../build/core/libzt_core.a ${SRCDIR}/../../build/osdep/libzt_osdep.a ${SRCDIR}/../../build/controller/libzt_controller.a ${SRCDIR}/../../build/lib/libredis++.a -lhiredis -lpq -lstdc++ -lpthread -lm
+// #cgo darwin LDFLAGS: -Wl,-undefined -Wl,dynamic_lookup
+// #cgo !darwin LDFLAGS: -Wl,-unresolved-symbols=ignore-all
 // #include "../../serviceiocore/GoGlue.h"
 import "C"