Add iOS Framework Bundle build

The new ios/configure script performs a separate ../configure for each of
the following iOS targets:

    iPhoneOS        on armv7
    iPhoneOS        on arm64
    iPhoneSimulator on i386
    iPhoneSimulator on x86_64

The script then creates ios/Makefile that builds a static iOS Framework
Bundle suitable for inclusion in an Xcode iOS project.

Add the --xcode-sdk=SDK option to configure.ac, to support cross
compiling using Apple Xcode.  It prefixes all compile/link toolchain
commands with the "xcrun --sdk SDK" command, ie, CC, AS, LD, AR, RANLIB,
etc.

Re-structure headerfiles.mk to separate "public" from "private" headers,
because the Framework module only exposes the public ones.  Moves the
SQLITE3_AMALGAMATION definition from Makefile.in into headerfiles.mk.

Update INSTALL.md and add a technical document for Apple iOS.

This enables development of Serval DNA within the context of an Xcode
iOS project using the standard edit-make-test cycle: after modifying a
Serval DNA source file, "cd ios; make" will recompile the changed file
for all the target architectures and update the Framework Bundle.
Rebuilding the Xcode project will then incorporate the changes, which
can be tested immediately.
This commit is contained in:
Andrew Bettison 2016-10-25 12:52:21 +10:30
parent c418385f56
commit ca8e846264
12 changed files with 1066 additions and 124 deletions

3
.gitignore vendored
View File

@ -43,3 +43,6 @@ test.*.log
/swift-client-api/Makefile
/swift-client-api/build/
/swift-client-api/swift-client-util
/ios/Makefile
/ios/build/
/ios/frameworks/

View File

@ -3,9 +3,10 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
SQLITE3_AMALGAMATION = sqlite-amalgamation-3140200
include $(LOCAL_PATH)/headerfiles.mk # for SQLITE3_AMALGAMATION
include $(LOCAL_PATH)/sourcefiles.mk
SERVALD_SRC_FILES = \
$(SQLITE3_SOURCES) \
$(SERVAL_CLIENT_SOURCES) \

View File

@ -10,17 +10,24 @@ These instructions will build [Serval DNA][] successfully for the following plat
* Debian Linux, ix86 and x86\_64, kernel versions 2.6 to 4.12, using [gcc
4.4][] and later, [gcc 5][] and [gcc 6][]
* Mac OS-X x86\_64, releases 10.7 “Lion” to 10.11 “El Capitan”, using
[Xcode][] versions 3.2 to 8, and GNU tools available from [homebrew][]
[Xcode][] versions 3.2 to 8, supplemented by [homebrew][]
* Oracle SunOs 5.10 (Solaris), Sparc, using [gcc 4.4][] and GNU tools
installed
[Serval DNA][] also runs on the following platforms, to which these build
instructions do not apply:
[Serval DNA][] also builds and runs on the following platforms, for which there
are separate build instructions:
* [Android 2.2 “Froyo”][], Arm, Linux kernels 2.6.x and 3.x, using [gcc 4.4][]
supplied as part of [Android NDK][] Revision 7b
* [OpenWRT][] (as used by the [Serval Mesh Extender][], the [Mesh Potato][],
and the [Commotion Wireless][] project)
* [Serval Mesh app for Android][batphone] includes instructions for building
Serval DNA as part of an app for [Android 2.2 “Froyo”][] and later versions;
Linux kernels 2.6.x and 3.x, Arm architecture, using [gcc 4.4][] supplied as
part of [Android NDK][] Revision 7b
* [Serval DNA on iOS][iOS] gives instructions for [Apple iOS][] using
[Xcode][] versions 8, supplemented by [homebrew][]
* [Serval DNA on OpenWRT][OpenWRT] gives instructions for the embedded router
Linux distribution, as used by the [Serval Mesh Extender][], the [Mesh
Potato][], and the [Commotion Wireless][] project
Download
--------
@ -53,7 +60,7 @@ Mandatory dependencies:
Optional:
* Java compiler and SDK 1.6.0 or later
* [Java][] compiler and SDK 1.6.0 or later
* [Swift][] 3 or 4 compiler
* ALSA sound library and headers (present on Linux, not on Android)
@ -64,7 +71,7 @@ Test dependencies:
* jq 1.3 or later
* curl
**Bash** and **curl** are both provided by the [XCode][] package for Mac OS X.
**Bash** and **curl** are both provided by the [Xcode][] package for Mac OS X.
**GNU grep**, **GNU sed**, **GNU awk** and **jq** can all be installed on Mac
OS-X using the [homebrew][] package manager. The [Notes for Developers][] give
more details.
@ -214,11 +221,13 @@ The [native build](#native-build) process produces the following artifacts:
functions. An executable (such as *servald*) can be built with any desired
subset of Serval functions by linking in only the required parts of this
library using the *features* mechanism described in [feature.h](./feature.h).
The Serval DNA [Swift][] API, which is used by the Serval Chat app for iOS,
uses this static library.
* **libservaldaemon.so** is a dynamic library containing the complete executable
code of the Serval DNA daemon, including [JNI][] entry points, SQLite and
libsodium cryptographic functions. The *servaldwrap* executable and the
Serval DNA Java API, which is used by [batphone][], both use this dynamic
Serval DNA [Java][] API, which is used by [batphone][], both use this dynamic
library.
* **directory_service** is the executable for the [Serval Infrastructure][]
@ -339,6 +348,8 @@ This document is available under the [Creative Commons Attribution 4.0 Internati
[Swift Client API module]: ./doc/Development.md#swift-client-api
[OpenWRT]: ./doc/OpenWRT.md
[Serval Infrastructure]: ./doc/Serval-Infrastructure.md
[iOS]: ./doc/Apple-iOS.md
[Apple iOS]: https://en.wikipedia.org/wiki/IOS
[Serval Mesh Extender]: http://developer.servalproject.org/dokuwiki/doku.php?id=content:meshextender:
[contact the Serval Project]: http://developer.servalproject.org/dokuwiki/doku.php?id=content:contact
[RFD900]: http://rfdesign.com.au/index.php/rfd900
@ -348,6 +359,7 @@ This document is available under the [Creative Commons Attribution 4.0 Internati
[MDP API]: ./doc/Mesh-Datagram-Protocol.md#mdp-api
[CLI API]: ./doc/CLI-API.md
[JNI]: http://en.wikipedia.org/wiki/Java_Native_Interface
[Java]: https://en.wikipedia.org/wiki/Java_(programming_language)
[Swift]: https://en.wikipedia.org/wiki/Swift_(programming_language)
[dlopen(3)]: http://man7.org/linux/man-pages/man3/dlopen.3.html
[Bash]: http://en.wikipedia.org/wiki/Bash_(Unix_shell)
@ -355,6 +367,6 @@ This document is available under the [Creative Commons Attribution 4.0 Internati
[Git]: http://git-scm.com/
[Subversion]: http://subversion.apache.org/
[Bourne shell]: http://en.wikipedia.org/wiki/Bourne_shell
[XCode]: https://developer.apple.com/xcode/
[Xcode]: https://developer.apple.com/xcode/
[homebrew]: http://brew.sh/
[CC BY 4.0]: ./LICENSE-DOCUMENTATION.md

View File

@ -31,10 +31,8 @@ INSTALL= install
INSTALL_PROGRAM= $(INSTALL)
INSTALL_DATA= $(INSTALL) -m 644
SQLITE3_AMALGAMATION = sqlite-amalgamation-3140200
include $(srcdir)/sourcefiles.mk
include $(srcdir)/headerfiles.mk
include $(srcdir)/headerfiles.mk # sets SQLITE3_AMALGAMATION
include $(srcdir)/sourcefiles.mk # depends on SQLITE3_AMALGAMATION
LIBSODIUM_SUBDIR = libsodium/
LIBSODIUM_DEV = libsodium-dev
@ -82,7 +80,7 @@ MONITOR_CLIENT_OBJS = \
SIMULATOR_OBJS = \
$(addprefix $(OBJSDIR_TOOLS)/, $(SIMULATOR_SOURCES:.c=.o))
PREFIXED_HEADERS = $(addprefix $(srcdir)/, $(HDRS))
PREFIXED_HEADERS = $(addprefix $(srcdir)/, $(ALL_HDRS))
PREFIXED_SOURCES = $(addprefix $(srcdir)/, $(ALL_SOURCES))
LDFLAGS=@LDFLAGS@ @LIBS@
@ -97,7 +95,6 @@ CFLAGS+=-DSQLITE_THREADSAFE=0 \
-DSQLITE_OMIT_VIRTUALTABLE \
-DSQLITE_OMIT_AUTHORIZATION
CFLAGS+=-fPIC -DSERVAL_ENABLE_DEBUG=1 -Wall -Werror -Wextra -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2
CFLAGS+=@CFLAGS_TARGET@
# Solaris magic
CFLAGS+=-DSHA2_USE_INTTYPES_H -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D__EXTENSIONS__=1
@ -145,7 +142,6 @@ uninstall:
$(RM) $(DESTDIR)$(sbindir)/servald
clean:
cd $(LIBSODIUM_SUBDIR) && $(MAKE) clean
$(RM) -r $(LIBSODIUM_DEV) \
$(OBJSDIRS:%=%/*) \
servald \
@ -154,6 +150,11 @@ clean:
libmonitorclient.so libmonitorclient.a \
tfw_createfile directory_service fakeradio simulator serval-tests \
tags
cd $(LIBSODIUM_SUBDIR) && $(MAKE) clean
distclean: clean
$(RM) config.h config.status config.log testconfig.sh
cd $(LIBSODIUM_SUBDIR) && $(MAKE) distclean
# Only provide Java targets if the Java compiler is available.
ifneq ($(JAVAC),)
@ -214,7 +215,9 @@ endif # $(SWIFTC)
CFLAGS+= -isystem $(LIBSODIUM_DEV)/include
$(LIBSODIUM_HEADERS) $(LIBSODIUM_A): $(LIBSODIUM_DEV)/.installed
.PHONY: libsodium-dev
libsodium-dev $(LIBSODIUM_HEADERS) $(LIBSODIUM_A): $(LIBSODIUM_DEV)/.installed
# The libsodium package uses libtool, so by default its static libraries get
# compiled without the -fPIC option. This prevents the libsodium static
@ -229,8 +232,7 @@ $(LIBSODIUM_DEV)/.installed:
@$(RM) $@
@touch $@.in-progress
@cd $(LIBSODIUM_SUBDIR) && $(MAKE) \
CFLAGS+="-prefer-pic @CFLAGS_TARGET@" \
CCASFLAGS+="@CFLAGS_TARGET@" \
CFLAGS+="-prefer-pic" \
prefix=$(abspath $(LIBSODIUM_DEV)) \
install
@mv -f $@.in-progress $@

View File

@ -55,18 +55,20 @@ What is in this repository?
This repository contains:
* the [GNU C][] source code for the **servald** executable,
* the [Java][] source code for the Serval API,
* some [technical documentation](./doc/),
* the [GNU C][] source code for the **servald** executable
* the [Java][] source code for the Serval API
* the [Swift][] source code for the Serval API
* [technical documentation](./doc/)
* a [test framework](./testframework.sh) and [test scripts](./tests/) written
in [Bash][],
in [Bash][]
* various support files for installation and configuration on various
platforms.
platforms
The **servald** executable is a multi-purpose program that can be invoked
directly from the command line, run as a daemon process, or invoked via [JNI][]
from within a Java program. The **servald** executable is really many commands
built into one; the command-line arguments select which *command* to run. Some
from within a [Java][] program or via the [Swift module][] from within a
[Swift][] program. The **servald** executable is really many commands built
into one; the command-line arguments select which *command* to run. Some
commands are stand-alone utilities, some start and stop the servald daemon
process, some communicate with the servald daemon as an MDP client, and others
via a two-way [pipe][] called the *monitor interface*.
@ -182,6 +184,7 @@ This document is available under the [Creative Commons Attribution 4.0 Internati
[issue #28]: https://github.com/servalproject/serval-dna/issues/28
[GNU C]: http://gcc.gnu.org/
[Java]: https://en.wikipedia.org/wiki/Java_(programming_language)
[Swift]: https://en.wikipedia.org/wiki/Swift_(programming_language)
[daemon]: http://en.wikipedia.org/wiki/Daemon_(computing)
[free software]: http://www.gnu.org/philosophy/free-sw.html
[contributors]: /servalproject/serval-dna/blob/development/CONTRIBUTORS.md

View File

@ -4,10 +4,17 @@ AC_INIT(servald, 0.9)
AC_CONFIG_SRCDIR([serval_types.h])
AC_CONFIG_MACRO_DIR([m4])
dnl Specify cross compilation using Xcode.
dnl Sets $enable_xcode_sdk to ARG if the --enable-xcode-sdk=ARG option is given.
dnl The --host flag must specify a compilation target that 'apple' as the vendor.
dnl See below for more details.
AC_ARG_ENABLE([xcode-sdk], [cross compile using Xcode])
dnl Specify toolchain programs.
AC_ARG_VAR([AR], [Library archiver])
AC_ARG_VAR([RANLIB], [Archive indexer])
dnl Specify Swift compiler
dnl Specify the Swift compiler
AC_ARG_VAR([SWIFTC], [Swift compiler])
AC_ARG_VAR([SWIFTCFLAGS], [Swift compiler flags])
@ -48,14 +55,91 @@ dnl Set $host, $host_cpu, $host_vendor, $host_os, either from --host option
dnl (cross compilation), or falling back to $build (native compilation).
AC_CANONICAL_HOST
dnl $CFLAGS_TARGET is used in the Serval DNA Makefile and also passed in CFLAGS to all
dnl sub-Makefiles, such as libsodium.
CFLAGS_TARGET=''
dnl On Apple platforms, the development toolchain is provided by Xcode, which has a
dnl set of "cross compilation" SDKs for the different Apple operating systems such as
dnl Mac OSX, iPhoneOS (aka iOS), WatchOS, etc. In addition, each Mac OSX development
dnl system provides its own "native" SDK (libraries + headers) which is not one of
dnl Xcode's listed SDKs and may be completely different from Xcode's MacOSX SDK.
dnl
dnl To enable cross-compilation on Apple systems, pass the following options to the
dnl configure script:
dnl
dnl ./configure --host=<cpu>-apple-darwin --enable-xcode-sdk=<sdk>
dnl
dnl where <sdk> is case insensitive and may or may not contain a version number
dnl suffix, eg:
dnl ./configure --host=armv7-xcode-darwin --enable-xcode-sdk=iPhoneOS
dnl ./configure --host=x86_64-xcode-darwin --enable-xcode-sdk=macosx10.12
dnl
dnl Note that if no --host option is given, AC_CANONICAL_HOST will set the 'cpu' part
dnl of $host to the native build CPU.
dnl
dnl Note that passing --enable-xcode-sdk=macosx without a --host option will result
dnl in a build for Mac OSX that will only execute natively if the MacOSX SDK in Xcode
dnl exactly matches the version of OSX that is running natively. Otherwise, the
dnl executables will probably fail to dynamically link with the native libraries at
dnl run time, with errors like:
dnl dyld: Symbol not found: _OBJC_CLASS_$_OS_dispatch_semaphore
dnl
dnl The configure script invokes the xcodebuild utility to resolve the 'os' part
dnl to the full name of the SDK supported by Xcode, with version suffix, and sets
dnl $host to <cpu>-apple-<sdk><sdkversion>. If the SDK named in --host is not
dnl available in Xcode, then the configure script fails with an error.
dnl
xcrun=''
xcode_sdk=''
arch_flag=''
min_version_flag=''
AS_IF([test "x$enable_xcode_sdk" != x], [ dnl
AS_IF([test "x$host_vendor" != xapple], [ dnl
AC_MSG_ERROR(["--with-xcode-sdk is incompatible with --host $host; vendor must be 'apple'"])
])
dnl Check for C99 compiler, preprocessor and assembler.
dnl Query Xcode for an SDK that matches the one specified by the --enable-xcode-sdk flag.
XCODE_SDK_lower=`echo "$enable_xcode_sdk" | tr A-Z a-z`
AC_MSG_CHECKING([Xcode SDK for cross compilation])
for sdk in [`xcodebuild -showsdks | sed -n -e 's/^.*-sdk \([^ ][^ ]*\)$/\1/p'`]; do
AS_CASE([$sdk],
[["$XCODE_SDK_lower"|"$XCODE_SDK_lower"[0-9]*]], [ dnl
xcode_sdk="$sdk"
break
]
)
done
AC_MSG_RESULT([$xcode_sdk])
AS_IF([test "x$xcode_sdk" = x], [AC_MSG_ERROR([Unsupported Xcode SDK: $enable_xcode_sdk])])
xcode_sdk_os=[`echo "$xcode_sdk" | sed -n -e 's/^\(.*[^0-9]\)[0-9][0-9]*\.[0-9][0-9]*$/\1/p'`]
xcode_sdk_version=[`echo "$xcode_sdk" | sed -n -e 's/^.*[^0-9]\([0-9][0-9]*\.[0-9][0-9]*\)$/\1/p'`]
xcrun="xcrun --sdk $xcode_sdk "
CC="${xcrun}clang"
CPP="$CC -E"
LD="${xcrun}ld"
AR="${xcrun}ar"
RANLIB="${xcrun}ranlib"
dnl Map the CPU name from the one used by config.sub to the one used by Xcode.
AS_CASE([$host_cpu], [aarch64], [host_arch=arm64], [host_arch=$host_cpu])
arch_flag="-arch $host_arch"
cross_compiling=yes
dnl If building for Mac OS-X or iPhoneOS, then make sure all C source files are
dnl compiled with a consistent target, to avoid warnings about inconsistent
dnl versions at link time, such as:
dnl
dnl ld: warning: object file (libservaldaemon.a(libsodium_la-crypto_sign.o)) was
dnl built for newer OSX version (10.12) than being linked (10.10)
dnl
AC_MSG_CHECKING([Clang Xcode target options])
AS_CASE([$xcode_sdk_os],
[[macosx]], [min_version_flag="-mmacosx-version-min=$xcode_sdk_version"],
[[iphoneos]], [min_version_flag="-miphoneos-version-min=$xcode_sdk_version"]
[[iphonesimulator]], [min_version_flag="-mios-simulator-version-min=$xcode_sdk_version"]
)
AC_MSG_RESULT([${min_version_flag:-(none)}])
], [ dnl
dnl Check for C99 compiler and preprocessor.
AC_PROG_CC_C99
AC_PROG_CPP
AM_PROG_AS
dnl Check for library creation tools.
AC_CHECK_TOOL([AR], [ar], [:])
@ -65,6 +149,10 @@ AS_IF([test "x$RANLIB" = x:], [AC_MSG_ERROR([Archive indexer not found: ranlib])
dnl C preprocessor option to support cross-compiling.
AX_APPEND_COMPILE_FLAGS(["-arch $host_cpu"], [CPPFLAGS])
])
dnl Check for C assembler.
AM_PROG_AS
dnl Check for a Swift 3 or 4 compiler; set SWIFTC if found.
AC_PROG_SWIFTC
@ -77,8 +165,14 @@ AS_IF([test "x$SWIFTC" != x], [ dnl
dnl Swift SDK names differ a little from Xcode names: iPhoneOS and iPhoneSimulator
dnl are both represented as ios.
swiftc_target=`$SWIFTC $SWIFTCFLAGS -version 2>&1 | sed -n -e 's/^Target: *//p'`
AS_IF([test "x$swiftc_target" = x], [AC_MSG_ERROR([Swift compiler does not report its target: $SWIFTC $SWIFTCFLAGS -version])])
swift_target_option=''
AS_CASE([$xcode_sdk_os],
[''], [],
[iphoneos|iphonesimulator], [swift_target_option="-target $host_arch-apple-ios$xcode_sdk_version"],
[*], [swift_target_option="-target $host_arch-apple-$xcode_sdk"]
)
swiftc_target=`$SWIFTC $swift_target_option $SWIFTCFLAGS -version 2>&1 | sed -n -e 's/^Target: *//p'`
AS_IF([test "x$swiftc_target" = x], [AC_MSG_ERROR([Swift compiler does not report its target: $SWIFTC $swift_target_option $SWIFTCFLAGS -version])])
dnl In a build for Mac OSX (native or cross), ensure that the Swift target is high
dnl enough to create a Swift package, which were not supported before Mac OSX 10.10.
@ -87,7 +181,7 @@ AS_IF([test "x$SWIFTC" != x], [ dnl
[[*-apple-macosx*]], [ dnl
swiftc_target_version=[`echo "$swiftc_target" | sed -n -e 's/^.*-macosx//p'`]
AS_VERSION_COMPARE([$swiftc_target_version], [$macosx_min_version], [ dnl
CFLAGS_TARGET="-mmacosx-version-min=$macosx_min_version"
min_version_flag="-mmacosx-version-min=$macosx_min_version"
swiftc_target=[`echo "$swiftc_target" | sed -n -e 's/-macosx.*$//p'`-macosx$macosx_min_version]
])
]
@ -106,8 +200,10 @@ AS_IF([test "x$SWIFTC" != x], [ dnl
])
])
dnl Add the -target option to SWIFTCFLAGS (if the user has already supplied a -target option in
dnl SWIFTCFLAGS, then this prepended one will take precedence).
dnl Set up the Swift compiler for cross compilation; invoke it using the Xcode xcrun wrapper
dnl utility and add the -target option to SWIFTCFLAGS (if the user has already supplied a
dnl -target option in SWIFTCFLAGS, then this prepended one will take precedence).
SWIFTC="${xcrun}$SWIFTC"
SWIFTCFLAGS="-target $swiftc_target $SWIFTCFLAGS"
])
@ -116,21 +212,22 @@ AS_IF([test "x$SWIFTC" != x && test "x$SWIFT_BUILD" = x], [
AC_PROG_SWIFT_PACKAGE_MANAGER
])
dnl The C compilation flags used in all Serval-DNA Makefiles.
CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
CFLAGS_TARGET="$CFLAGS_TARGET"
CFLAGS="$CFLAGS_TARGET $CFLAGS"
export CPPFLAGS
export CFLAGS
AC_SUBST([WRAPPER])
AC_SUBST([CFLAGS_TARGET])
dnl Swift definitions that get expanded in Makefiles.
AC_SUBST([SWIFTC])
AC_SUBST([SWIFTCFLAGS])
AC_SUBST([SWIFT_VERSION])
AC_SUBST([SWIFT_BUILD])
dnl The C compilation and linking flags used in all Makefiles and all the following
dnl configuration tests.
CPPFLAGS="$arch_flag $CPPFLAGS -D_GNU_SOURCE"
CFLAGS="$arch_flag $min_version_flag $CFLAGS"
LDFLAGS="$arch_flag $LDFLAGS"
dnl Extra toolchain definitions that get expanded in Makefiles (CC, CCAS, etc. are already
dnl expanded by default).
AC_SUBST([AR])
dnl Various GCC function and variable attributes
AX_GCC_FUNC_ATTRIBUTE(aligned)
AX_GCC_FUNC_ATTRIBUTE(alloc_size)
@ -350,12 +447,19 @@ AC_CONFIG_HEADERS([config.h])
AC_SUBST([CONFIG_H], [config.h])
dnl The entire libsodium source is in a subdirectory, and has its own configure
dnl script.
dnl script. Invoke the configure script with the compilers and their flags.
export CPP
export CPPFLAGS
export CC
export CCAS
export CFLAGS
export LD
export LDFLAGS
export AR
export RANLIB
AC_CONFIG_SUBDIRS([libsodium])
ac_configure_args="$ac_configure_args CC='$CC' CCAS='$CCAS' LD='$LD'"
dnl Generate files.
AC_OUTPUT([
Makefile
testconfig.sh

299
doc/Apple-iOS.md Normal file
View File

@ -0,0 +1,299 @@
Serval DNA on iOS
=================
[Serval Project][], November 2017
These instructions describe how to embed [Serval DNA][] into an [Apple iOS][]
app.
This work was funded by a grant from the [NLnet Foundation][].
Introduction
------------
Please see the [build instructions][build] and [Notes for Developers][develop]
for an introduction to the [Serval DNA][] native build and development
environment. (To summarise: the [Serval DNA][] build and development toolchain
is completely oriented around the [Bash shell][] command-line on [Unix][]
platforms such as [GNU][]/[Linux][] and [Darwin][], and uses [GNU autoconf][]
achieve portability between different platforms.)
The only platform available for developing iOS apps is the [Xcode][] integrated
development environment from Apple. Xcode is only available on Mac OS-X, so
[Serval DNA][]'s iOS development toolchain is based entirely on the
[Darwin][]/[Xcode][] environment and is not complicated by portability issues.
Xcode builds iOS apps by [cross compiling][] to the selected target.
The [ios](../ios) subdirectory contains scripts for building Serval DNA into a
multi-target [Framework Bundle][] that can be imported into any Xcode project.
The framework provides access to all public C functions in the Serval DNA
source code, and to all entry points of the Serval DNA Swift API.
Supported targets
-----------------
The supported operating systems are:
* [iOS 10][] or later (iPhoneOS and iPhoneSimulator)
running on any of the following devices:
* [iPhone 5][] and [iPhone 5C][] (ARMv7s 32-bit dual-core CPU)
* [iPhone 5S][] (ARMv8 64-bit dual-core CPU)
* [iPhone 6 and 6 Plus][] (ARMv8 64-bit dual-core CPU)
* [iPhone 6S and 6S Plus][] (ARMv8-A 64-bit dual-core CPU)
* [iPhone SE][] (ARMv8-A 64-bit dual-core CPU)
* [iPhone 7 and 7 Plus][] (ARM 64-bit quad-core CPU)
* [iPhone 8 and 8 Plus][] (ARM 64-bit hexa-core CPU)
* [iPhone X][] (ARM 64-bit hexa-core CPU)
* iPhone Simulator (Intel 32-bit CPU)
* iPhone Simulator (Intel 64-bit CPU)
In Apple terminology, a CPU architecture is called a *slice*.
In this document, *target* means an operating system and a slice, so, based on
the above list, the supported targets are:
* iPhoneOS ARMv7s (32-bit)
* iPhoneOS ARMv8 (64-bit)
* iPhoneSimulator i386 (32-bit)
* iPhoneSimulator x86\_64 (64-bit)
Dependencies
------------
Building [Serval DNA][] for iOS requires [Xcode version 8][Xcode 8] or later,
because the [Swift 3][] programming language was first introduced in [Xcode
version 8][Xcode 8], and Serval DNA exposes its API in iOS using Swift 3.
[Xcode 8][] provides the following command-line utilities:
* [Bash shell][] version 3.2
* [GNU make][] version 3.81
* [Clang][] compiler for [C11][] based on LLVM version 8
* [Swift 3][] compiler based on LLVM version 8
* standard BSD utilities such as [sed][], [tr][], and [mkdir][]
These are adequate for cross-compiling for iOS as described below, but may not
be enough for native development; see [Notes for Developers][develop].
Build the Serval DNA Framework Bundle
-------------------------------------
In a [working copy of the Serval DNA source code](../INSTALL.md#download), use
the following commands:
$ cd serval-dna
$ autoreconf -f -i -I m4
$ cd ios
$ ./configure
$ make
$
See below for a description of the [built artifacts](#built-artifacts).
Once the `ios/configure` script has been run once, it only needs to be run
again if the main configure script [configure.ac](../configure.ac) has been
changed (and `autoreconf` has been re-run) or if [Makefile.in](../Makefile.in)
or any other `.in` files have been changed.
After any change to Serval DNA source or header file, to re-compile and re-link
the framework bundle, simply run `make` again:
$ cd ios
$ make
$
Built artifacts
---------------
The `make` command above produces the following files:
* `ios/frameworks/ServalDNA.framework/` contains a static iOS [Framework
Bundle][] that consists of the following pieces:
* `Resources/` (symbolic link) contains all “resource” files that accompany
the shared library:
* `Info.plist` is the bundle's property list in XML format; this allows
Xcode to recognise the bundle and import it correctly
* `ServalDNA` (symbolic link) is a multi-slice static library for all
[supported targets](#supported-targets)
* `Headers/` (symbolic link) contains all the Serval DNA C header files, and
subdirectories for all [supported targets](#supported-targets):
* `iphoneos-armv7` contains the C header files specific to the iPhone
ARMv7 target
* `iphoneos-arm64` contains the C header files for the iPhone ARMv8 target
* `iphonesimulator-i386` contains the C header files for the 32-bit
simulator target
* `iphonesimulator-x86_64` contains the C header files for the 64-bit
simulator target
* `module.modulemap` (symbolic link) is a file that defines the [Clang module][]
for the bundle; this is what gives Swift code access to the Serval DNA
headers and entry points
* `ios/frameworks/ServalDNA.xcconfig` is an Xcode configuration file that
contains all the settings needed to use the `ServalDNA.framework` bundle in
an Xcode project
Import ServalDNA.framework into Xcode
-------------------------------------
To use the Serval DNA iOS [Framework Bundle][] in an Xcode iOS project:
1. Open the Xcode application
2. Create a new iOS project or open an existing one, called “Sample App” for
example
1. Add the bundle's config file to the Xcode project:
* menu **File** → **Add Files to “Sample App”...**
* a file chooser dialog window pops up
* navigate to the Xcode config file, eg: *Home***src****serval-dna**
**ios****frameworks** → **ServalDNA.xcconfig**
* press the **Add** button at the lower right of the dialog window
* the file chooser dialog window closes
* the **ServalDNA.xcconfig file** should now appear in the “Project
navigator” pane on the left side of the Xcode main window
2. Include the bundle's config file in the project's settings:
* in the “Project navigator” pane, click on the topmost row, which should be
labelled with the project name, eg: **Sample App**
* in the second row of the centre pane, click on **Info**
* in the left column of the centre pane, click on the row immediately
beneath the **PROJECT** line, which should be labelled with the project
name, eg: **Sample App**
* in the main area of the centre pane, under the **Configurations** heading,
for each of the “Debug” and “Release” sub-headings:
* click on the triangle to expand the sub-heading
* on the line immediately beneath the sub-heading, which should be
labelled with the project name, eg: **Sample App**, click on the widget
in the “Based on Configuration File” column
* a selection box should pop up, containing the options “None” and “ServalDNA”
* choose **ServalDNA**
3. Write some simple code that invokes a Serval DNA function:
* TODO
4. Run the simulator to test that the bundle links correctly:
* menu **Product** → **Run**
* the message “Build succeeded” should pop up, and the Simulator window
should appear shortly afterwards
How it works
------------
The `ios/configure` script takes advantage of [GNU autoconf][]'s support for
out-of-tree builds: if an autoconf-generated `configure` script (such as the
one used by Serval DNA's [build][]) is invoked from within a different working
directory than the source directory that contains the `configure` script
itself, then it places all resulting configuration files such as `config.h`,
`config.state` and `Makefile` under the working directory, not the source
directory. Invoking the `make` command in that working directory will then
place all built artifacts under the same working directory, without altering
the source directory; ie, the build is completely contained within the working
directory. Because of this, many differently-configured builds can be
preformed from a single copy of the source code, without interfering with each
other.
The `ios/configure` script creates one working directory per target, under the
`ios/build` directory, and invokes the main Serval DNA `configure` script in
each target subdirectory, with appropriate options to produce the respective
cross-compilation, eg:
cd build/armv7-iphoneos
../../../configure --host="armv7-apple-darwin" --enable-xcode-sdk=iphoneos
cd -
cd build/arm64-iphoneos
../../../configure --host="aarch64-apple-darwin" --enable-xcode-sdk=iphoneos
cd -
cd build/i386-iphonesimulator
../../../configure --host="i386-apple-darwin" --enable-xcode-sdk=iphonesimulator
cd -
cd build/x86_64-iphonesimulator
../../../configure --host="x86_64-apple-darwin" --enable-xcode-sdk=iphonesimulator
cd -
The `ios/configure` script then creates `ios/Makefile`, which, when invoked
by the `make` command:
* for each target, runs `cd build/TARGET; make libservaldaemon.a`
* creates the `ios/frameworks/ServalDNA.framework` destination directory
* combines the all the built static libraries into a single, multi-slice
static library in the framework directory using the [lipo(1)][] utility
* copies all the Serval DNA C header files into the framework's `Headers`
subdirectory
* for each target, copies all the target-specific C header files (config.h and
libsodium headers) into the framework's `Headers/TARGET` subdirectory
* creates the framework's `Resources/Info.plist` file
* creates the framework's `modules.modulemap` file
* creates all framework's internal symbolic links
* creates the `ServalDNA.xcconfig` file to accompany the framework
If any Serval DNA source (or header) file is subsequently modified, it is only
necessary to re-run the `make` command to recompile for all the targets and
update the framework. Just like in normal development, only the affected
object files will be re-compiled as determined by each target's Makefile
dependency rules. This makes it possible to carry out development of the
Serval DNA source code itself and test it using an Xcode iOS project, with a
relatively quick turn-around.
-----
**Copyright 2017 Flinders University**
![CC-BY-4.0](./cc-by-4.0.png)
This document is available under the [Creative Commons Attribution 4.0 International licence][CC BY 4.0].
[Serval Project]: http://www.servalproject.org/
[Serval DNA]: ../README.md
[Apple iOS]: https://en.wikipedia.org/wiki/IOS
[NLnet Foundation]: https://nlnet.nl/
[Bash shell]: http://en.wikipedia.org/wiki/Bash_(Unix_shell)
[Unix]: https://en.wikipedia.org/wiki/Unix
[GNU]: https://en.wikipedia.org/wiki/GNU
[Linux]: https://en.wikipedia.org/wiki/Linux
[Darwin]: https://en.wikipedia.org/wiki/Darwin_(operating_system)
[GNU autoconf]: http://www.gnu.org/software/autoconf/autoconf.html
[GNU make]: https://www.gnu.org/software/make/
[Clang]: https://en.wikipedia.org/wiki/Clang
[build]: ../INSTALL.md
[develop]: ./Development.md
[Xcode]: https://en.wikipedia.org/wiki/Xcode
[Xcode 8]: https://developer.apple.com/swift/blog/?id=36
[C11]: https://en.wikipedia.org/wiki/C11_(C_standard_revision)
[Swift 3]: https://swift.org/blog/swift-3-0-released/
[cross compiling]: https://en.wikipedia.org/wiki/Cross_compiler
[iOS 10]: https://en.wikipedia.org/wiki/IOS_10
[iPhone 5]: https://en.wikipedia.org/wiki/IPhone_5
[iPhone 5C]: https://en.wikipedia.org/wiki/IPhone_5C
[iPhone 5S]: https://en.wikipedia.org/wiki/IPhone_5S
[iPhone 6 and 6 Plus]: https://en.wikipedia.org/wiki/IPhone_6
[iPhone 6S and 6S Plus]: https://en.wikipedia.org/wiki/IPhone_6S
[iPhone SE]: https://en.wikipedia.org/wiki/IPhone_SE
[iPhone 7 and 7 Plus]: https://en.wikipedia.org/wiki/IPhone_7
[iPhone 8 and 8 Plus]: https://en.wikipedia.org/wiki/IPhone_8
[iPhone X]: https://en.wikipedia.org/wiki/IPhone_X
[sed]: https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/sed.1.html
[tr]: https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/tr.1.html
[mkdir]: https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/mkdir.1.html
[Framework Bundle]: https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPFrameworks/Frameworks.html
[Clang module]: https://clang.llvm.org/docs/Modules.html
[lipo(1)]: http://www.manpages.info/macosx/lipo.1.html

View File

@ -2,27 +2,40 @@ Notes for Serval DNA Developers
===============================
[Serval Project][], December 2017
This document is intended for all developers of [Serval DNA][], and also for
non-developers who are experiencing errors in the [build][] process.
Introduction
------------
This document is intended for all developers of [Serval DNA][], and also for
non-developers who are experiencing errors in the [build][] process.
The [Serval DNA][] development and [build][] toolchain is completely oriented
around the [Bash shell][] command-line on [Unix][] platforms such as
[GNU][]/[Linux][] and [Darwin][], and uses [GNU autoconf][] achieve portability
between different platforms.
To date, the [Serval Project][] has not dedicated effort to integrating with
GUI development environments such as [Android Studio][] or supporting non-Unix
platforms such as [Microsoft Windows][], because the ongoing effort of
maintaining compatibility with so many platforms would detract from the
development of core features. Anybody is welcome to contribute support for
more platforms, but at this stage, the Serval Project cannot commit to
maintaining any contributed integrations.
Autotools
---------
The [configure.ac][] file is an [autoconf][] script that contains instructions
for adapting the build of Serval DNA to different platforms and CPU
architectures. This script makes use of many [GNU M4][] macros, each of which
tests an aspect of the build environment, such as the make and version of the C
compiler (eg, [GCC][], [Clang][]), the availability of headers, functions and
system calls in the standard library, and so forth.
The [configure.ac][] file is a [GNU autoconf][] script that contains
instructions for adapting the build of Serval DNA to different platforms and
CPU architectures. This script makes use of many [GNU M4][] macros, each of
which tests an aspect of the build environment, such as the make and version of
the C compiler (eg, [GCC][], [Clang][]), the availability of headers, functions
and system calls in the standard library, and so forth.
Most of these M4 macros are standard, either supplied with [autoconf][] or from
the [autoconf macro archive][]. Some macros are specific to Serval DNA, either
to improve on a standard macro or perform a test for which no standard macro
exists. These extra macros are locally defined in files within the [m4](../m4)
sub-directory.
Most of these M4 macros are standard, either supplied with [GNU autoconf][] or
from the [autoconf macro archive][]. Some macros are specific to Serval DNA,
either to improve on a standard macro or perform a test for which no standard
macro exists. These extra macros are locally defined in files within the
[m4](../m4) sub-directory.
The [autoreconf][] command used in the [build][] instructions generates an
`aclocal.m4` file that includes all the necessary files from the [m4](../m4)
@ -153,7 +166,7 @@ dependencies before building on [Debian][] and [Ubuntu][] systems:
Processing triggers for man-db (2.7.5-1) ...
$
Apple Mac OS X
Apple Mac OS-X
--------------
### Test utilities
@ -350,7 +363,12 @@ Available under the [Creative Commons Attribution 4.0 International licence][CC
[CliContext]: ../swift-daemon-api/Sources/CliContext.swift
[CliContextFile]: ../swift-daemon-api/Sources/CliContextFile.swift
[serval\_commandline\_main]: ../swift-daemon-api/Sources/commandline.swift
[autoconf]: http://www.gnu.org/software/autoconf/autoconf.html
[GNU autoconf]: http://www.gnu.org/software/autoconf/autoconf.html
[Bash shell]: http://en.wikipedia.org/wiki/Bash_(Unix_shell)
[Unix]: https://en.wikipedia.org/wiki/Unix
[GNU]: https://en.wikipedia.org/wiki/GNU
[Linux]: https://en.wikipedia.org/wiki/Linux
[Darwin]: https://en.wikipedia.org/wiki/Darwin_(operating_system)
[autoconf macro archive]: http://www.gnu.org/software/autoconf-archive/
[GNU M4]: http://www.gnu.org/software/m4/m4.html
[GCC]: https://gcc.gnu.org/

View File

@ -1,56 +1,81 @@
HDRS= fifo.h \
SQLITE3_AMALGAMATION = sqlite-amalgamation-3140200
SQLITE3_HDRS = $(SQLITE3_AMALGAMATION)/sqlite3.h
# These library headers are designed for re-use, and do not depend on any
# SERVAL_HDRS.
LIB_HDRS= \
lang.h \
feature.h \
section.h \
trigger.h \
uri.h \
base64.h \
xprintf.h \
whence.h \
str.h \
strbuf.h \
serval_uuid.h \
numeric_str.h \
socket.h \
net.h \
mem.h \
os.h \
strbuf_helpers.h \
log.h \
log_output.h \
debug.h \
rotbuf.h \
fifo.h \
cli.h \
fdqueue.h \
http_server.h \
nibble_tree.h
# These headers are specific to Serval DNA, and also depend on LIB_HDRS. They
# are exposed by the iOS framework module, so they are accessible to Swift code
# in Xcode projects.
PUBLIC_HDRS= \
constants.h \
serval_types.h \
rhizome_types.h \
dataformats.h \
instance.h \
sighandlers.h \
commandline.h \
crypto.h \
server.h \
servald_main.h \
sync_keys.h \
keyring.h \
route_link.h \
limit.h \
overlay_buffer.h \
overlay_address.h \
overlay_packet.h \
overlay_interface.h \
section.h \
trigger.h \
commandline.h \
limit.h \
rhizome_types.h \
rhizome.h \
sync_keys.h \
httpd.h \
instance.h \
meshms.h \
meshmb.h \
message_ply.h \
nibble_tree.h \
serval_types.h \
serval.h \
server.h \
route_link.h \
keyring.h \
socket.h \
cli.h \
str.h \
numeric_str.h \
base64.h \
uri.h \
rotbuf.h \
mem.h \
os.h \
serval_uuid.h \
sighandlers.h \
strbuf.h \
strbuf_helpers.h \
conf.h \
conf_schema.h \
crypto.h \
dataformats.h \
log.h \
log_output.h \
debug.h \
net.h \
fdqueue.h \
http_server.h \
xprintf.h \
lang.h \
constants.h \
monitor-client.h \
mdp_client.h \
msp_client.h \
msp_common.h \
msp_server.h \
radio_link.h \
$(SQLITE3_AMALGAMATION)/sqlite3.h
monitor-client.h \
serval.h
# These headers are specific to Serval DNA, and also depend on LIB_HDRS. They are
# not exposed by the iOS framework module, so are inaccessible to Swift code in
# Xcode projects.
PRIVATE_HDRS= \
conf.h \
httpd.h \
msp_common.h \
# These headers cannot be included stand-alone, but some PRIVATE_HDRS depend on them.
SERVAL_META_HDRS = \
conf_schema.h
# All header files, useful for writing dependency rules with total coverage.
ALL_HDRS = $(LIB_HDRS) $(PUBLIC_HDRS) $(PRIVATE_HDRS) $(SQLITE3_HDRS) $(SERVAL_META_HDRS)

18
ios/README.md Normal file
View File

@ -0,0 +1,18 @@
Serval DNA on iOS
=================
[Serval Project][], September 2016
The files in this directory are used for building [Serval DNA][] for [Apple iOS][].
See [Serval DNA on iOS][] for instructions.
-----
**Copyright 2016 Flinders University**
![CC-BY-4.0](./cc-by-4.0.png)
This document is available under the [Creative Commons Attribution 4.0 International licence][CC BY 4.0].
[Serval Project]: http://www.servalproject.org/
[Serval DNA]: ../README.md
[Serval DNA on iOS]: ../doc/Apple-iOS.md
[Apple iOS]: https://en.wikipedia.org/wiki/IOS

403
ios/configure vendored Executable file
View File

@ -0,0 +1,403 @@
#!/bin/bash
#
# Build configuration utility for Serval DNA on Apple iOS.
#
# Copyright 2016-2017 Flinders University
#
# This script runs Serval DNA's main 'configure' script several times, once for
# each different target iOS target, and saves the Makefile that is generated by
# each run. It then creates a top-level Makefile that:
# (1) invokes each of the saved Makefiles in turn to generate one static library
# for each target, then
# (2) combines all these libraries into a single "multi slice" static library
# that can be imported into an Xcode project.
#
# This allows the iOS development cycle to be similarly rapid as for platforms
# such as Linux or native Apple OS-X:
# (1) a single 'configure' step adapts the Makefile(s) to the specific needs of
# the target architecture(s), then
# (2) the edit-make-test cycle can be repeated as often as desired:
# (a) edit; make changes to source file(s)
# (b) make; compile the changed source files into executable form using the
# dependency rules in the Makefile(s), which avoids unnecessary
# re-compilation, then re-build the app in Xcode, which links in the
# new static library
# (c) test; run the re-built app, either in an iOS simulator or by
# side-loading into an iPhone
#
# Exit on error
set -e
usage() {
echo "Usage: ${0##*/} [-f|--force]"
}
# Run the Serval DNA configure script once for each architecture, and save the
# files produced by each run.
main() {
setup
parse_command_line "$@"
check
exec 5>&1
TARGETS=()
configure iphoneos armv7 /Library/Serval
configure iphoneos arm64 /Library/Serval
configure iphonesimulator i386 /tmp/serval-dna
configure iphonesimulator x86_64 /tmp/serval-dna
create_makefile
}
# Trace and diagnostic functions.
run() {
echo + "$@" >&5
"$@"
}
usage_error() {
echo "${0##*/}: $*" >&2
usage >&2
exit 1
}
fatal() {
echo "${0##*/}: $1" >&2
shift
while [ $# -ne 0 ]; do
echo "$1" >&2
shift
done
exit 1
}
# Parse command-line options.
parse_command_line() {
library=libservaldaemon.a
swiftmodule=ServalDNA.swiftmodule
opt_force_configure=false
opt_force_config_status=false
log_display_line_count=10
while [ $# -ne 0 ]; do
opt="$1"
shift
case "$opt" in
-h | --help)
usage
exit 0
;;
-f|--force-configure)
opt_force_configure=true
;;
--force-config-status)
opt_force_config_status=true
;;
-*)
usage_error "Unknown option: $opt"
;;
*)
usage_error "Spurious argument: $opt"
;;
esac
done
}
# Work out the path of the directory containing this script relative to the
# current working directory (SCRIPT_DIR), the path of the Serval DNA repository
# root directory relative to the current working directory (SERVAL_DNA_DIR), and
# the path of these two directories relative to each other.
setup() {
case "$0" in
*/?*/*) SCRIPT_DIR="${0%/*}"; SERVAL_DNA_DIR="${0%/?*/*}";;
./*) SCRIPT_DIR="."; SERVAL_DNA_DIR="..";;
*/*) SCRIPT_DIR="${0%/*}"; SERVAL_DNA_DIR=".";;
*) SCRIPT_DIR="."; SERVAL_DNA_DIR="..";;
esac
SCRIPT_DIR_RELATIVE_TO_SERVAL_DNA_DIR="$(cd "$SCRIPT_DIR" >/dev/null && echo "${PWD##*/}")"
SERVAL_DNA_DIR_RELATIVE_TO_SCRIPT_DIR=".."
SERVAL_DNA_CONFIGURE="$SERVAL_DNA_DIR/configure"
}
# Ensure that the Serval DNA 'configure' script exists and is executable.
check() {
if [ ! -e "$SERVAL_DNA_CONFIGURE" ]; then
fatal "missing script: $SERVAL_DNA_CONFIGURE" \
"Run 'autoreconf -f -i -I m4' then run me again."
fi
if [ ! -x "$SERVAL_DNA_CONFIGURE" ]; then
fatal "script is not executable: $SERVAL_DNA_CONFIGURE" \
"Run 'autoreconf -f -i -I m4' then run me again."
fi
case "$("$SERVAL_DNA_CONFIGURE" --version)" in
servald\ configure\ *) ;;
*) fatal "malfunctioning script: $SERVAL_DNA_CONFIGURE" \
"Run 'autoreconf -f -i -I m4' then run me again."
esac
}
configure() {
local platform="${1?}"
local arch="${2?}"
local prefix="${3?}"
# Convert from the Xcode architecture name to the autoconf cpu name, so it
# can be passed in the --host option to the configure script.
local cpu
case "$arch" in
arm64) cpu=aarch64;;
*) cpu="$arch";;
esac
# A "target" is an architecture (aka, "slice" or "architecture", eg, armv7,
# arm64, i386) and an Apple SDK (eg, iphoneos, iphonesimulator, macosx).
local target="$arch-$platform"
TARGETS+=("$arch-$platform")
configure_script="$SERVAL_DNA_DIR_RELATIVE_TO_SCRIPT_DIR/configure"
makefile_in="$SERVAL_DNA_DIR_RELATIVE_TO_SCRIPT_DIR/Makefile.in"
# Path of the directory under which the files this script creates will be placed
# relative to the directory containing this script.
local target_build_dir="$SCRIPT_DIR/build/$target"
target_build_dir="${target_build_dir#./}"
script_dir_relative_to_target_build_dir="../.."
if [ ! -d "$target_build_dir" ]; then
run mkdir -p "$target_build_dir"
fi
# Note: the configure script created by autoconf places its output files in
# the current working directory.
if $opt_force_configure || $opt_force_config_status ||
! [ -e "$target_build_dir/.configured" ] ||
[ "$target_build_dir/config.status" -ot "$configure_script" ] ||
[ "$target_build_dir/Makefile" -ot "$configure_script" ] ||
[ "$target_build_dir/Makefile" -ot "$makefile_in" ] ||
[ "$target_build_dir/Makefile" -ot "$target_build_dir/config.status" ]
then
run pushd "$target_build_dir" >/dev/null
rm -f .configured
configure_script="$script_dir_relative_to_target_build_dir/$configure_script"
makefile_in="$script_dir_relative_to_target_build_dir/$makefile_in"
if $opt_force_configure ||
! [ -e ".configured" ] ||
[ "config.status" -ot "$configure_script" ] ||
[ "Makefile" -ot "$configure_script" ]
then
run rm -f config.status Makefile
if ! run "$configure_script" \
--host="$cpu-apple-darwin" \
--enable-xcode-sdk="$platform" \
--prefix "$prefix" \
&>configure.out
then
fatal "configure failed; see $target_build_dir/configure.out for full log" \
"Last $log_display_line_count lines were:" \
"" \
"$(tail -n $log_display_line_count configure.out)"
fi
if [ ! -r config.status ]; then
fatal "configure for $target did not produce config.status"
fi
if [ ! -r Makefile ]; then
fatal "configure for $target did not produce Makefile"
fi
elif $opt_force_config_status ||
[ "Makefile" -ot "$makefile_in" ] ||
[ "Makefile" -ot "config.status" ]
then
run rm -f Makefile
if ! run ./config.status &>config.status.out
then
fatal "./config.status failed; see $target_build_dir/config.status.out:" \
"$(cat config.status.out)"
fi
fi
> .configured
run popd >/dev/null
fi
}
# Create a Serval DNA Makefile that creates an Apple framework bundle:
# - generates a modulemap file for the bundle
# - generates a Xcode config file
# - invokes all the per-target iOS makefiles to create one static library for
# each target slice (arch-sdk)
# - merges all the static libraries into a single, multi-slice library
# - generates an Info.plist XML file describing the bundle
# - creates the correct directory structure and symbolic links for the bundle
foreach_target() {
local target
local target_dir
for target in "${TARGETS[@]}"; do
arch="${target%%-*}"
sdk="${target#-*}"
target_dir="build/$target"
target_var=$(echo -n "$target" | tr -C a-zA-z0-9_ _)
eval "$@"
done
}
create_makefile() {
echo "Creating $SCRIPT_DIR/Makefile"
cat >"$SCRIPT_DIR/Makefile" <<EOF
# Makefile for Serval DNA on Apple iOS
# Copyright 2017 Flinders University
# This file was auto-generated by the ./${0##*/} script
# $(date)
srcdir=$SERVAL_DNA_DIR_RELATIVE_TO_SCRIPT_DIR
dstdir=frameworks
targets=${TARGETS[*]}
fw_name=ServalDNA
fw_version=A
fw_bundle_id=org.servalproject.serval-dna
fw_bundle_version=1.0
fw_dir=\$(dstdir)/\$(fw_name).framework
fw_dstdir=\$(fw_dir)/Versions/\$(fw_version)
fw_library=\$(fw_dstdir)/\$(fw_name)
fw_swiftmodule=\$(fw_dstdir)/Modules/\$(fw_name).swiftmodule
fw_info_plist=\$(fw_dstdir)/Resources/Info.plist
fw_config_headers=\$(targets:%=\$(fw_dstdir)/Headers/%/config.h)
fw_serval_headers=\$(addprefix \$(fw_dstdir)/Headers/, \$(LIB_HDRS) \$(PUBLIC_HDRS))
fw_sqlite3_headers=\$(addprefix \$(fw_dstdir)/Headers/, \$(notdir \$(SQLITE3_HDRS)))
fw_modulemap=\$(fw_dstdir)/Modules/module.modulemap
xcconfig=\$(dstdir)/\$(fw_name).xcconfig
include \$(srcdir)/headerfiles.mk
.PHONY: all \\
clean\
$(foreach_target echo '" \\"' \; \
echo '" install_${target_var}_sodium_headers \\"' \; \
echo '" $target_dir/$library \\"' \; \
echo '" $target_dir/$swiftmodule \\"' \; \
echo -n '" clean-$target"')
all: \$(fw_library) \\
\$(fw_info_plist) \\
\$(fw_config_headers) \\
\$(fw_serval_headers) \\
\$(fw_sqlite3_headers) \\
\$(fw_modulemap) \\
\$(xcconfig)$(foreach_target echo '" \\"' \; \
echo -n '" install_${target_var}_sodium_headers"' \; \
echo -n '" \$(fw_swiftmodule)/$arch.swiftmodule"')
cd \$(fw_dstdir)/.. && ln -snf \$(fw_version) Current
cd \$(fw_dstdir)/../.. && ln -snf Versions/Current/* .
\$(fw_info_plist): ./info-plist.sh
mkdir -p \$(dir \$@)
./info-plist.sh \$(fw_name) \$(fw_bundle_id) \$(fw_bundle_version) >\$@
\$(fw_library):$(foreach_target echo '" \\"' \; \
echo -n '" $target_dir/$library"')
mkdir -p \$(dir \$@)
lipo -create -output \$@ \$^
$(foreach_target echo '"\$(fw_swiftmodule)/$arch.swiftmodule: $target_dir/$swiftmodule"' \; \
echo '" mkdir -p \$(dir \$@)"' \; \
echo '" cp \$< \$@"' \; \
echo)
\$(fw_config_headers): \$(fw_dstdir)/Headers/%: build/%
mkdir -p \$(dir \$@)
cp \$< \$@
\$(fw_serval_headers): \$(fw_dstdir)/Headers/%: \$(srcdir)/%
mkdir -p \$(dir \$@)
cp \$< \$@
\$(fw_sqlite3_headers): \$(fw_dstdir)/Headers/%: \$(srcdir)/\$(SQLITE3_AMALGAMATION)/%
mkdir -p \$(dir \$@)
cp \$< \$@
\$(fw_modulemap):$(foreach_target echo '" \\"' \; \
echo -n '" install_${target_var}_sodium_headers"') \\
\$(srcdir)/headerfiles.mk Makefile
mkdir -p \$(dir \$@)
@{ \\
echo '/*' \\
echo 'module.modulemap for Serval DNA on Apple iOS' ;\\
echo 'Copyright 2017 Flinders University' ;\\
echo 'This file was auto-generated by \$(abspath Makefile)' ;\\
echo '\$(shell date)' ;\\
echo '*/' ;\\
echo 'framework module ServalDNA {' ;\\
echo ' requires tls // thread-local storage' ;\\
echo ' explicit module Daemon {' ;\\
echo ' export Sodium' ;\\
$(foreach_target echo '" echo '\'' header \"$target/config.h\"'\'' ;\\"')
for header in \$(LIB_HDRS) \$(PUBLIC_HDRS) \$(notdir \$(SQLITE3_HDRS)); do \\
echo " header \"\$\$header\"" ;\\
done ; \\
echo ' }' ;\\
echo ' explicit module Sodium {' ;\\
$(foreach_target echo '" echo '\'' header \"$target/sodium.h\"'\'' ;\\"' \; \
echo '" (cd $target_dir/libsodium-dev/include/; find . -type f -print | sed -e '\''s|^\./||'\'' -e '\''s|.*| header \"$target/&\"|'\'' ) ;\\"')
echo ' }' ;\\
echo '}' ;\\
echo 'module ifaddrs [system] [extern_c] {' ;\\
echo ' header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/ifaddrs.h"' ;\\
echo ' export *' ;\\
echo '}' ;\\
echo 'module inttypes [system] [extern_c] {' ;\\
echo ' header "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/clang/include/inttypes.h"' ;\\
echo ' export *' ;\\
echo '}' ;\\
} >\$@
\$(xcconfig): Makefile
mkdir -p \$(dir \$@)
@{ \\
echo '// ServalDNA.xcconfig for Serval DNA on Apple iOS' ;\\
echo '// Copyright 2017 Flinders University' ;\\
echo '// This file was auto-generated by \$(abspath Makefile)' ;\\
echo '// \$(shell date)' ;\\
echo 'SERVAL_DNA_FRAMEWORK_DIR = \$(abspath \$(fw_dir))' ;\\
echo 'FRAMEWORK_SEARCH_PATHS = \$\$(inherited) \$(abspath \$(dstdir))' ;\\
echo 'GCC_PREPROCESSOR_DEFINITIONS = \$\$(inherited) HAVE_CONFIG_H=1' ;\\
$(foreach_target echo '" echo '\''HEADER_SEARCH_PATHS[arch=$arch] = \$\$(inherited) \$\$(SERVAL_DNA_FRAMEWORK_DIR)/Headers/$target'\'' ;\\"')
echo 'SWIFT_INCLUDE_PATHS = \$\$(inherited) \$\$(SERVAL_DNA_FRAMEWORK_DIR)/Modules' ;\\
echo 'OTHER_SWIFT_FLAGS = \$\$(inherited) -Xcc -DHAVE_CONFIG_H=1' ;\\
} >\$@
$(foreach_target echo \; \
echo '"install_${target_var}_sodium_headers: $target_dir/$library"' \; \
echo '" cp -R $target_dir/libsodium-dev/include/ \$(fw_dstdir)/Headers/$target/"')
# If the source directory is already configured, then its config.h header
# file would interfere with these sub-makes, so delete it before invoking
# each sub-make.
$(foreach_target echo \; \
echo '"$target_dir/$library:"' \; \
echo '" \$(RM) \$(srcdir)/config.h"' \; \
echo '" \$(MAKE) -C $target_dir $library"')
$(foreach_target echo \; \
echo '"$target_dir/$swiftmodule:"' \; \
echo '" \$(RM) \$(srcdir)/config.h"' \; \
echo '" \$(MAKE) -C $target_dir $swiftmodule"')
clean: $(foreach_target echo -n '" clean-$target"')
\$(RM) -r \$(dstdir)
$(foreach_target echo \; \
echo '"clean-$target:"' \; \
echo '" \$(MAKE) -C $target_dir clean"')
EOF
}
main "$@"

54
ios/info-plist.sh Executable file
View File

@ -0,0 +1,54 @@
#!/bin/bash
# Utility to output an Apple framework Info.plist file for Serval DNA.
# Copyright 2017 Flinders University
set -e
case "$0" in
*/*) SERVAL_DNA_DIR="${0%/*}/..";;
*) SERVAL_DNA_DIR="..";;
esac
bundle_name="${1?}"
bundle_id="${2?}"
bundle_version="${3?}"
escape() {
echo -n "$(printf '%s\n' "$*" | sed -e 's/&/&amp;/g' -e 's/</&lt;/g' -e 's/>/&gt;/g')"
}
comment() {
echo '<!--'
local arg
for arg; do
printf ' %s\n' "$arg" | sed -e 's/-->/-- >/g'
done
echo '-->'
}
property() {
echo -n ' <key>'
escape "$1"
echo -n '</key><string>'
escape "$2"
echo '</string>'
}
echo '<?xml version="1.0" encoding="UTF-8"?>'
echo '<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'
comment "Info.plist for the $bundle_name framework iOS bundle." \
"Copyright 2007 Flinders University"
echo '<plist version="1.0">'
echo '<dict>'
property CFBundleIdentifier "$bundle_id"
property CFBundleName "$bundle_name"
property CFBundleVersion "$bundle_version"
property CFBundleShortVersionString "$bundle_version"
property CFBundleExecutable "$bundle_name"
property CFBundleDevelopmentRegion English
property CFBundleInfoDictionaryVersion 6.0
property CFBundlePackageType FMWK
property NSHumanReadableCopyright "$(cat $SERVAL_DNA_DIR/COPYRIGHT.txt)"
echo '</dict>'
echo '</plist>'