1#!/bin/bash
2# Copyright 2013 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6# This a simple script to make building/testing Mojo components easier (on
7# Linux).
8
9# TODO(vtl): Maybe make the test runner smart and not run unchanged test
10# binaries.
11# TODO(vtl) Maybe also provide a way to pass command-line arguments to the test
12# binaries.
13
14do_help() {
15  cat << EOF
16Usage: $(basename "$0") [command|option ...]
17
18command should be one of:
19  build - Build.
20  test - Run unit tests (does not build).
21  perftest - Run perf tests (does not build).
22  pytest - Run Python unit tests.
23  gyp - Run gyp for mojo (does not sync).
24  gypall - Run gyp for all of chromium (does not sync).
25  sync - Sync using gclient (does not run gyp).
26  show-bash-alias - Outputs an appropriate bash alias for mojob. In bash do:
27      \$ eval \`mojo/tools/mojob.sh show-bash-alias\`
28
29option (which will only apply to following commands) should be one of:
30  Build/test options (specified before build/test/perftest):
31    --debug - Build/test in Debug mode.
32    --release - Build/test in Release mode.
33    --debug-and-release - Build/test in both Debug and Release modes (default).
34  Compiler options (specified before gyp):
35    --clang - Use clang (default).
36    --gcc - Use gcc.
37  Component options:
38    --shared Build components as shared libraries (default).
39    --static Build components as static libraries.
40  Use goma:
41    --use-goma - Use goma if \$GOMA_DIR is set or \$HOME/goma exists (default).
42    --no-use-goma - Do not use goma.
43
44Note: It will abort on the first failure (if any).
45EOF
46}
47
48do_build() {
49  echo "Building in out/$1 ..."
50  if [ "$GOMA" = "auto" -a -v GOMA_DIR ]; then
51    ninja -j 1000 -C "out/$1" mojo || exit 1
52  else
53    ninja -C "out/$1" mojo || exit 1
54  fi
55}
56
57do_unittests() {
58  echo "Running unit tests in out/$1 ..."
59  mojo/tools/test_runner.py mojo/tools/data/unittests "out/$1" \
60      mojob_test_successes || exit 1
61}
62
63do_perftests() {
64  echo "Running perf tests in out/$1 ..."
65  "out/$1/mojo_public_system_perftests" || exit 1
66}
67
68do_pytests() {
69  python mojo/tools/run_mojo_python_tests.py || exit 1
70}
71
72do_gyp() {
73  local gyp_defines="$(make_gyp_defines)"
74  echo "Running gyp for mojo with GYP_DEFINES=$gyp_defines ..."
75  GYP_DEFINES="$gyp_defines" build/gyp_chromium mojo/mojo.gyp || exit 1
76}
77
78do_gypall() {
79  local gyp_defines="$(make_gyp_defines)"
80  echo "Running gyp for everything with GYP_DEFINES=$gyp_defines ..."
81  GYP_DEFINES="$gyp_defines" build/gyp_chromium || exit 1
82}
83
84do_sync() {
85  # Note: sync only (with hooks, but no gyp-ing).
86  GYP_CHROMIUM_NO_ACTION=1 gclient sync || exit 1
87}
88
89# Valid values: Debug, Release, or Debug_and_Release.
90BUILD_TEST_TYPE=Debug_and_Release
91should_do_Debug() {
92  test "$BUILD_TEST_TYPE" = Debug -o "$BUILD_TEST_TYPE" = Debug_and_Release
93}
94should_do_Release() {
95  test "$BUILD_TEST_TYPE" = Release -o "$BUILD_TEST_TYPE" = Debug_and_Release
96}
97
98# Valid values: clang or gcc.
99COMPILER=clang
100# Valid values: shared or static.
101COMPONENT=shared
102# Valid values: auto or disabled.
103GOMA=auto
104make_gyp_defines() {
105  local options=()
106  # Always include these options.
107  options+=("use_aura=1")
108  case "$COMPILER" in
109    clang)
110      options+=("clang=1")
111      ;;
112    gcc)
113      options+=("clang=0")
114      ;;
115  esac
116  case "$COMPONENT" in
117    shared)
118      options+=("component=shared_library")
119      ;;
120    static)
121      options+=("component=static_library")
122      ;;
123  esac
124  case "$GOMA" in
125    auto)
126      if [ -v GOMA_DIR ]; then
127        options+=("use_goma=1" "gomadir=\"${GOMA_DIR}\"")
128      else
129        options+=("use_goma=0")
130      fi
131      ;;
132    disabled)
133      options+=("use_goma=0")
134      ;;
135  esac
136  echo "${options[*]}"
137}
138
139set_goma_dir_if_necessary() {
140  if [ "$GOMA" = "auto" -a ! -v GOMA_DIR ]; then
141    if [ -d "${HOME}/goma" ]; then
142      GOMA_DIR="${HOME}/goma"
143    fi
144  fi
145}
146
147start_goma_if_necessary() {
148  if [ "$GOMA" = "auto" -a -v GOMA_DIR ]; then
149    "${GOMA_DIR}/goma_ctl.py" ensure_start
150  fi
151}
152
153# We're in src/mojo/tools. We want to get to src.
154cd "$(realpath "$(dirname "$0")")/../.."
155
156if [ $# -eq 0 ]; then
157  do_help
158  exit 0
159fi
160
161for arg in "$@"; do
162  case "$arg" in
163    # Commands -----------------------------------------------------------------
164    help|--help)
165      do_help
166      exit 0
167      ;;
168    build)
169      set_goma_dir_if_necessary
170      start_goma_if_necessary
171      should_do_Debug && do_build Debug
172      should_do_Release && do_build Release
173      ;;
174    test)
175      should_do_Debug && do_unittests Debug
176      should_do_Release && do_unittests Release
177      ;;
178    perftest)
179      should_do_Debug && do_perftests Debug
180      should_do_Release && do_perftests Release
181      ;;
182    pytest)
183      do_pytests
184      ;;
185    gyp)
186      set_goma_dir_if_necessary
187      do_gyp
188      ;;
189    gypall)
190      set_goma_dir_if_necessary
191      do_gypall
192      ;;
193    sync)
194      do_sync
195      ;;
196    show-bash-alias)
197      # You want to type something like:
198      #   alias mojob=\
199      #       '"$(pwd | sed '"'"'s/\(.*\/src\).*/\1/'"'"')/mojo/tools/mojob.sh"'
200      # This is quoting hell, so we simply escape every non-alphanumeric
201      # character.
202      echo alias\ mojob\=\'\"\$\(pwd\ \|\ sed\ \'\"\'\"\'s\/\\\(\.\*\\\/src\\\)\
203\.\*\/\\1\/\'\"\'\"\'\)\/mojo\/tools\/mojob\.sh\"\'
204      ;;
205    # Options ------------------------------------------------------------------
206    --debug)
207      BUILD_TEST_TYPE=Debug
208      ;;
209    --release)
210      BUILD_TEST_TYPE=Release
211      ;;
212    --debug-and-release)
213      BUILD_TEST_TYPE=Debug_and_Release
214      ;;
215    --clang)
216      COMPILER=clang
217      ;;
218    --gcc)
219      COMPILER=gcc
220      ;;
221    --shared)
222      COMPONENT=shared
223      ;;
224    --static)
225      COMPONENT=static
226      ;;
227    --use-goma)
228      GOMA=auto
229      ;;
230    --no-use-goma)
231      GOMA=disabled
232      ;;
233    *)
234      echo "Unknown command \"${arg}\". Try \"$(basename "$0") help\"."
235      exit 1
236      ;;
237  esac
238done
239