Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upGitHub is where the world builds software
Millions of developers and companies build, ship, and maintain their software on GitHub — the largest and most advanced development platform in the world.
| #!/bin/bash | |
| set -e | |
| nephbin="$(dirname "$(readlink -f "$0")")" | |
| . "$nephbin"/lib/util.sh | |
| . "$nephbin"/lib/moz.sh | |
| . ~/.bashrc | |
| cd "$MOZPATH" | |
| parse_args mb xj:bicfvp \ | |
| autoclobber,moz:,no-mach,cgroup,no-distcc,ramdisk,no-buildtree,only-distcc,nuke,cpufreq,branch: \ | |
| "$@" | |
| eval args=("$(get_args)") | |
| # Enable autoclobber in make system | |
| autoclobber="$(get_option autoclobber)$(get_option x)" | |
| # Select and use a specific moz config, string is passed to moz() as args | |
| mozconfig="$(get_option moz)" | |
| # Don't use mach | |
| nomach="$(get_option no-mach)" | |
| # Use cgroup hooks | |
| cgroup="$(get_option cgroup)" | |
| # Don't use distcc | |
| nodistcc="$(get_option no-distcc)" | |
| # Build against current tree, without build-tree | |
| nobuildtree="$(get_option no-buildtree)" | |
| # Only sync buildtree, don't build anything | |
| onlysyncbuild="$(get_option b)" | |
| # Don't use local cpus | |
| onlydistcc="$(get_option only-distcc)" | |
| # Delete objdir first | |
| nuke="$(get_option nuke)" | |
| explicitbranch="$(get_option branch)" | |
| # Try to put build tree / objdir in ramdisks | |
| ramdisk="$(get_option ramdisk)" | |
| # Explicitly reconfigure tree | |
| configure="$(get_option c)" | |
| # Override clobber check | |
| force="$(get_option f)" | |
| # Make jobs | |
| makejobs="$(get_option j)" | |
| # Use 'binaries' target to do an incremental build, skipping some steps | |
| incremental="$(get_option i)" | |
| verbose="$(get_option v)" | |
| # make package when finished | |
| package="$(get_option p)" | |
| # Jump to performance cpufreq | |
| cpufreq="$(get_option cpufreq)" | |
| # | |
| # mozconfig | |
| # | |
| [ -z "$mozconfig" ] || cmd moz $mozconfig | |
| # | |
| # Make environment | |
| # | |
| PYTHON="py2e python" | |
| MACH="py2e ./mach" | |
| MAKE="py2e make" | |
| [ -z "$verbose" ] && MAKE="$MAKE --silent" | |
| # | |
| # Defaults & Sanity | |
| # | |
| # If this is set, the build system clobbers if one is needed | |
| [ -z "$autoclobber" ] || export AUTOCLOBBER=1 | |
| if [[ "${#args[@]}" -eq 1 && "${args[0]}" = "binaries" ]]; then | |
| # mb -i is just shorthand for "mb binaries" | |
| incremental=1 | |
| elif [ -n "$incremental" ]; then | |
| [ "${#args[@]}" -eq 0 ] || die "Cannot specify directories along with -i" | |
| args=("binaries") | |
| fi | |
| [ -z "$ramdisk" ] || ramdisk="/tmp/mb-ramdisk-$USER" | |
| if [ ! -z "$nodistcc" ] && [ ! -z "$onlydistcc" ]; then | |
| die "--no-distcc and --only-distcc are mutually exclusive" | |
| fi | |
| if [ -z "$MOZOBJ" ] || [ -z "$MOZTREE" ] || [ -z "$MOZCONFIG" ] || \ | |
| [ ! -d "$MOZTREE" ] || [ ! -f "$MOZCONFIG" ]; then | |
| die "moz environment is not properly configured :(" | |
| fi | |
| if [ -z "$nomach" ]; then | |
| if [ ! -f "$MOZTREE/mach" ]; then | |
| die "This tree has no mach, but --no-mach was not specified" | |
| fi | |
| # See if mach this tree's revision of mach supports package/buildsymbols | |
| ! $MACH help buildsymbols &>/dev/null || mach_buildsymbols=1 | |
| ! $MACH help package &>/dev/null || mach_package=1 | |
| fi | |
| [ -f "$MOZTREE/client.mk" ] || die "Tree \"$MOZTREE\" doesn't have a client.mk..." | |
| if [ -n "$incremental" ]; then | |
| if [ -n "$autoclobber$nuke" ]; then | |
| die "Doing an incremental build with --autoclobber or --nuke doesn't make sense" | |
| fi | |
| if [ ! -f "$MOZOBJ/Makefile" ]; then | |
| die "Can't do an incremental build without a already-built tree" | |
| fi | |
| fi | |
| if [ -z "$nuke" ] && [ -d "$MOZOBJ/.hacky" ]; then | |
| eerr "mb no longer supports hacky.mk, trying to build this tree will fail." | |
| die "switch to an older version of mb, or use --nuke" | |
| fi | |
| # | |
| # Handle --no-buildtree | |
| # | |
| if [ ! -z "$nobuildtree" ]; then | |
| MOZBUILDTREE="$MOZTREE" | |
| fi | |
| # | |
| # Setup cpufreq and cgroup | |
| # | |
| trap="" | |
| if [ ! -z "$cpufreq" ]; then | |
| estat "Boosting cpufreq" | |
| trap="cpufreq-selector -c all -g ondemand" | |
| cpufreq-selector -c all -g performance | |
| fi | |
| if [ ! -z "$cgroup" ]; then | |
| if [ ! -f /sys/fs/cgroup/cpu/tasks ]; then | |
| ewarn "No cgroup" | |
| sleep 2 | |
| else | |
| lpcg | |
| [ -z "$trap" ] || trap="$trap; " | |
| trap="${trap}dcg" | |
| fi | |
| fi | |
| [ -z "$trap" ] || trap "$trap" EXIT | |
| # | |
| # DistCC? | |
| # | |
| if [ -z "$nodistcc" ]; then | |
| # To use pump mode, set this, signal somehow to distcc.conf to add add | |
| # ,cpp,lzo to hosts, make sure mozconfig doesn't use ccache and enables | |
| # distcc. | |
| # MACH="pump $MACH" | |
| # MAKE="pump $MAKE" | |
| # TODO add a way to not require changing mozconfig, make --distcc-pump an | |
| # option or something. | |
| if [ -f "$nephbin/../priv/distcc.conf" ]; then | |
| [ -z "$onlydistcc" ] || export NEPH_DISTCC_NOLOCAL=1 | |
| estat "Found distcc.conf" | |
| source "$nephbin/../priv/distcc.conf" | |
| fi | |
| if [ -z "${DISTCC_HOSTS}${DISTCC_POTENTIAL_HOSTS}" ]; then | |
| eerr "No DISTCC_HOSTS or DISTCC_POTENTIAL_HOSTS" | |
| die "Set these or use --no-distcc" | |
| fi | |
| export MAKE_JOBS=$(( $(distcc -j) * 2 )) | |
| estat "distcc configured with $MAKE_JOBS jobs: "$DISTCC_HOSTS | |
| fi | |
| [ -z "$makejobs" ] || export MAKE_JOBS="$makejobs" | |
| # | |
| # Nuke if requested | |
| # | |
| if [ ! -z "$nuke" ]; then | |
| estat "Nuking build" | |
| [ -z "$ramdisk" ] || cmd rm -rf "$ramdisk" | |
| cmd rm -rf "$MOZOBJ" | |
| # If we're using a ramdisk, --nuke should kill the (potentially-non-ramdisk) | |
| # build tree | |
| [ -z "$ramdisk" ] || cmd rm -rf "$MOZBUILDTREE" | |
| elif [ -d "$MOZOBJ" ] && [ ! -z "$force" ]; then | |
| estat "Overriding clobber" | |
| touch "$MOZOBJ"/CLOBBER | |
| fi | |
| # | |
| # Setup ramdisk maybe | |
| # | |
| # Kill dead ramdisk symlinks | |
| [ ! -L "$MOZBUILDTREE" ] || [ -d "$MOZBUILDTREE" ] || rm "$MOZBUILDTREE" | |
| [ ! -L "$MOZOBJ" ] || [ -d "$MOZOBJ" ] || rm "$MOZOBJ" | |
| if [ ! -z "$ramdisk" ]; then | |
| # Check for existing, non-ramdisk directories | |
| if [ -e "$MOZOBJ" ] && [ ! -L "$MOZOBJ" ]; then | |
| die "Non-ramdisk objdir exists. Drop --ramdisk or use --nuke" | |
| fi | |
| if [ -e "$MOZBUILDTREE" ] && [ ! -L "$MOZBUILDTREE" ]; then | |
| # Build tree isn't ramdisk | |
| if [ -n "$nuke" ]; then | |
| # With nuke, just delete build tree to remake on ramdisk below | |
| estat "Switching to ramdisk build tree, nuking existing" | |
| cmd rm -rf "$MOZBUILDTREE" | |
| else | |
| die "Non-ramdisk build tree exists, use --nuke or drop --ramdisk" | |
| fi | |
| fi | |
| # Setup ramdisk | |
| if [ ! -d "$ramdisk" ]; then | |
| ( umask 077 && cmd mkdir "$ramdisk" ) | |
| ( cd "$ramdisk" && ln -s "$MOZPATH/cfg" ) | |
| fi | |
| if [ ! -d "$MOZOBJ" ]; then | |
| cmd mkdir "$ramdisk/$MOZOBJ" | |
| cmd ln -s "$ramdisk/$MOZOBJ" | |
| fi | |
| else | |
| # Not using a ramdisk, make sure one isn't setup | |
| if [ -L "$MOZBUILDTREE" ] || [ -L "$MOZOBJ" ]; then | |
| if [ -n "$nuke" ]; then | |
| # --nuke was given, just delete existing build tree | |
| cmd rm -rf "$ramdisk/$MOZBUILDTREE" | |
| cmd rm -f "$MOZBUILDTREE" | |
| else | |
| die "--ramdisk not given, but current build is on a ramdisk. Use --nuke" | |
| fi | |
| fi | |
| fi | |
| # | |
| # If configured at this point, check that it is against the right tree | |
| # | |
| if [ -f "$MOZOBJ/Makefile" ]; then | |
| configured_tree="$(egrep '^topsrcdir' "$MOZOBJ/Makefile" | awk '{ print $NF }')" | |
| configured_tree="$(readlink -f "$configured_tree")" | |
| expected_tree="$(readlink -f "$MOZBUILDTREE")" | |
| if [ "$configured_tree" != "$expected_tree" ]; then | |
| die "Build directory is configured against the wrong tree, use --nuke" | |
| fi | |
| fi | |
| # | |
| # Setup build tree if needed | |
| # | |
| if [ "$MOZBUILDTREE" != "$MOZTREE" ]; then | |
| # Create a commit via |git stash create| that represents our working tree | |
| # state, and check it out in MOZBUILDTREE to build. | |
| # MOZBUILDTREE will always be on this branch, which is our current branch + a | |
| # working tree commit. This lets us do things like |git diff build/moz-git| to | |
| # compare against our last build, and have a reflog of working directory | |
| # changes we built at. | |
| branch="build/$MOZBUILDTREE" | |
| # The ref our working tree is based on | |
| if [ -z "$explicitbranch" ]; then | |
| buildref=HEAD | |
| else | |
| buildref="$explicitbranch" | |
| no_worktree=1 | |
| fi | |
| buildref="$(cd "$MOZTREE" && git rev-parse "$buildref")" | |
| [ ! -z "$buildref" ] || die "Failed to parse $buildref" | |
| # Make sure build branch exists | |
| if [ ! -d "$MOZBUILDTREE" ]; then | |
| estat "Creating new $MOZBUILDTREE" | |
| ( cd "$MOZTREE" && cmd git branch -f "$branch" "$buildref" ) | |
| if [ -z "$ramdisk" ]; then | |
| /usr/share/git/workdir/git-new-workdir "$MOZTREE" "$MOZBUILDTREE" "$branch" | |
| else | |
| /usr/share/git/workdir/git-new-workdir "$MOZTREE" \ | |
| "$ramdisk/$MOZBUILDTREE" "$branch" | |
| cmd ln -s "$ramdisk/$MOZBUILDTREE" | |
| fi | |
| fi | |
| # Make a staging tree or reset it. We use a staging tree so we can avoid | |
| # touching all uncommited files every build by blowing away the previous build | |
| # commit. It's possible to do this with two trees, but much uglier. | |
| if [ ! -d "mb-staging" ]; then | |
| estat "Creating mb-staging stage tree" | |
| /usr/share/git/workdir/git-new-workdir "$MOZTREE" mb-staging "$buildref" | |
| else | |
| ( | |
| cd mb-staging | |
| git checkout --detach -f "$buildref" 2>/dev/null | |
| ) | |
| fi | |
| ( | |
| cd mb-staging | |
| if [[ ! "$no_worktree" ]]; then | |
| # Copy working tree state to staging with |stash create| and hardlinking | |
| # untracked files over | |
| worktree_stash="$(cd "$MOZPATH/$MOZTREE" && cmd git stash create)" | |
| if [ ! -z "$worktree_stash" ]; then | |
| cmd git stash apply "$worktree_stash" >/dev/null | |
| fi | |
| while IFS="" read -r file; do | |
| cmd mkdir -p "$(dirname "$file")" | |
| cmd ln "$MOZPATH/$MOZTREE/$file" "$file" | |
| done < <(cd "$MOZPATH/$MOZTREE" && git ls-files -o --exclude-standard) | |
| git add -A | |
| fi | |
| cmd git commit --allow-empty -m "BUILD @ $(date)" >/dev/null | |
| ) | |
| buildref="$(cd mb-staging && git rev-parse HEAD)" | |
| ( | |
| # Finally update our build tree to this ref (keeps a helpful build/whatever | |
| # reflog) | |
| cd "$MOZBUILDTREE" | |
| # Should already be on this branch, but we definitely don't want to reset | |
| # another branch if we accidentally messed with this workdir | |
| cmd git checkout -f "$branch" 2>/dev/null | |
| oldref="$(git rev-parse HEAD)" | |
| cmd git reset --hard "$buildref" | |
| PAGER="" cmd git diff "$oldref" --stat | |
| ) | |
| fi | |
| [ -z "$onlysyncbuild" ] || exit 0 | |
| # | |
| # Explicit configure if requested | |
| # | |
| if [ ! -z "$configure" ]; then | |
| if [ -z "$nomach" ]; then | |
| estat "-f specified, nuking config.status to force reconfigure" | |
| cmd rm -vf "$MOZOBJ"/config.status | |
| else | |
| estat "Not using mach, explicitly reconfiguring tree (-f)" | |
| ( | |
| cd "$MOZBUILDTREE" | |
| cmd $MAKE -f client.mk configure | |
| ) | |
| fi | |
| fi | |
| # | |
| # Do the build | |
| # | |
| ( | |
| cmd cd "$MOZBUILDTREE" | |
| if [ -z "$nomach" ]; then | |
| estat "Building with mach" | |
| # Mach ignores make arguments for 'binaries' for whatever reason, if we have | |
| # distcc, force pass a -j directly to mach | |
| if [[ -n $incremental && -n $MAKE_JOBS ]]; then | |
| args=("-j$MAKE_JOBS" "${args[@]}") | |
| fi | |
| cmd $MACH build "${args[@]}" | |
| else | |
| ewarn "Not using mach" | |
| [ "${#args[@]}" -eq 0 ] || die "Building directories not supported w/o mach" | |
| time cmd $MAKE -f client.mk && estat "Make succeeded" | |
| fi | |
| ) | |
| if [ ! -z "$package" ]; then | |
| ( | |
| cmd cd "$MOZBUILDTREE" | |
| [ -n "$nomach_buildsymbols" ] || cmd $MACH buildsymbols | |
| [ -n "$nomach_package" ] || cmd $MACH package | |
| ) | |
| ( | |
| cmd cd "$MOZPATH/$MOZOBJ" | |
| [ -z "$nomach_buildsymbols" ] || cmd $MAKE buildsymbols | |
| [ -z "$nomach_package" ] || cmd $MAKE package | |
| cmd $MAKE package-tests | |
| ) | |
| estat "Package succeeded" | |
| fi |