mirror of
https://github.com/zhigang1992/ReactiveViewModel.git
synced 2026-01-12 09:24:31 +08:00
Update objc-build-scripts
This commit is contained in:
@@ -1,6 +1,66 @@
|
||||
These scripts are primarily meant to support the use of
|
||||
[Janky](https://github.com/github/janky). To use them, read the contents of this
|
||||
repository into a `script` folder:
|
||||
# objc-build-scripts
|
||||
|
||||
This project is a collection of scripts created with two goals:
|
||||
|
||||
1. To standardize how Objective-C projects are bootstrapped after cloning
|
||||
1. To easily build Objective-C projects on continuous integration servers
|
||||
|
||||
## Scripts
|
||||
|
||||
Right now, there are two important scripts: [`bootstrap`](#bootstrap) and
|
||||
[`cibuild`](#cibuild). Both are Bash scripts, to maximize compatibility and
|
||||
eliminate pesky system configuration issues (like setting up a working Ruby
|
||||
environment).
|
||||
|
||||
The structure of the scripts on disk is meant to follow that of a typical Ruby
|
||||
project:
|
||||
|
||||
```
|
||||
script/
|
||||
bootstrap
|
||||
cibuild
|
||||
```
|
||||
|
||||
### bootstrap
|
||||
|
||||
This script is responsible for bootstrapping (initializing) your project after
|
||||
it's been checked out. Here, you should install or clone any dependencies that
|
||||
are required for a working build and development environment.
|
||||
|
||||
By default, the script will verify that [xctool][] is installed, then initialize
|
||||
and update submodules recursively. If any submodules contain `script/bootstrap`,
|
||||
that will be run as well.
|
||||
|
||||
To check that other tools are installed, you can set the `REQUIRED_TOOLS`
|
||||
environment variable before running `script/bootstrap`, or edit it within the
|
||||
script directly. Note that no installation is performed automatically, though
|
||||
this can always be added within your specific project.
|
||||
|
||||
### cibuild
|
||||
|
||||
This script is responsible for building the project, as you would want it built
|
||||
for continuous integration. This is preferable to putting the logic on the CI
|
||||
server itself, since it ensures that any changes are versioned along with the
|
||||
source.
|
||||
|
||||
By default, the script will run [`bootstrap`](#bootstrap), look for any Xcode
|
||||
workspace or project in the working directory, then build all targets/schemes
|
||||
(as found by `xcodebuild -list`) using [xctool][].
|
||||
|
||||
You can also specify the schemes to build by passing them into the script:
|
||||
|
||||
```sh
|
||||
script/cibuild ReactiveCocoa-Mac ReactiveCocoa-iOS
|
||||
```
|
||||
|
||||
As with the `bootstrap` script, there are several environment variables that can
|
||||
be used to customize behavior. They can be set on the command line before
|
||||
invoking the script, or the defaults changed within the script directly.
|
||||
|
||||
## Getting Started
|
||||
|
||||
To add the scripts to your project, read the contents of this repository into
|
||||
a `script` folder:
|
||||
|
||||
```
|
||||
$ git remote add objc-build-scripts https://github.com/jspahrsummers/objc-build-scripts.git
|
||||
@@ -8,13 +68,15 @@ $ git fetch objc-build-scripts
|
||||
$ git read-tree --prefix=script/ -u objc-build-scripts/master
|
||||
```
|
||||
|
||||
Then commit the changes to incorporate the scripts into your own repository's
|
||||
Then commit the changes, to incorporate the scripts into your own repository's
|
||||
history. You can also freely tweak the scripts for your specific project's
|
||||
needs.
|
||||
|
||||
To bring in upstream changes later:
|
||||
To merge in upstream changes later:
|
||||
|
||||
```
|
||||
$ git fetch -p objc-build-scripts
|
||||
$ git merge -Xsubtree=script objc-build-scripts/master
|
||||
$ git merge --ff --squash -Xsubtree=script objc-build-scripts/master
|
||||
```
|
||||
|
||||
[xctool]: https://github.com/facebook/xctool
|
||||
|
||||
@@ -1,11 +1,73 @@
|
||||
#!/bin/bash
|
||||
|
||||
SCRIPT_DIR=$(dirname "$0")
|
||||
cd "$SCRIPT_DIR/.."
|
||||
export SCRIPT_DIR=$(dirname "$0")
|
||||
|
||||
set -o errexit
|
||||
##
|
||||
## Configuration Variables
|
||||
##
|
||||
|
||||
echo "*** Updating submodules..."
|
||||
git submodule sync --quiet
|
||||
git submodule update --init
|
||||
git submodule foreach --recursive --quiet "git submodule sync --quiet && git submodule update --init"
|
||||
config ()
|
||||
{
|
||||
# A whitespace-separated list of executables that must be present and locatable.
|
||||
: ${REQUIRED_TOOLS="xctool"}
|
||||
|
||||
export REQUIRED_TOOLS
|
||||
}
|
||||
|
||||
##
|
||||
## Bootstrap Process
|
||||
##
|
||||
|
||||
main ()
|
||||
{
|
||||
config
|
||||
|
||||
if [ -n "$REQUIRED_TOOLS" ]
|
||||
then
|
||||
echo "*** Checking dependencies..."
|
||||
check_deps
|
||||
fi
|
||||
|
||||
local submodules=$(git submodule status 2>/dev/null)
|
||||
if [ -n "$submodules" ]
|
||||
then
|
||||
echo "*** Updating submodules..."
|
||||
update_submodules
|
||||
fi
|
||||
}
|
||||
|
||||
check_deps ()
|
||||
{
|
||||
for tool in $REQUIRED_TOOLS
|
||||
do
|
||||
which -s "$tool"
|
||||
if [ "$?" -ne "0" ]
|
||||
then
|
||||
echo "*** Error: $tool not found. Please install it and bootstrap again."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
bootstrap_submodule ()
|
||||
{
|
||||
local bootstrap="script/bootstrap"
|
||||
|
||||
if [ -e "$bootstrap" ]
|
||||
then
|
||||
echo "*** Bootstrapping $name..."
|
||||
"$bootstrap" >/dev/null
|
||||
else
|
||||
update_submodules
|
||||
fi
|
||||
}
|
||||
|
||||
update_submodules ()
|
||||
{
|
||||
git submodule sync --quiet && git submodule update --init && git submodule foreach --quiet bootstrap_submodule
|
||||
}
|
||||
|
||||
export -f bootstrap_submodule
|
||||
export -f update_submodules
|
||||
|
||||
main
|
||||
|
||||
166
script/cibuild
166
script/cibuild
@@ -1,114 +1,142 @@
|
||||
#!/bin/bash
|
||||
|
||||
SCRIPT_DIR=$(dirname "$0")
|
||||
cd "$SCRIPT_DIR/.."
|
||||
export SCRIPT_DIR=$(dirname "$0")
|
||||
|
||||
##
|
||||
## Configuration Variables
|
||||
##
|
||||
|
||||
# The build configuration to use.
|
||||
if [ -z "$XCCONFIGURATION" ]
|
||||
then
|
||||
XCCONFIGURATION="Release"
|
||||
fi
|
||||
SCHEMES="$@"
|
||||
|
||||
# The workspace to build.
|
||||
#
|
||||
# If not set and no workspace is found, the -workspace flag will not be passed
|
||||
# to xcodebuild.
|
||||
if [ -z "$XCWORKSPACE" ]
|
||||
then
|
||||
XCWORKSPACE=$(ls -d *.xcworkspace 2>/dev/null | head -n 1)
|
||||
fi
|
||||
config ()
|
||||
{
|
||||
# The workspace to build.
|
||||
#
|
||||
# If not set and no workspace is found, the -workspace flag will not be passed
|
||||
# to `xctool`.
|
||||
#
|
||||
# Only one of `XCWORKSPACE` and `XCODEPROJ` needs to be set. The former will
|
||||
# take precedence.
|
||||
: ${XCWORKSPACE=$(find_pattern "*.xcworkspace")}
|
||||
|
||||
# A bootstrap script to run before building.
|
||||
#
|
||||
# If this file does not exist, it is not considered an error.
|
||||
BOOTSTRAP="$SCRIPT_DIR/bootstrap"
|
||||
# The project to build.
|
||||
#
|
||||
# If not set and no project is found, the -project flag will not be passed
|
||||
# to `xctool`.
|
||||
#
|
||||
# Only one of `XCWORKSPACE` and `XCODEPROJ` needs to be set. The former will
|
||||
# take precedence.
|
||||
: ${XCODEPROJ=$(find_pattern "*.xcodeproj")}
|
||||
|
||||
# A whitespace-separated list of default targets or schemes to build, if none
|
||||
# are specified on the command line.
|
||||
#
|
||||
# Individual names can be quoted to avoid word splitting.
|
||||
DEFAULT_TARGETS=
|
||||
# A bootstrap script to run before building.
|
||||
#
|
||||
# If this file does not exist, it is not considered an error.
|
||||
: ${BOOTSTRAP="$SCRIPT_DIR/bootstrap"}
|
||||
|
||||
# Extra build settings to pass to xcodebuild.
|
||||
XCODEBUILD_SETTINGS="TEST_AFTER_BUILD=YES"
|
||||
# Extra options to pass to xctool.
|
||||
: ${XCTOOL_OPTIONS="RUN_CLANG_STATIC_ANALYZER=NO"}
|
||||
|
||||
# A whitespace-separated list of default schemes to build.
|
||||
#
|
||||
# Individual names can be quoted to avoid word splitting.
|
||||
: ${SCHEMES:=$(xcodebuild -list 2>/dev/null | awk -f "$SCRIPT_DIR/schemes.awk")}
|
||||
|
||||
export XCWORKSPACE
|
||||
export XCODEPROJ
|
||||
export BOOTSTRAP
|
||||
export XCTOOL_OPTIONS
|
||||
export SCHEMES
|
||||
}
|
||||
|
||||
##
|
||||
## Build Process
|
||||
##
|
||||
|
||||
if [ -z "$*" ]
|
||||
then
|
||||
# lol recursive shell script
|
||||
if [ -n "$DEFAULT_TARGETS" ]
|
||||
main ()
|
||||
{
|
||||
config
|
||||
|
||||
if [ -f "$BOOTSTRAP" ]
|
||||
then
|
||||
echo "$DEFAULT_TARGETS" | xargs "$SCRIPT_DIR/cibuild"
|
||||
else
|
||||
xcodebuild -list | awk -f "$SCRIPT_DIR/targets.awk" | xargs "$SCRIPT_DIR/cibuild"
|
||||
echo "*** Bootstrapping..."
|
||||
"$BOOTSTRAP" || exit $?
|
||||
fi
|
||||
|
||||
exit $?
|
||||
fi
|
||||
echo "*** The following schemes will be built:"
|
||||
echo "$SCHEMES" | xargs -n 1 echo " "
|
||||
echo
|
||||
|
||||
if [ -f "$BOOTSTRAP" ]
|
||||
then
|
||||
echo "*** Bootstrapping..."
|
||||
bash "$BOOTSTRAP" || exit $?
|
||||
fi
|
||||
echo "$SCHEMES" | xargs -n 1 | (
|
||||
local status=0
|
||||
|
||||
echo "*** The following targets will be built:"
|
||||
while read scheme
|
||||
do
|
||||
build_scheme "$scheme" || status=1
|
||||
done
|
||||
|
||||
for target in "$@"
|
||||
do
|
||||
echo "$target"
|
||||
done
|
||||
exit $status
|
||||
)
|
||||
}
|
||||
|
||||
echo "*** Cleaning all targets..."
|
||||
xcodebuild -alltargets clean OBJROOT="$PWD/build" SYMROOT="$PWD/build" $XCODEBUILD_SETTINGS
|
||||
|
||||
run_xcodebuild ()
|
||||
find_pattern ()
|
||||
{
|
||||
local scheme=$1
|
||||
ls -d $1 2>/dev/null | head -n 1
|
||||
}
|
||||
|
||||
run_xctool ()
|
||||
{
|
||||
if [ -n "$XCWORKSPACE" ]
|
||||
then
|
||||
xcodebuild -workspace "$XCWORKSPACE" -scheme "$scheme" -configuration "$XCCONFIGURATION" build OBJROOT="$PWD/build" SYMROOT="$PWD/build" $XCODEBUILD_SETTINGS
|
||||
xctool -workspace "$XCWORKSPACE" $XCTOOL_OPTIONS "$@" 2>&1
|
||||
elif [ -n "$XCODEPROJ" ]
|
||||
then
|
||||
xctool -project "$XCODEPROJ" $XCTOOL_OPTIONS "$@" 2>&1
|
||||
else
|
||||
xcodebuild -scheme "$scheme" -configuration "$XCCONFIGURATION" build OBJROOT="$PWD/build" SYMROOT="$PWD/build" $XCODEBUILD_SETTINGS
|
||||
echo "*** No workspace or project file found."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
local status=$?
|
||||
|
||||
return $status
|
||||
parse_build ()
|
||||
{
|
||||
awk -f "$SCRIPT_DIR/xctool.awk" 2>&1 >/dev/null
|
||||
}
|
||||
|
||||
build_scheme ()
|
||||
{
|
||||
local scheme=$1
|
||||
|
||||
run_xcodebuild "$scheme" 2>&1 | awk -f "$SCRIPT_DIR/xcodebuild.awk"
|
||||
echo "*** Cleaning $scheme..."
|
||||
run_xctool -scheme "$scheme" clean >/dev/null || exit $?
|
||||
|
||||
echo "*** Building and testing $scheme..."
|
||||
echo
|
||||
|
||||
local sdkflag=
|
||||
local action=test
|
||||
|
||||
# Determine whether we can run unit tests for this target.
|
||||
run_xctool -scheme "$scheme" run-tests | parse_build
|
||||
|
||||
local awkstatus=$?
|
||||
local xcstatus=${PIPESTATUS[0]}
|
||||
|
||||
if [ "$xcstatus" -eq "65" ]
|
||||
if [ "$awkstatus" -ne "0" ]
|
||||
then
|
||||
# This probably means that there's no scheme by that name. Give up.
|
||||
echo "*** Error building scheme $scheme -- perhaps it doesn't exist"
|
||||
elif [ "$awkstatus" -eq "1" ]
|
||||
then
|
||||
return $awkstatus
|
||||
# Unit tests aren't supported.
|
||||
action=build
|
||||
fi
|
||||
|
||||
return $xcstatus
|
||||
if [ "$awkstatus" -eq "1" ]
|
||||
then
|
||||
# Build for iOS.
|
||||
sdkflag="-sdk iphonesimulator"
|
||||
fi
|
||||
|
||||
run_xctool $sdkflag -scheme "$scheme" $action
|
||||
}
|
||||
|
||||
echo "*** Building..."
|
||||
export -f build_scheme
|
||||
export -f run_xctool
|
||||
export -f parse_build
|
||||
|
||||
for scheme in "$@"
|
||||
do
|
||||
build_scheme "$scheme" || exit $?
|
||||
done
|
||||
main
|
||||
|
||||
12
script/schemes.awk
Normal file
12
script/schemes.awk
Normal file
@@ -0,0 +1,12 @@
|
||||
BEGIN {
|
||||
FS = "\n";
|
||||
}
|
||||
|
||||
/Targets:/ {
|
||||
while (getline && $0 != "") {
|
||||
if ($0 ~ /Test/) continue;
|
||||
|
||||
sub(/^ +/, "");
|
||||
print "'" $0 "'";
|
||||
}
|
||||
}
|
||||
25
script/xctool.awk
Normal file
25
script/xctool.awk
Normal file
@@ -0,0 +1,25 @@
|
||||
# Exit statuses:
|
||||
#
|
||||
# 0 - No errors found.
|
||||
# 1 - Wrong SDK. Retry with SDK `iphonesimulator`.
|
||||
# 2 - Missing target.
|
||||
|
||||
BEGIN {
|
||||
status = 0;
|
||||
}
|
||||
|
||||
{
|
||||
print;
|
||||
}
|
||||
|
||||
/Testing with the '(.+)' SDK is not yet supported/ {
|
||||
status = 1;
|
||||
}
|
||||
|
||||
/does not contain a target named/ {
|
||||
status = 2;
|
||||
}
|
||||
|
||||
END {
|
||||
exit status;
|
||||
}
|
||||
Reference in New Issue
Block a user