diff --git a/CMakeLists.txt b/CMakeLists.txt
index 069105e..d61f1ba 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -154,9 +154,18 @@ endif ()
# | SOURCE FILE GLOBS |
# -----------------------------------------------------------------------------
-set (LWIP_SRC_DIR ${PROJ_DIR}/ext/lwip/src)
-set (ZTO_SRC_DIR ${PROJ_DIR}/ext/ZeroTierOne)
-set (LIBZT_SRC_DIR ${PROJ_DIR}/src)
+set (LWIP_SRC_DIR "${PROJ_DIR}/ext/lwip/src")
+set (ZTO_SRC_DIR "${PROJ_DIR}/ext/ZeroTierOne")
+set (LIBZT_SRC_DIR "${PROJ_DIR}/src")
+
+include_directories ("${LIBZT_SRC_DIR}")
+include_directories ("${ZTO_SRC_DIR}/include")
+include_directories ("${ZTO_SRC_DIR}/osdep")
+include_directories ("${ZTO_SRC_DIR}/node")
+include_directories ("${ZTO_SRC_DIR}/service")
+include_directories ("${PROJ_DIR}/include")
+include_directories ("${LWIP_SRC_DIR}/include")
+include_directories ("${LWIP_PORT_DIR}/include")
file (GLOB lwipSrcGlob
${LWIP_SRC_DIR}/netif/*.c
@@ -184,16 +193,6 @@ file (GLOB ExampleAppSrcGlob
${PROJ_DIR}/examples/cpp/sharedlib/*.cpp
${PROJ_DIR}/examples/ztproxy/*.cpp)
-include_directories (${LWIP_SRC_DIR}/include)
-include_directories (${LWIP_PORT_DIR}/include)
-include_directories (${LIBZT_SRC_DIR})
-
-include_directories (${ZTO_SRC_DIR}/include)
-include_directories (${ZTO_SRC_DIR}/osdep)
-include_directories (${ZTO_SRC_DIR}/node)
-include_directories (${ZTO_SRC_DIR}/service)
-
-include_directories (${INCLUDE_PATH})
# header globs for xcode frameworks
file (GLOB frameworkPrivateHeaderGlob
@@ -298,6 +297,7 @@ message (STATUS ${libztSrcGlob})
target_link_libraries (${DYNAMIC_LIB_NAME} lwip_pic zto_pic http_pic)
set_target_properties (${DYNAMIC_LIB_NAME} PROPERTIES OUTPUT_NAME zt)
set_target_properties (${DYNAMIC_LIB_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS true)
+set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
if (BUILDING_ANDROID)
target_link_libraries (${DYNAMIC_LIB_NAME} android log)
diff --git a/Makefile b/Makefile
index 24f24d3..b2a4bf6 100644
--- a/Makefile
+++ b/Makefile
@@ -1,44 +1,44 @@
-#
-# ZeroTier SDK - Network Virtualization Everywhere
-# Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see .
-#
-# --
-#
-# You can be released from the requirements of the license by purchasing
-# a commercial license. Buying such a license is mandatory as soon as you
-# develop commercial closed-source software that incorporates or links
-# directly against ZeroTier software without disclosing the source code
-# of your own application.
-#
-
-# NOTE: This file only exists as a convenience for cleaning. To build, use
-# CMake. Instructions are given in README.md
+# NOTE: This file only exists as a convenience for cleaning and building
+# products for release. To build, use CMake. Instructions in README.md
.PHONY: clean
clean:
- rm -rf bin build
+ rm -rf bin build products tmp
rm -f *.o *.s *.exp *.lib .depend* *.core core
rm -rf .depend
find . -type f \( -name '*.a' -o -name '*.o' -o -name '*.so' -o -name \
- '*.o.d' -o -name '*.out' -o -name '*.log' -o -name '*.dSYM' \) -delete
+ '*.o.d' -o -name '*.out' -o -name '*.log' -o -name '*.dSYM' -o -name '*.dylib' -o -name '*.class' \) -delete
+# Build and package everything
+# This command shall be run twice:
+# (1) Generates projects
+#
+# (2) Build products and package everything
+.PHONY: dist
+dist: patch
+ ./packages/dist.sh
+
+# Initialize submodules and apply patches
+.PHONY: all
+all: update patch
+ cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Release
+ cmake --build build
+
+# Clean build paths
clean_win:
-"rd /S /Q bin"
-"rd /S /Q build"
+# Remove any CMake-generated library-building projects
+clean_packages:
+ rm -rf packages/xcode_ios
+ rm -rf packages/xcode_macos
+
+.PHONY: update
+update:
+ git submodule update --init --recursive
+
+# Patch submodules
patch:
- git -C ext/lwip apply ../lwip.patch
- git -C ext/lwip-contrib apply ../lwip-contrib.patch
\ No newline at end of file
+ -git -C ext/lwip apply ../lwip.patch
+ -git -C ext/lwip-contrib apply ../lwip-contrib.patch
\ No newline at end of file
diff --git a/README.md b/README.md
index 374bf42..9ccf5bf 100644
--- a/README.md
+++ b/README.md
@@ -18,6 +18,9 @@ Library version of [ZeroTier](https://github.com/zerotier/ZeroTierOne)
| Android | | | [libzt.aar](https://download.zerotier.com/RELEASES/1.2.12/dist/libzt/android/libzt-1.2.0r1-android-armeabi-v7a.aar) | [examples/android/ExampleAndroidApp](examples/android/ExampleAndroidApp) | [packages/android](packages/android)|
| Linux | see below | see below | | | see below |
+C API: [libzt.h](include/libzt.h)
+Java JNI API: [ZeroTier.java](packages/android/app/src/main/java/ZeroTier.java)
+
***
### C++ Example
diff --git a/packages/dist.sh b/packages/dist.sh
new file mode 100755
index 0000000..8dcf2fc
--- /dev/null
+++ b/packages/dist.sh
@@ -0,0 +1,211 @@
+#!/bin/bash
+
+# Call this script from the root project directory via `make dist`
+# - submodules will be recursively initialized and updated
+# - patches will be applied to submodules if needed
+# - this script will call CMake to generate library-building packages if necessary
+# - once projects have been generated, this script will use their tooling to build the libraries/packages
+# - when all products have been built and moved to `tmp`, they will be compressed and moved to `products`
+
+PROJNAME="zt"
+LIBNAME="lib"$PROJNAME
+OSNAME=$(uname | tr '[A-Z]' '[a-z]')
+LIBZT_VERSION="1.2.0"
+LIBZT_REVISION="1"
+ZT_CORE_VERSION="1.2.12"
+FILENAME_PREFIX=${LIBNAME}"-"${LIBZT_VERSION}"r"${LIBZT_REVISION}
+
+PROJROOT=$(pwd)
+BUILD_PRODUCTS_DIR=$(pwd)/bin
+LIB_PRODUCTS_DIR=${BUILD_PRODUCTS_DIR}/lib
+FINISHED_PRODUCTS_DIR=$(pwd)/products
+TMP_PRODUCTS_DIR=${BUILD_PRODUCTS_DIR}/tmp
+
+# previously built, will include in package
+WIN_PREBUILT_DIR=${PROJROOT}/prebuilt
+WIN_RELEASE_PRODUCTS_DIR=${WIN_PREBUILT_DIR}/release
+WIN_DEBUG_PRODUCTS_DIR=${WIN_PREBUILT_DIR}/debug
+WIN32_RELEASE_PRODUCTS_DIR=${WIN_RELEASE_PRODUCTS_DIR}/win32
+WIN64_RELEASE_PRODUCTS_DIR=${WIN_RELEASE_PRODUCTS_DIR}/win64
+WIN32_DEBUG_PRODUCTS_DIR=${WIN_DEBUG_PRODUCTS_DIR}/win32
+WIN64_DEBUG_PRODUCTS_DIR=${WIN_DEBUG_PRODUCTS_DIR}/win64
+
+XCODE_IOS_PROJ_DIR=$(pwd)/"packages/xcode_ios"
+XCODE_MACOS_PROJ_DIR=$(pwd)/"packages/xcode_macos"
+
+ANDROID_PROJ_DIR=$(pwd)/"packages/android"
+ANDROID_ARCHIVE_FILENAME="zt.aar"
+
+mkdir ${FINISHED_PRODUCTS_DIR}
+mkdir ${TMP_PRODUCTS_DIR}
+
+# Check that projects exist, generate them and exit if they don't exist
+generate_projects_if_necessary()
+{
+ # iOS
+ if [ ! -d "$XCODE_IOS_PROJ_DIR" ]; then
+ echo "BUILDING: iOS project"
+ should_exit=1
+ mkdir -p $XCODE_IOS_PROJ_DIR
+ cd $XCODE_IOS_PROJ_DIR
+ cmake -G Xcode ../../
+ # Bug in CMake requires us to manually replace architecture strings in project file
+ sed -i '' 's/x86_64/$(CURRENT_ARCH)/g' $PROJNAME.xcodeproj/project.pbxproj
+ cd -
+ fi
+ # macOS
+ if [ ! -d "$XCODE_MACOS_PROJ_DIR" ]; then
+ echo "BUILDING: macOS project"
+ should_exit=1
+ mkdir -p $XCODE_MACOS_PROJ_DIR
+ cd $XCODE_MACOS_PROJ_DIR
+ cmake -G Xcode ../../
+ cd -
+ fi
+ # android?
+ if [[ $should_exit = 1 ]]; then
+ echo "Generated projects. Perform necessary modifications and then re-run this script"
+ echo "Please place previously built windows binaries in ${WIN_PREBUILT_DIR} before running again."
+ exit 0
+ else
+ echo "Projects detected, going to build stage next"
+ fi
+}
+
+# Xcode Frameworks
+build_xcode_targets()
+{
+ CMAKE_CONFIG=${1}
+ UPPERCASE_CONFIG="$(tr '[:lower:]' '[:upper:]' <<< ${1:0:1})${1:1}"
+ if [[ ${2} = *"jni"* ]]; then
+ CMAKE_FLAGS=${CMAKE_FLAGS}" -DJNI=1"
+ fi
+ if [[ $OSNAME = *"darwin"* && ${2} != *"JNI"* ]]; then
+ CURR_BUILD_PRODUCTS_DIR=${LIB_PRODUCTS_DIR}/${UPPERCASE_CONFIG}
+ # (iOS)
+ echo "BUILDING: iOS"
+ cd $XCODE_IOS_PROJ_DIR
+ xcodebuild -target zt -configuration "${UPPERCASE_CONFIG}" -sdk "iphoneos"
+ xcodebuild -target zt-static -configuration "${UPPERCASE_CONFIG}" -sdk "iphoneos"
+ cd -
+ CURR_ARCH="arm64" # anything older should be built custom
+ CURR_TMP_PRODUCT_DIR=${TMP_PRODUCTS_DIR}/ios-${CURR_ARCH}
+ mkdir -p ${CURR_TMP_PRODUCT_DIR}
+ mv ${CURR_BUILD_PRODUCTS_DIR}/*.framework ${CURR_TMP_PRODUCT_DIR}
+ mv ${CURR_BUILD_PRODUCTS_DIR}/libzt.* ${CURR_TMP_PRODUCT_DIR}
+
+ # (macOS)
+ echo "BUILDING: macOS"
+ cd $XCODE_MACOS_PROJ_DIR
+ xcodebuild -target zt -configuration "${UPPERCASE_CONFIG}" -sdk "macosx"
+ xcodebuild -target zt-static -configuration "${UPPERCASE_CONFIG}" -sdk "macosx"
+ xcodebuild -target zt-shared -configuration "${UPPERCASE_CONFIG}" -sdk "macosx"
+ cd -
+ CURR_ARCH=${HOSTTYPE}
+ CURR_TMP_PRODUCT_DIR=${TMP_PRODUCTS_DIR}/macos-${CURR_ARCH}
+ mkdir -p ${CURR_TMP_PRODUCT_DIR}
+ mv ${CURR_BUILD_PRODUCTS_DIR}/*.framework ${CURR_TMP_PRODUCT_DIR}
+ mv ${CURR_BUILD_PRODUCTS_DIR}/libzt.* ${CURR_TMP_PRODUCT_DIR}
+ fi
+}
+
+# Android archive (AAR)
+build_aar()
+{
+ CMAKE_CONFIG=${1}
+ UPPERCASE_CONFIG="$(tr '[:lower:]' '[:upper:]' <<< ${1:0:1})${1:1}"
+ if [[ ${2} = *"jni"* ]]; then
+ CMAKE_FLAGS=${CMAKE_FLAGS}" -DJNI=1"
+ fi
+ CURR_ARCH="armeabi-v7a"
+ CURR_TMP_PRODUCT_DIR=${TMP_PRODUCTS_DIR}/android-${CURR_ARCH}
+ mkdir -p ${CURR_TMP_PRODUCT_DIR}
+ echo "BUILDING: AAR"
+ cd ${ANDROID_PROJ_DIR}
+ ./gradlew assemble${UPPERCASE_CONFIG} # e.g. assembleRelease
+ mv ${ANDROID_PROJ_DIR}/app/build/outputs/aar/app-${CONFIG}.aar ${CURR_TMP_PRODUCT_DIR}/${ANDROID_ARCHIVE_FILENAME}
+ cd -
+}
+
+# Java archive (JAR)
+#Call ordinary CMake build script with JNI flag set, use product in JAR file
+build_jar()
+{
+ CMAKE_CONFIG=${1}
+ UPPERCASE_CONFIG="$(tr '[:lower:]' '[:upper:]' <<< ${1:0:1})${1:1}"
+ if [[ ${2} = *"jni"* ]]; then
+ CMAKE_FLAGS=${CMAKE_FLAGS}" -DJNI=1"
+ fi
+ CURR_ARCH=${HOSTTYPE}
+ CURR_TMP_PRODUCT_DIR=${TMP_PRODUCTS_DIR}/macos-${CURR_ARCH}
+ mkdir -p ${CURR_TMP_PRODUCT_DIR}
+ echo "BUILDING: JAR"
+ rm -rf ${LIB_PRODUCTS_DIR} # clean-lite
+ cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=${CMAKE_CONFIG} "-DJNI=1 -DBUILD_TESTS=0"
+ cmake --build build
+ cd ${PROJROOT}/examples/java
+ cp ../../bin/lib/libzt.dylib .
+ mv ${LIB_PRODUCTS_DIR}/libzt.a ${CURR_TMP_PRODUCT_DIR}/libzt-jni.a
+ mv ${LIB_PRODUCTS_DIR}/libzt.dylib ${CURR_TMP_PRODUCT_DIR}/libzt-jni.dylib
+ javac com/zerotier/libzt/*.java
+ jar cf libzt.jar libzt.dylib com/zerotier/libzt/*.class
+ mv libzt.jar ${CURR_TMP_PRODUCT_DIR}
+ cd -
+}
+
+# Build everything (to a specific configuration)
+build()
+{
+ if [[ $OSNAME == *"darwin"* ]]; then
+ build_xcode_targets ${1} ${2}
+ build_aar ${1} ${2}
+ fi
+ build_jar ${1} ${2}
+}
+
+# Package everything together
+package_products()
+{
+ CONFIG=${1}
+ PRODUCT_FILENAME=${FILENAME_PREFIX}-${CONFIG}.tar.gz
+ echo "Making: " ${FINISHED_PRODUCTS_DIR}/${PRODUCT_FILENAME}
+ cd ${TMP_PRODUCTS_DIR}
+ tar -zcvf ${PRODUCT_FILENAME} .
+ mv *.tar.gz ${FINISHED_PRODUCTS_DIR}
+ cd -
+}
+
+copy_windows_targets()
+{
+ echo "Copying prebuilt windows binaries into temporary staging directory"
+ if [ ! -d "$XCODE_MACOS_PROJ_DIR" ]; then
+ echo "WARNING: windows products directory appears to be empty. Exiting"
+ exit 0
+ fi
+ CONFIG=${1}
+ cp -r ${WIN_PREBUILT_DIR}/${CONFIG}/win32 ${TMP_PRODUCTS_DIR}
+ cp -r ${WIN_PREBUILT_DIR}/${CONFIG}/win64 ${TMP_PRODUCTS_DIR}
+}
+
+build_all_products()
+{
+ CONFIG=${1}
+ build ${CONFIG}
+ copy_windows_targets ${CONFIG}
+ package_products ${CONFIG}
+}
+
+main()
+{
+ # prepare environment
+ generate_projects_if_necessary
+ mkdir -p ${WIN32_RELEASE_PRODUCTS_DIR}
+ mkdir -p ${WIN64_RELEASE_PRODUCTS_DIR}
+ mkdir -p ${WIN32_DEBUG_PRODUCTS_DIR}
+ mkdir -p ${WIN64_DEBUG_PRODUCTS_DIR}
+ # build
+ build_all_products "release"
+ build_all_products "debug"
+}
+
+main "$@"
\ No newline at end of file