mirror of
https://github.com/zhigang1992/ReactiveViewModel.git
synced 2026-01-12 17:43:19 +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
|
# objc-build-scripts
|
||||||
[Janky](https://github.com/github/janky). To use them, read the contents of this
|
|
||||||
repository into a `script` folder:
|
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
|
$ 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
|
$ 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
|
history. You can also freely tweak the scripts for your specific project's
|
||||||
needs.
|
needs.
|
||||||
|
|
||||||
To bring in upstream changes later:
|
To merge in upstream changes later:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git fetch -p objc-build-scripts
|
$ 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
|
#!/bin/bash
|
||||||
|
|
||||||
SCRIPT_DIR=$(dirname "$0")
|
export SCRIPT_DIR=$(dirname "$0")
|
||||||
cd "$SCRIPT_DIR/.."
|
|
||||||
|
|
||||||
set -o errexit
|
##
|
||||||
|
## Configuration Variables
|
||||||
|
##
|
||||||
|
|
||||||
echo "*** Updating submodules..."
|
config ()
|
||||||
git submodule sync --quiet
|
{
|
||||||
git submodule update --init
|
# A whitespace-separated list of executables that must be present and locatable.
|
||||||
git submodule foreach --recursive --quiet "git submodule sync --quiet && git submodule update --init"
|
: ${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
|
#!/bin/bash
|
||||||
|
|
||||||
SCRIPT_DIR=$(dirname "$0")
|
export SCRIPT_DIR=$(dirname "$0")
|
||||||
cd "$SCRIPT_DIR/.."
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Configuration Variables
|
## Configuration Variables
|
||||||
##
|
##
|
||||||
|
|
||||||
# The build configuration to use.
|
SCHEMES="$@"
|
||||||
if [ -z "$XCCONFIGURATION" ]
|
|
||||||
then
|
|
||||||
XCCONFIGURATION="Release"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# The workspace to build.
|
config ()
|
||||||
#
|
{
|
||||||
# If not set and no workspace is found, the -workspace flag will not be passed
|
# The workspace to build.
|
||||||
# to xcodebuild.
|
#
|
||||||
if [ -z "$XCWORKSPACE" ]
|
# If not set and no workspace is found, the -workspace flag will not be passed
|
||||||
then
|
# to `xctool`.
|
||||||
XCWORKSPACE=$(ls -d *.xcworkspace 2>/dev/null | head -n 1)
|
#
|
||||||
fi
|
# 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.
|
# The project to build.
|
||||||
#
|
#
|
||||||
# If this file does not exist, it is not considered an error.
|
# If not set and no project is found, the -project flag will not be passed
|
||||||
BOOTSTRAP="$SCRIPT_DIR/bootstrap"
|
# 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
|
# A bootstrap script to run before building.
|
||||||
# are specified on the command line.
|
#
|
||||||
#
|
# If this file does not exist, it is not considered an error.
|
||||||
# Individual names can be quoted to avoid word splitting.
|
: ${BOOTSTRAP="$SCRIPT_DIR/bootstrap"}
|
||||||
DEFAULT_TARGETS=
|
|
||||||
|
|
||||||
# Extra build settings to pass to xcodebuild.
|
# Extra options to pass to xctool.
|
||||||
XCODEBUILD_SETTINGS="TEST_AFTER_BUILD=YES"
|
: ${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
|
## Build Process
|
||||||
##
|
##
|
||||||
|
|
||||||
if [ -z "$*" ]
|
main ()
|
||||||
then
|
{
|
||||||
# lol recursive shell script
|
config
|
||||||
if [ -n "$DEFAULT_TARGETS" ]
|
|
||||||
|
if [ -f "$BOOTSTRAP" ]
|
||||||
then
|
then
|
||||||
echo "$DEFAULT_TARGETS" | xargs "$SCRIPT_DIR/cibuild"
|
echo "*** Bootstrapping..."
|
||||||
else
|
"$BOOTSTRAP" || exit $?
|
||||||
xcodebuild -list | awk -f "$SCRIPT_DIR/targets.awk" | xargs "$SCRIPT_DIR/cibuild"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exit $?
|
echo "*** The following schemes will be built:"
|
||||||
fi
|
echo "$SCHEMES" | xargs -n 1 echo " "
|
||||||
|
echo
|
||||||
|
|
||||||
if [ -f "$BOOTSTRAP" ]
|
echo "$SCHEMES" | xargs -n 1 | (
|
||||||
then
|
local status=0
|
||||||
echo "*** Bootstrapping..."
|
|
||||||
bash "$BOOTSTRAP" || exit $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "*** The following targets will be built:"
|
while read scheme
|
||||||
|
do
|
||||||
|
build_scheme "$scheme" || status=1
|
||||||
|
done
|
||||||
|
|
||||||
for target in "$@"
|
exit $status
|
||||||
do
|
)
|
||||||
echo "$target"
|
}
|
||||||
done
|
|
||||||
|
|
||||||
echo "*** Cleaning all targets..."
|
find_pattern ()
|
||||||
xcodebuild -alltargets clean OBJROOT="$PWD/build" SYMROOT="$PWD/build" $XCODEBUILD_SETTINGS
|
|
||||||
|
|
||||||
run_xcodebuild ()
|
|
||||||
{
|
{
|
||||||
local scheme=$1
|
ls -d $1 2>/dev/null | head -n 1
|
||||||
|
}
|
||||||
|
|
||||||
|
run_xctool ()
|
||||||
|
{
|
||||||
if [ -n "$XCWORKSPACE" ]
|
if [ -n "$XCWORKSPACE" ]
|
||||||
then
|
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
|
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
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
local status=$?
|
parse_build ()
|
||||||
|
{
|
||||||
return $status
|
awk -f "$SCRIPT_DIR/xctool.awk" 2>&1 >/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
build_scheme ()
|
build_scheme ()
|
||||||
{
|
{
|
||||||
local scheme=$1
|
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 awkstatus=$?
|
||||||
local xcstatus=${PIPESTATUS[0]}
|
|
||||||
|
|
||||||
if [ "$xcstatus" -eq "65" ]
|
if [ "$awkstatus" -ne "0" ]
|
||||||
then
|
then
|
||||||
# This probably means that there's no scheme by that name. Give up.
|
# Unit tests aren't supported.
|
||||||
echo "*** Error building scheme $scheme -- perhaps it doesn't exist"
|
action=build
|
||||||
elif [ "$awkstatus" -eq "1" ]
|
|
||||||
then
|
|
||||||
return $awkstatus
|
|
||||||
fi
|
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 "$@"
|
main
|
||||||
do
|
|
||||||
build_scheme "$scheme" || exit $?
|
|
||||||
done
|
|
||||||
|
|||||||
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