diff --git a/CMakeLists.txt b/CMakeLists.txt index b054c1b..45f3425 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,12 @@ endif () if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set (BUILDING_DARWIN TRUE) endif () +if (IOS_FRAMEWORK) + set (BUILDING_IOS TRUE) +endif () +if (BUILDING_DARWIN AND NOT IOS_FRAMEWORK) + set (BUILDING_MACOS TRUE) +endif () if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") set (BUILDING_LINUX TRUE) endif () @@ -180,13 +186,15 @@ if (SDK_JNI OR BUILDING_ANDROID) if (BUILDING_WIN) include_directories ("${JNI_INCLUDE_DIR}\\win32") endif () - if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") # on macOS + if (BUILDING_MACOS) include_directories ("${JNI_INCLUDE_DIR}/darwin") endif () + if (BUILDING_LINUX) + include_directories ("${JNI_INCLUDE_DIR}/linux") + endif () else () message (STATUS "JNI not found") endif () - if (JNI_FOUND) add_definitions (-DSDK_JNI=1) endif () @@ -460,8 +468,12 @@ if (SHOULD_BUILD_TESTS) #set_target_properties (selftest PROPERTIES COMPILE_FLAGS "-D__SELFTEST__") # client/server performance test - add_executable (client ${PROJ_DIR}/test/client.cpp) - target_link_libraries(client ${STATIC_LIB_NAME}) - add_executable (server ${PROJ_DIR}/test/server.cpp) - target_link_libraries(server ${STATIC_LIB_NAME}) + #add_executable (client ${PROJ_DIR}/test/client.cpp) + #target_link_libraries(client ${STATIC_LIB_NAME}) + #add_executable (server ${PROJ_DIR}/test/server.cpp) + #target_link_libraries(server ${STATIC_LIB_NAME}) + + # Simple Example + #add_executable (simple ${PROJ_DIR}/test/simple.cpp) + #target_link_libraries(simple ${STATIC_LIB_NAME}) endif () \ No newline at end of file diff --git a/Makefile b/Makefile index 9418f11..73d099a 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,10 @@ CLEAN_SCRIPT := ./ports/clean.sh PACKAGE_SCRIPT := ./ports/package.sh endif +EXECUTABLES = cmake +build_reqs := $(foreach exec,$(EXECUTABLES),\ + $(if $(shell which $(exec)),some string,$(error "No $(exec) in PATH"))) + # Pull all submodules update: git submodule update --init @@ -18,15 +22,21 @@ patch: -git -C ext/lwip-contrib apply ../lwip-contrib.patch -git -C ext/ZeroTierOne apply ../ZeroTierOne.patch -.PHONY: clean -clean: - -rm -rf ports/android/app/build - -rm -rf ports/xcode_macos +# Target-specific clean +clean_ios: -rm -rf ports/xcode_ios-arm64 - -rm -rf tmp lib bin products +clean_macos: + -rm -rf ports/xcode_macos +clean_android: + -rm -rf ports/android/app/build -find ports -name ".externalNativeBuild" -exec rm -r "{}" \; + +.PHONY: clean +clean: clean_ios clean_macos clean_android + -rm -rf tmp lib bin products -rm -f *.o *.s *.exp *.lib *.core core - find . -type f \( -name '*.o' -o -name '*.o.d' -o -name \ + find . -type f \( -name '*.dylib' -o -name '*.so' -o -name \ + '*.a' -o -name '*.o' -o -name '*.o.d' -o -name \ '*.out' -o -name '*.log' -o -name '*.dSYM' -o -name '*.class' \) -delete # Use CMake generators to build projects from CMakeLists.txt @@ -70,9 +80,15 @@ host_jar_release: host_jar: host_jar_debug host_jar_release host: host_debug host_release -# all +# Build every target available on this host all: host host_jar macos ios android + $(DIST_BUILD_SCRIPT) display -# dist +# [For distribution process only] Prepare remote builds +wrap: + $(DIST_BUILD_SCRIPT) wrap + +# [For distribution process only] Marge and package everything into a tarball dist: + $(DIST_BUILD_SCRIPT) merge $(DIST_BUILD_SCRIPT) dist diff --git a/ports/dist.sh b/ports/dist.sh index a5987c5..c1825f6 100755 --- a/ports/dist.sh +++ b/ports/dist.sh @@ -5,6 +5,30 @@ # targets as specified in CMakeLists.txt. This script is also responsible for # packaging all of the resultant builds, licenses, and documentation. +# Example workflow for producing a full release package: +# +# (1) On packaging platform, build most targets (including android and ios): +# (1a) make all +# (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 +# ├── API.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 dist + BUILD_CONCURRENCY= #"-j 2" OSNAME=$(uname | tr '[A-Z]' '[a-z]') @@ -50,6 +74,7 @@ generate_projects() fi } +# Build framework for iOS (with embedded static library) ios() { if [[ ! $OSNAME = *"darwin"* ]]; then @@ -82,6 +107,7 @@ ios() #mv $XCODE_IOS_ARMV7_PROJ_DIR/$UPPERCASE_CONFIG-iphoneos/* $OUTPUT_DIR } +# Build framework for current host (macOS only) macos() { if [[ ! $OSNAME = *"darwin"* ]]; then @@ -105,6 +131,7 @@ macos() mv $XCODE_MACOS_PROJ_DIR/$UPPERCASE_CONFIG/* $OUTPUT_DIR } +# Build Java JAR for current host (uses JNI) host_jar() { echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")" @@ -138,8 +165,17 @@ host_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/main/java/*.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() { echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")" @@ -164,6 +200,7 @@ host() cleanup } +# Build android AAR from ports/android android() { # NOTE: There's no reason this won't build on linux, it's just that @@ -194,6 +231,15 @@ android() cd - } +# 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 +} + +# Remove intermediate object files and/or libraries cleanup() { echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")" @@ -205,7 +251,58 @@ cleanup() 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 {} + - #find $(pwd)/lib -type f -name 'libztcore.a' -exec rm {} + +} + +# 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 products $ARCH_WRAP_DIR + echo "Copied products to: " $ARCH_WRAP_DIR } # Copies binaries, documentation, licenses, etc into a products @@ -240,14 +337,17 @@ package_everything() # Clean find $PROD_DIR -type f \( -name '*.DS_Store' -o -name 'thumbs.db' \) -delete # Emit a README file -# echo $'* libzt version: '${LIBZT_VERSION}$'\n* Core ZeroTier version: -#'${ZT_CORE_VERSION}$'\n* Date: '$(date)$'\n -#- ZeroTier Manual: https://www.zerotier.com/manual.shtml -#- libzt Manual: https://www.zerotier.com/manual.shtml#5 -#- libzt Repo: https://github.com/zerotier/libzt -#- Other Downloads: https://www.zerotier.com/download.shtml -#- For more assistance, visit https://my.zerotier.com and ask your -#question in our Community section' > $PROD_DIR/README.FIRST + echo 'See API.md for more information on how to use the SDK +- ZeroTier Manual: https://www.zerotier.com/manual.shtml +- libzt Manual: https://www.zerotier.com/manual.shtml#5 +- libzt Repo: https://github.com/zerotier/libzt +- ZeroTierOne Repo: https://github.com/zerotier/ZeroTierOne +- Downloads: https://www.zerotier.com/download.shtml' > $PROD_DIR/README + # 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 . @@ -257,8 +357,13 @@ package_everything() if [[ $OSNAME = *"linux"* ]]; then md5sum $PROD_FILENAME fi + # Print results for post-build inspection + echo -e "\n" + tree $PROD_DIR + cat $PROD_DIR/VERSION } +# Package both debug and release dist() { echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"