This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
zhangyang-libzt/dist.sh
2021-02-05 15:58:48 -08:00

736 lines
23 KiB
Bash
Executable File

#!/bin/bash
# This script works in conjunction with the Makefile and CMakeLists.txt. It is
# intended to be called from the Makefile, it generates projects and builds
# targets as specified in CMakeLists.txt. In addition, this script is
# responsible for packaging all of the resultant builds, licenses, and
# documentation as well as controlling the installation and remote execution of
# tests on mobile devices.
# Example workflow for producing a full release package:
#
# (1) On packaging platform, build most targets (including android and ios):
# (1a) make all
# (1b) make wrap
# (2) On other supported platforms, build remaining supported targets
# and copy them into a directory structure that is expected by a later stage:
# (2a) make all
# (2b) make wrap
# (3) Copy all resultant $(ARCH)_product directories to root project directory
# of packaging platform. For instance:
#
# libzt
# ├── README.md
# ├── products
# ├── linux-x86_64_products
# ├── linux-armv7l_products
# ├── linux-armv6l_products
# ├── products
# ├── win_products
# └── ...
#
# (4) Merge all builds into single `products` directory and package:
# (4a) make clean
# (4a) make dist
CMAKE=cmake
BUILD_CONCURRENCY=
#"-j 2"
OSNAME=$(uname | tr '[A-Z]' '[a-z]')
BUILD_TMP=$(pwd)/tmp
ANDROID_PROJ_DIR=$(pwd)/ports/android
XCODE_IOS_PROJ_DIR=$(pwd)/ports/xcode_ios
XCODE_IOS_SIMULATOR_PROJ_DIR=$(pwd)/ports/xcode_ios_simulator
XCODE_MACOS_PROJ_DIR=$(pwd)/ports/xcode_macos
# Generates wrapper source files for various target languages
generate_swig_wrappers()
{
SRC=../src
cd ports/;
# C#
mkdir -p ${SRC}/csharp
swig -csharp -c++ zt.i
# Prepend our callback garb to libzt.cs, copy new source files into src/csharp
cat csharp/csharp_callback.cs libzt.cs > libzt_concat.cs
rm libzt.cs
mv libzt_concat.cs libzt.cs
mv -f *.cs zt_wrap.cxx ${SRC}/csharp/
# Javascript
# Build for all three engines. Why not?
ENGINE=jsc
mkdir -p ${SRC}/js/${ENGINE}
swig -javascript -${ENGINE} -c++ zt.i
mv zt_wrap.cxx ${SRC}/js/${ENGINE}
ENGINE=v8
mkdir -p ${SRC}/js/${ENGINE}
swig -javascript -${ENGINE} -c++ zt.i
mv zt_wrap.cxx ${SRC}/js/${ENGINE}
ENGINE=node
mkdir -p ${SRC}/js/${ENGINE}
swig -javascript -${ENGINE} -c++ zt.i
mv -f zt_wrap.cxx ${SRC}/js/${ENGINE}
# Python
mkdir -p ${SRC}/python
swig -python -c++ zt.i
mv -f zt_wrap.cxx *.py ${SRC}/python
# Lua
mkdir -p ${SRC}/lua
swig -lua -c++ zt.i
mv -f zt_wrap.cxx ${SRC}/lua
# Go 64
mkdir -p ${SRC}/go64
swig -intgosize 64 -go -c++ zt.i
mv -f zt_wrap.cxx *.go *.c ${SRC}/go64
# Go 32
mkdir -p ${SRC}/go32
swig -intgosize 32 -go -c++ zt.i
mv -f zt_wrap.cxx *.go *.c ${SRC}/go32
cd -
}
# Generates projects if needed
generate_projects()
{
if [[ ! $OSNAME = *"darwin"* ]]; then
exit 0
fi
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
if [[ $OSNAME = *"darwin"* ]]; then
# iOS (SDK 11+, 64-bit only, arm64)
if [ ! -d "$XCODE_IOS_PROJ_DIR" ]; then
mkdir -p $XCODE_IOS_PROJ_DIR
cd $XCODE_IOS_PROJ_DIR
$CMAKE -G Xcode ../../ -DIOS_FRAMEWORK=1 -DIOS_ARM64=1
# Manually replace arch strings in project file
sed -i '' 's/x86_64/$(CURRENT_ARCH)/g' zt.xcodeproj/project.pbxproj
cd -
fi
if [ ! -d "$XCODE_IOS_SIMULATOR_PROJ_DIR" ]; then
mkdir -p $XCODE_IOS_SIMULATOR_PROJ_DIR
cd $XCODE_IOS_SIMULATOR_PROJ_DIR
$CMAKE -G Xcode ../../ -DIOS_FRAMEWORK=1
# Manually replace arch strings in project file
#sed -i '' 's/x86_64/$(CURRENT_ARCH)/g' zt.xcodeproj/project.pbxproj
cd -
fi
# macOS
if [ ! -d "$XCODE_MACOS_PROJ_DIR" ]; then
mkdir -p $XCODE_MACOS_PROJ_DIR
cd $XCODE_MACOS_PROJ_DIR
$CMAKE -G Xcode ../../ -DMACOS_FRAMEWORK=1
cd -
fi
fi
}
# Build framework for iOS (with embedded static library)
ios()
{
if [[ ! $OSNAME = *"darwin"* ]]; then
exit 0
fi
generate_projects # if needed
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
UPPERCASE_CONFIG="$(tr '[:lower:]' '[:upper:]' <<< ${1:0:1})${1:1}"
cd $XCODE_IOS_PROJ_DIR
# Framework
xcodebuild -arch arm64 -target zt -configuration "$UPPERCASE_CONFIG" -sdk "iphoneos"
cd -
IOS_OUTPUT_DIR=$(pwd)/lib/$1/ios
mkdir -p $IOS_OUTPUT_DIR
rm -rf $IOS_OUTPUT_DIR/zt.framework # Remove prior to move to prevent error
mv $XCODE_IOS_PROJ_DIR/$UPPERCASE_CONFIG-iphoneos/* $IOS_OUTPUT_DIR
cd $XCODE_IOS_SIMULATOR_PROJ_DIR
# Framework
xcodebuild -target zt -configuration "$UPPERCASE_CONFIG" -sdk "iphonesimulator"
cd -
SIMULATOR_OUTPUT_DIR=$(pwd)/lib/$1/ios-simulator
mkdir -p $SIMULATOR_OUTPUT_DIR
rm -rf $SIMULATOR_OUTPUT_DIR/zt.framework # Remove prior to move to prevent error
mv $XCODE_IOS_SIMULATOR_PROJ_DIR/$UPPERCASE_CONFIG-iphonesimulator/* $SIMULATOR_OUTPUT_DIR
# Combine the two archs
lipo -create $IOS_OUTPUT_DIR/zt.framework/zt $SIMULATOR_OUTPUT_DIR/zt.framework/zt -output $IOS_OUTPUT_DIR/zt.framework/zt
# Clean up
rm -rf $SIMULATOR_OUTPUT_DIR
}
# Build framework for current host (macOS only)
macos()
{
if [[ ! $OSNAME = *"darwin"* ]]; then
exit 0
fi
generate_projects # if needed
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
UPPERCASE_CONFIG="$(tr '[:lower:]' '[:upper:]' <<< ${1:0:1})${1:1}"
cd $XCODE_MACOS_PROJ_DIR
# Framework
xcodebuild -target zt -configuration "$UPPERCASE_CONFIG" -sdk "macosx"
cd -
OUTPUT_DIR=$(pwd)/lib/$1/macos-universal
mkdir -p $OUTPUT_DIR
rm -rf $OUTPUT_DIR/zt.framework # Remove prior to move to prevent error
mv $XCODE_MACOS_PROJ_DIR/$UPPERCASE_CONFIG/* $OUTPUT_DIR
}
# Build xcframework
xcframework()
{
if [[ ! $OSNAME = *"darwin"* ]]; then
exit 0
fi
generate_projects # if needed
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
UPPERCASE_CONFIG="$(tr '[:lower:]' '[:upper:]' <<< ${1:0:1})${1:1}"
OUTPUT_DIR=$(pwd)/lib/$1
cd $XCODE_MACOS_PROJ_DIR
xcodebuild -target zt -configuration "$UPPERCASE_CONFIG" -sdk "macosx"
cd $XCODE_IOS_PROJ_DIR
xcodebuild -arch arm64 -target zt -configuration "$UPPERCASE_CONFIG" -sdk "iphoneos"
cd $XCODE_IOS_SIMULATOR_PROJ_DIR
xcodebuild -target zt -configuration "$UPPERCASE_CONFIG" -sdk "iphonesimulator"
mkdir -p $OUTPUT_DIR
rm -rf $OUTPUT_DIR/zt.xcframework # Remove prior to move to prevent error
xcodebuild -create-xcframework \
-framework $XCODE_MACOS_PROJ_DIR/$UPPERCASE_CONFIG/zt.framework \
-framework $XCODE_IOS_PROJ_DIR/$UPPERCASE_CONFIG-iphoneos/zt.framework \
-framework $XCODE_IOS_SIMULATOR_PROJ_DIR/$UPPERCASE_CONFIG-iphonesimulator/zt.framework \
-output $OUTPUT_DIR/zt.xcframework
}
# Build Java JAR for current host (uses JNI)
host_jar()
{
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
copy_root_java_sources_to_projects
NORMALIZED_OSNAME=$OSNAME
if [[ $OSNAME = *"darwin"* ]]; then
DYNAMIC_LIB_NAME="libzt.dylib"
NORMALIZED_OSNAME="macos"
fi
if [[ $OSNAME = *"linux"* ]]; then
DYNAMIC_LIB_NAME="libzt.so"
fi
LIB_OUTPUT_DIR=$(pwd)/lib/$1/${NORMALIZED_OSNAME}-$(uname -m)
mkdir -p $LIB_OUTPUT_DIR
rm -rf $LIB_OUTPUT_DIR/zt.jar
# Build dynamic library
BUILD_DIR=$(pwd)/tmp/${NORMALIZED_OSNAME}-$(uname -m)-jni-$1
UPPERCASE_CONFIG="$(tr '[:lower:]' '[:upper:]' <<< ${1:0:1})${1:1}"
$CMAKE -H. -B$BUILD_DIR -DCMAKE_BUILD_TYPE=$UPPERCASE_CONFIG -DSDK_JNI=ON "-DSDK_JNI=1"
$CMAKE --build $BUILD_DIR $BUILD_CONCURRENCY
# Copy dynamic library from previous build step
# And, remove any lib that may exist prior. We don't want accidental successes
cd $(pwd)/ports/java
rm $DYNAMIC_LIB_NAME
mv $BUILD_DIR/lib/$DYNAMIC_LIB_NAME .
# Begin constructing JAR
export JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF8
javac com/zerotier/libzt/*.java
jar cf zt.jar $DYNAMIC_LIB_NAME com/zerotier/libzt/*.class
rm $DYNAMIC_LIB_NAME
cd -
# Move completed JAR
LIB_OUTPUT_DIR=$(pwd)/lib/$1/${NORMALIZED_OSNAME}-$(uname -m)
mkdir -p $LIB_OUTPUT_DIR
mv $(pwd)/ports/java/zt.jar $LIB_OUTPUT_DIR
# Build sample app classes
# Remove old dynamic library if it exists
rm -rf $(pwd)/examples/java/$DYNAMIC_LIB_NAME
javac -cp ".:"$LIB_OUTPUT_DIR/zt.jar $(pwd)/examples/java/src/com/zerotier/libzt/javasimpleexample/*.java
# To run:
# jar xf $LIB_OUTPUT_DIR/zt.jar libzt.dylib
# cp libzt.dylib examples/java/
# java -cp "lib/debug/macos-x86_64/zt.jar:examples/java/src/main/java" ExampleApp
}
# Build all ordinary library types for current host
host_pinvoke()
{
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
NORMALIZED_OSNAME=$OSNAME
if [[ $OSNAME = *"darwin"* ]]; then
DYNAMIC_LIB_NAME="libzt.dylib"
NORMALIZED_OSNAME="macos"
fi
if [[ $OSNAME = *"linux"* ]]; then
DYNAMIC_LIB_NAME="libzt.so"
fi
# CMake build files
BUILD_DIR=$(pwd)/tmp/${NORMALIZED_OSNAME}-$(uname -m)-$1
mkdir -p $BUILD_DIR
# Where to place results
BIN_OUTPUT_DIR=$(pwd)/bin/$1/${NORMALIZED_OSNAME}-$(uname -m)
mkdir -p $BIN_OUTPUT_DIR
rm -rf $BIN_OUTPUT_DIR/*
LIB_OUTPUT_DIR=$(pwd)/lib/$1/${NORMALIZED_OSNAME}-$(uname -m)-pinvoke
mkdir -p $LIB_OUTPUT_DIR
rm -rf $LIB_OUTPUT_DIR/libzt.a $LIB_OUTPUT_DIR/$DYNAMIC_LIB_NAME $LIB_OUTPUT_DIR/libztcore.a
# Build
cmake -DZTS_PINVOKE=True -H. -B$BUILD_DIR -DCMAKE_BUILD_TYPE=$1
$CMAKE --build $BUILD_DIR $BUILD_CONCURRENCY
# Move and clean up
cp -f $BUILD_DIR/bin/* $BIN_OUTPUT_DIR
cp -f $BUILD_DIR/lib/* $LIB_OUTPUT_DIR
clean_post_build
}
# Build all ordinary library types for current host
host()
{
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
NORMALIZED_OSNAME=$OSNAME
if [[ $OSNAME = *"darwin"* ]]; then
DYNAMIC_LIB_NAME="libzt.dylib"
NORMALIZED_OSNAME="macos"
fi
if [[ $OSNAME = *"linux"* ]]; then
DYNAMIC_LIB_NAME="libzt.so"
fi
# CMake build files
BUILD_DIR=$(pwd)/tmp/${NORMALIZED_OSNAME}-$(uname -m)-$1
mkdir -p $BUILD_DIR
# Where to place results
BIN_OUTPUT_DIR=$(pwd)/bin/$1/${NORMALIZED_OSNAME}-$(uname -m)
mkdir -p $BIN_OUTPUT_DIR
rm -rf $BIN_OUTPUT_DIR/*
LIB_OUTPUT_DIR=$(pwd)/lib/$1/${NORMALIZED_OSNAME}-$(uname -m)
mkdir -p $LIB_OUTPUT_DIR
rm -rf $LIB_OUTPUT_DIR/libzt.a $LIB_OUTPUT_DIR/$DYNAMIC_LIB_NAME $LIB_OUTPUT_DIR/libztcore.a
# Build
$CMAKE -H. -B$BUILD_DIR -DCMAKE_BUILD_TYPE=$1
$CMAKE --build $BUILD_DIR $BUILD_CONCURRENCY
# Move and clean up
cp -f $BUILD_DIR/bin/* $BIN_OUTPUT_DIR
cp -f $BUILD_DIR/lib/* $LIB_OUTPUT_DIR
clean_post_build
}
# Set important variables for Android builds
set_android_env()
{
#JDK=jdk1.8.0_202.jdk
# Set ANDROID_HOME because setting sdk.dir in local.properties isn't always reliable
export ANDROID_HOME=/Users/$USER/Library/Android/sdk
export PATH=/Library/Java/JavaVirtualMachines/$JDK/Contents/Home/bin/:${PATH}
export PATH=/Users/$USER/Library/Android/sdk/platform-tools/:${PATH}
GRADLE_ARGS=--stacktrace
ANDROID_APP_NAME=com.example.mynewestapplication
}
# Build android AAR from ports/android
android()
{
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
set_android_env
copy_root_java_sources_to_projects
# NOTE: There's no reason this won't build on linux, it's just that
# for our purposes we limit this to execution on macOS
if [[ ! $OSNAME = *"darwin"* ]]; then
exit 0
fi
# CMake build files
BUILD_DIR=$(pwd)/tmp/android-$1
mkdir -p $BUILD_DIR
# If clean requested, remove temp build dir
if [[ $1 = *"clean"* ]]; then
rm -rf $BUILD_DIR
exit 0
fi
# Where to place results
LIB_OUTPUT_DIR=$(pwd)/lib/$1/android
mkdir -p $LIB_OUTPUT_DIR
# Build
UPPERCASE_CONFIG="$(tr '[:lower:]' '[:upper:]' <<< ${1:0:1})${1:1}"
CMAKE_FLAGS="-DSDK_JNI=1 -DSDK_JNI=ON"
cd $ANDROID_PROJ_DIR
./gradlew $GRADLE_ARGS --recompile-scripts
./gradlew $GRADLE_ARGS assemble$UPPERCASE_CONFIG # assembleRelease / assembleDebug
mv $ANDROID_PROJ_DIR/app/build/outputs/aar/app-$1.aar \
$LIB_OUTPUT_DIR/libzt-$1.aar
cd -
}
# Remove intermediate object files and/or libraries
clean_post_build()
{
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
find $(pwd)/lib -type f -name 'liblwip_pic.a' -exec rm {} +
find $(pwd)/lib -type f -name 'liblwip.a' -exec rm {} +
find $(pwd)/lib -type f -name 'libminiupnpc.a' -exec rm {} +
find $(pwd)/lib -type f -name 'libminiupnpc_pic.a' -exec rm {} +
find $(pwd)/lib -type f -name 'libnatpmp.a' -exec rm {} +
find $(pwd)/lib -type f -name 'libnatpmp_pic.a' -exec rm {} +
find $(pwd)/lib -type f -name 'libzto_pic.a' -exec rm {} +
find $(pwd)/lib -type f -name 'libzt_pic.a' -exec rm {} +
}
# General clean
clean()
{
# Remove all temporary build files, products, etc
rm -rf builds tmp lib bin products
rm -f *.o *.s *.exp *.lib *.core core
# Generally search for and remove object files, libraries, etc
find . -path './*_products' -prune -type f \( -name '*.dylib' -o -name '*.dll' -o -name '*.so' -o -name \
'*.a' -o -name '*.o' -o -name '*.exe' -o -name '*.o.d' -o -name \
'*.out' -o -name '*.log' -o -name '*.dSYM' -o -name '*.class' \) -delete
# Remove any sources copied to project directories
rm -rf ports/android/app/src/main/java/com/zerotier/libzt/*.java
rm -rf ports/java/com/zerotier/libzt/*.java
}
# Copy and rename Android AAR from lib to example app directory
prep_android_example()
{
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
mkdir -p examples/android/ExampleAndroidApp/app/libs/
cp -f lib/$1/android/libzt-$1.aar \
examples/android/ExampleAndroidApp/app/libs/libzt.aar
}
# Clean Android project
clean_android_project()
{
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
set_android_env
ANDROID_EXAMPLE_PROJ_DIR="examples/android/ExampleAndroidApp"
cd $ANDROID_EXAMPLE_PROJ_DIR
./gradlew $GRADLE_ARGS clean
./gradlew $GRADLE_ARGS cleanBuildCache
cd -
}
# Build APK from AAR and sources
build_android_app()
{
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
set_android_env
ANDROID_EXAMPLE_PROJ_DIR="examples/android/ExampleAndroidApp"
UPPERCASE_CONFIG="$(tr '[:lower:]' '[:upper:]' <<< ${1:0:1})${1:1}"
cd $ANDROID_EXAMPLE_PROJ_DIR
./gradlew assemble$UPPERCASE_CONFIG
cd -
}
# Stops an Android app that is already installed on device
stop_android_app()
{
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
set_android_env
adb shell am force-stop $ANDROID_APP_NAME
}
# Starts an Android app that is already installed on device
start_android_app()
{
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
set_android_env
adb shell monkey -p $ANDROID_APP_NAME 1
}
# Copy and install example Android app on device
install_android_app()
{
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
set_android_env
if [[ $1 = "release" ]]; then
APKNAME=app-$1-"unsigned"
else
APKNAME=app-$1
fi
APK=examples/android/ExampleAndroidApp/app/build/outputs/apk/$1/$APKNAME.apk
echo "Installing $APK ..."
adb install -r $APK
}
# Perform all steps necessary to run a new instance of the app on device
run_android_app()
{
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
stop_android_app
prep_android_example $1
clean_android_project
# The following two functions take 'debug' as an argument regardless
# of the build type since the native code is built with the proper
# configuration anyway.
build_android_app "debug"
install_android_app "debug"
start_android_app
}
# View ADB logs of running Android app
android_app_log()
{
set_android_env
if [[ $OSNAME = *"darwin"* ]]; then
adb logcat
fi
}
# View ADB logs of running Android app (filtered, must restart for each app re-launch)
android_app_log_filtered()
{
set_android_env
if [[ $OSNAME = *"darwin"* ]]; then
adb logcat | grep -F "`adb shell ps | grep $ANDROID_APP_NAME | cut -c10-15`"
fi
}
# Copy java sources to projects before build process. This is so
# that we only have to maintain one set of sources for multiple java-
# based projects.
copy_root_java_sources_to_projects()
{
cp -f src/java/*.java ports/android/app/src/main/java/com/zerotier/libzt
cp -f src/java/*.java ports/java/com/zerotier/libzt/
}
# At the end of build stage, print contents and trees for inspection
display()
{
find $(pwd)/lib -type f -name 'zt.jar' -exec echo -e "\n" \; -exec ls {} \; -exec jar tf {} +
echo -e "\n"
tree $(pwd)/lib
}
# Merge all remotely-built targets. This is used before dist()
merge()
{
if [ -d "darwin-x86_64_products" ]; then
rsync -a darwin-x86_64_products/ products/
else
echo "Warning: darwin-x86_64_products is missing"
fi
# x86_64 64-bit linux
REMOTE_PRODUCTS_DIR=linux-x86_64_products
if [ -d "$REMOTE_PRODUCTS_DIR" ]; then
rsync -a $REMOTE_PRODUCTS_DIR/ products/
echo "Merged products from " $REMOTE_PRODUCTS_DIR " to " products
else
echo "Warning: $REMOTE_PRODUCTS_DIR is missing"
fi
# armv7l linux
REMOTE_PRODUCTS_DIR=linux-armv7l_products
if [ -d "$REMOTE_PRODUCTS_DIR" ]; then
rsync -a $REMOTE_PRODUCTS_DIR/ products/
echo "Merged products from " $REMOTE_PRODUCTS_DIR " to " products
else
echo "Warning: $REMOTE_PRODUCTS_DIR is missing"
fi
# armv6l linux
REMOTE_PRODUCTS_DIR=linux-armv6l_products
if [ -d "$REMOTE_PRODUCTS_DIR" ]; then
rsync -a $REMOTE_PRODUCTS_DIR/ products/
echo "Merged products from " $REMOTE_PRODUCTS_DIR " to " products
else
echo "Warning: $REMOTE_PRODUCTS_DIR is missing"
fi
# 32/64-bit windows
REMOTE_PRODUCTS_DIR=win_products
if [ -d "$REMOTE_PRODUCTS_DIR" ]; then
rsync -a $REMOTE_PRODUCTS_DIR/ products/
echo "Merged products from " $REMOTE_PRODUCTS_DIR " to " products
else
echo "Warning: $REMOTE_PRODUCTS_DIR is missing"
fi
}
# On hosts which are not the final packaging platform (e.g. armv7, armv6l, etc)
# we will rename the products directory so that we can merge() it at a later
# stage on the packaging platform
wrap()
{
ARCH_WRAP_DIR=$OSNAME"-"$(uname -m)_products
cp -rf lib $ARCH_WRAP_DIR
echo "Copied products to:" $ARCH_WRAP_DIR
PROD_FILENAME=$ARCH_WRAP_DIR.tar.gz
tar --exclude=$PROD_FILENAME -zcvf $PROD_FILENAME -C $ARCH_WRAP_DIR .
}
# Renames and copies licenses for libzt and each of its dependencies
package_licenses()
{
CURR_DIR=$1
DEST_DIR=$2
mkdir -p $DEST_DIR
cp $CURR_DIR/ext/lwip/COPYING $DEST_DIR/LWIP-LICENSE.BSD
cp $CURR_DIR/ext/concurrentqueue/LICENSE.md $DEST_DIR/CONCURRENTQUEUE-LICENSE.BSD
cp $CURR_DIR/LICENSE.txt $DEST_DIR/ZEROTIER-LICENSE.BSL-1.1
cp $CURR_DIR/include/net/ROUTE_H-LICENSE.APSL $DEST_DIR/ROUTE_H-LICENSE.APSL
cp $CURR_DIR/include/net/ROUTE_H-LICENSE $DEST_DIR/ROUTE_H-LICENSE
}
# Copies binaries, documentation, licenses, source, etc into a products
# directory and then tarballs everything together
package_everything()
{
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
LIBZT_VERSION=$(git describe)
PROD_NAME=$LIBZT_VERSION-$(date '+%Y%m%d_%H-%M')-$1
PROD_DIR=$(pwd)/products/$PROD_NAME/
# Make products directory
# Licenses
package_licenses $(pwd) $PROD_DIR/licenses
# Examples
mkdir -p $PROD_DIR/examples
cp examples/cpp/* $PROD_DIR/examples
# Source
mkdir -p $PROD_DIR/src
cp src/*.cpp src/*.hpp src/*.c src/*.h $PROD_DIR/src
cp $(pwd)/README.pdf $PROD_DIR/README.pdf
# Header(s)
mkdir -p $PROD_DIR/include
cp $(pwd)/include/*.h $PROD_DIR/include
# Libraries
mkdir -p $PROD_DIR/lib
cp -r $(pwd)/products/$1/* $PROD_DIR/lib
rm -rf $(pwd)/products/$1
# Clean
find $PROD_DIR -type f \( -name '*.DS_Store' -o -name 'thumbs.db' \) -delete
# Record the version (and each submodule's version)
echo "$(git describe)" > $PROD_DIR/VERSION
echo -e "$(git submodule status | awk '{$1=$1};1')" >> $PROD_DIR/VERSION
echo -e "$(cat ext/ZeroTierOne/version.h | grep ZEROTIER_ONE_VERSION | sed 's/\#define//g' | awk '{$1=$1};1')" >> $PROD_DIR/VERSION
echo "$(date)" >> $PROD_DIR/VERSION
# Tar everything
PROD_FILENAME=$(pwd)/products/$PROD_NAME.tar.gz
tar --exclude=$PROD_FILENAME -zcvf $PROD_FILENAME -C $PROD_DIR .
if [[ $OSNAME = *"darwin"* ]]; then
md5 $PROD_FILENAME
fi
if [[ $OSNAME = *"linux"* ]]; then
md5sum $PROD_FILENAME
fi
# Print results for post-build inspection
echo -e "\n"
tree $PROD_DIR
cat $PROD_DIR/VERSION
# Final check. Display warnings if anything is missing
FILES="VERSION
README.md
README.pdf
reference/errno.h
licenses/LWIP-LICENSE.BSD
licenses/CONCURRENTQUEUE-LICENSE.BSD
licenses/ZEROTIER-LICENSE.BSL-1.1
licenses/ROUTE_H-LICENSE.APSL
licenses/ROUTE_H-LICENSE
licenses/LWIP-LICENSE.BSD"
for f in $FILES
do
if [ ! -f "$PROD_DIR$f" ]; then
echo "Warning: $PROD_DIR$f is missing"
fi
done
}
# Generates a source-only tarball
sdist()
{
VERSION=$(git describe --abbrev=0)
TARBALL_DIR="libzt-${VERSION}"
TARBALL_NAME=libzt-${VERSION}-source.tar.gz
PROD_DIR=$(pwd)/products/
mkdir -p $PROD_DIR
#
mkdir ${TARBALL_DIR}
# primary sources
cp -rf src ${TARBALL_DIR}/src
cp -rf include ${TARBALL_DIR}/include
# important build scripts
cp Makefile ${TARBALL_DIR}
cp CMakeLists.txt ${TARBALL_DIR}
cp *.md ${TARBALL_DIR}
cp *.sh ${TARBALL_DIR}
cp *.bat ${TARBALL_DIR}
# submodules/dependencies
# lwIP
mkdir ${TARBALL_DIR}/ext
mkdir -p ${TARBALL_DIR}/ext/lwip/src
cp -rf ext/lwip/src/api ${TARBALL_DIR}/ext/lwip/src
cp -rf ext/lwip/src/core ${TARBALL_DIR}/ext/lwip/src
cp -rf ext/lwip/src/include ${TARBALL_DIR}/ext/lwip/src
cp -rf ext/lwip/src/netif ${TARBALL_DIR}/ext/lwip/src
# lwIP ports
mkdir -p ${TARBALL_DIR}/ext/lwip-contrib/ports
cp -rf ext/lwip-contrib/ports/unix ${TARBALL_DIR}/ext/lwip-contrib/ports
cp -rf ext/lwip-contrib/ports/win32 ${TARBALL_DIR}/ext/lwip-contrib/ports
# ZeroTierOne
mkdir ${TARBALL_DIR}/ext/ZeroTierOne
cp -rf ext/ZeroTierOne/*.h ${TARBALL_DIR}/ext/ZeroTierOne
cp -rf ext/ZeroTierOne/controller ${TARBALL_DIR}/ext/ZeroTierOne
cp -rf ext/ZeroTierOne/ext ${TARBALL_DIR}/ext/ZeroTierOne
cp -rf ext/ZeroTierOne/include ${TARBALL_DIR}/ext/ZeroTierOne
cp -rf ext/ZeroTierOne/node ${TARBALL_DIR}/ext/ZeroTierOne
cp -rf ext/ZeroTierOne/osdep ${TARBALL_DIR}/ext/ZeroTierOne
#
# Perform selective removal
rm -rf ${TARBALL_DIR}/ext/ZeroTierOne/ext/bin
rm -rf ${TARBALL_DIR}/ext/ZeroTierOne/ext/tap-mac
rm -rf ${TARBALL_DIR}/ext/ZeroTierOne/ext/librethinkdbxx
rm -rf ${TARBALL_DIR}/ext/ZeroTierOne/ext/installfiles
rm -rf ${TARBALL_DIR}/ext/ZeroTierOne/ext/curl-*
rm -rf ${TARBALL_DIR}/ext/ZeroTierOne/ext/http-parser
#
mkdir ${TARBALL_DIR}/ext/concurrentqueue
cp -rf ext/concurrentqueue/*.h ${TARBALL_DIR}/ext/concurrentqueue
# Licenses
package_licenses $(pwd) $TARBALL_DIR/licenses
# Tarball everything and display the results
tar -cvf ${TARBALL_NAME} ${TARBALL_DIR}
tree ${TARBALL_DIR}
rm -rf ${TARBALL_DIR}
mv ${TARBALL_NAME} ${PROD_DIR}
}
# Package both debug and release
bdist()
{
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
package_everything "debug"
package_everything "release"
}
# Generate a markdown CHANGELOG from git-log
update_changelog()
{
first_commit=$(git rev-list --max-parents=0 HEAD)
git for-each-ref --sort=-refname --format="## [%(refname:short)] - %(taggerdate:short) &(newline)*** &(newline)- %(subject) %(body)" refs/tags > CHANGELOG.md
gsed -i '''s/\&(newline)/\n/' CHANGELOG.md # replace first instance
gsed -i '''s/\&(newline)/\n/' CHANGELOG.md # replace second instance
echo -e "\n" >> CHANGELOG.md
for curr_tag in $(git tag -l --sort=-v:refname)
do
prev_tag=$(git describe --abbrev=0 ${curr_tag}^)
if [ -z "${prev_tag}" ]
then
prev_tag=${first_commit}
fi
echo "[${curr_tag}]: https://github.com/zerotier/libzt/compare/${prev_tag}..${curr_tag}" >> CHANGELOG.md
done
}
# List all functions in this script (just for convenience)
list()
{
IFS=$'\n'
for f in $(declare -F); do
echo "${f:11}"
done
}
"$@"