1#!/bin/bash
2# See usage() below for the description.
3
4function usage() {
5  cat <<EOF
6# This script copies the .jar files that each plugin depends on into the plugins libs folder.
7# By default, on Mac & Linux, this script creates symlinks from the libs folder to the jar file.
8# Since Windows does not support symlinks, the jar files are copied.
9#
10# Options:
11# -f : to copy files rather than creating symlinks on the Mac/Linux platforms.
12# -d : print make dependencies instead of running make; doesn't copy files.
13# -c : copy files expected after make dependencies (reported by -d) have been built.
14#
15# The purpose of -d/-c is to include the workflow in a make file:
16# - the make rule should depend on \$(shell create_all_symlinks -d)
17# - the rule body should perform   \$(shell create_all_symlinks -c [-f])
18EOF
19}
20
21# CD to the top android directory
22PROG_DIR=`dirname "$0"`
23cd "${PROG_DIR}/../../../"
24
25HOST=`uname`
26USE_COPY=""        # force copy dependent jar files rather than creating symlinks
27ONLY_SHOW_DEPS=""  # only report make dependencies but don't build them nor copy.
28ONLY_COPY_DEPS=""  # only copy dependencies built by make; uses -f as needed.
29
30function die() {
31  echo "Error: $*" >/dev/stderr
32  exit 1
33}
34
35function warn() {
36  # Only print something if not in show-deps mode
37  if [[ -z $ONLY_SHOW_DEPS ]]; then
38    echo "$*"
39  fi
40}
41
42function printGradleJarPath() {
43  # Prints to stdout the absolute path of the JAR assembled for a given gradle project.
44  # $1 = source dir, e.g. tools/base or tools/swt
45  # $2 = the gradle project name e.g. common or lint-api
46  echo "## Quering Gradle properties for '$2' in '$1'." > /dev/stderr
47  ( cd $1 && \
48    ./gradlew :$2:properties | awk '
49        BEGIN { B=""; N=""; V="" }
50        /^archivesBaseName:/ { N=$2 }
51        /^buildDir:/         { D=$2 }
52        /^version:/          { V=$2 }
53        END { print D "/libs/" N "-" V ".jar" }' )
54}
55
56## parse arguments
57while [ $# -gt 0 ]; do
58  case "$1" in
59    "-f" )
60      USE_COPY="1"
61      ;;
62    "-d" )
63      ONLY_SHOW_DEPS="1"
64      ;;
65    "-c" )
66      ONLY_COPY_DEPS="1"
67      ;;
68    * )
69      usage
70      exit 2
71  esac
72  shift
73done
74
75warn "## Running $0"
76
77if [[ "${HOST:0:6}" == "CYGWIN" || "$USE_MINGW" == "1" ]]; then
78  # This is either Cygwin or Linux/Mingw cross-compiling to Windows.
79  PLATFORM="windows-x86"
80  if [[ "${HOST:0:6}" == "CYGWIN" ]]; then
81    # We can't use symlinks under Cygwin
82    USE_COPY="1"
83  fi
84elif [[ "$HOST" == "Linux" ]]; then
85  PLATFORM="linux-x86"
86elif [[ "$HOST" == "Darwin" ]]; then
87  PLATFORM="darwin-x86"
88else
89  die "Unsupported platform ($HOST). Aborting."
90fi
91
92if [[ "$USE_COPY" == "1" ]]; then
93  function cpfile { # $1=source $2=dest $3=optional dest filename
94    cp -fv $1 $2/$3
95  }
96else
97  # computes the "reverse" path, e.g. "a/b/c" => "../../.."
98  function back() {
99    echo $1 | sed 's@[^/]*@..@g'
100  }
101
102  function cpfile { # $1=source $2=dest $3=optional dest filename
103    local src=$1
104    if [[ "${src:0:1}" != "/" ]]; then
105      # Not an absolute path. We assume a relative path to be
106      # relative to the android root and we want to make it
107      # relative to the destination dir.
108      src=$(back $2)/$1
109    fi
110    ln -svf $src $2/$3
111  }
112fi
113
114DEST="sdk/eclipse/scripts"
115
116set -e # fail early
117LIBS=""
118CP_FILES=""
119
120
121### Configure which libs to build.
122#
123# Each entry for LIBS needs to be prefixed with the way we want to build it:
124# make: - a library built using its traditional Android.mk
125# base: - a gradle library located in tools/base
126# swt:  - a gradle library located in toosl/swt
127#
128# LIBS entries without or with an unknown ":" prefix will generate an error.
129
130### BASE ###
131
132BASE_PLUGIN_DEST="sdk/eclipse/plugins/com.android.ide.eclipse.base/libs"
133BASE_PLUGIN_LIBS="base:common swt:sdkstats base:sdklib base:dvlib base:layoutlib-api base:sdk-common"
134BASE_PLUGIN_PREBUILTS="\
135    prebuilts/tools/common/m2/repository/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar \
136    prebuilts/tools/common/m2/repository/org/apache/commons/commons-compress/1.0/commons-compress-1.0.jar \
137    prebuilts/tools/common/m2/repository/com/google/guava/guava/15.0/guava-15.0.jar \
138    prebuilts/tools/common/m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar \
139    prebuilts/tools/common/m2/repository/commons-codec/commons-codec/1.4/commons-codec-1.4.jar \
140    prebuilts/tools/common/m2/repository/org/apache/httpcomponents/httpclient/4.1.1/httpclient-4.1.1.jar \
141    prebuilts/tools/common/m2/repository/org/apache/httpcomponents/httpcore/4.1/httpcore-4.1.jar \
142    prebuilts/tools/common/m2/repository/org/apache/httpcomponents/httpmime/4.1/httpmime-4.1.jar"
143
144# temporarily disabled
145#    prebuilts/tools/common/m2/repository/org/bouncycastle/bcpkix-jdk15on/1.48/bcpkix-jdk15on-1.48.jar \
146#    prebuilts/tools/common/m2/repository/org/bouncycastle/bcprov-jdk15on/1.48/bcprov-jdk15on-1.48.jar"
147
148LIBS="$LIBS $BASE_PLUGIN_LIBS"
149CP_FILES="$CP_FILES @:$BASE_PLUGIN_DEST $BASE_PLUGIN_LIBS $BASE_PLUGIN_PREBUILTS"
150
151
152### ADT ###
153
154ADT_DEST="sdk/eclipse/plugins/com.android.ide.eclipse.adt/libs"
155ADT_LIBS="make:ant-glob base:asset-studio base:lint-api base:lint-checks base:ninepatch make:propertysheet \
156          base:rule-api swt:sdkuilib swt:swtmenubar base:manifest-merger"
157ADT_PREBUILTS="\
158    prebuilts/tools/common/freemarker/freemarker-2.3.19.jar \
159    prebuilts/tools/common/m2/repository/org/ow2/asm/asm/4.0/asm-4.0.jar \
160    prebuilts/tools/common/m2/repository/org/ow2/asm/asm-tree/4.0/asm-tree-4.0.jar \
161    prebuilts/tools/common/m2/repository/org/ow2/asm/asm-analysis/4.0/asm-analysis-4.0.jar \
162    prebuilts/tools/common/m2/repository/com/android/tools/external/lombok/lombok-ast/0.2.2/lombok-ast-0.2.2.jar"
163
164LIBS="$LIBS $ADT_LIBS"
165CP_FILES="$CP_FILES @:$ADT_DEST $ADT_LIBS $ADT_PREBUILTS"
166
167
168### DDMS ###
169
170DDMS_DEST="sdk/eclipse/plugins/com.android.ide.eclipse.ddms/libs"
171DDMS_LIBS="base:ddmlib swt:ddmuilib swt:swtmenubar swt:uiautomatorviewer"
172
173DDMS_PREBUILTS="\
174    prebuilts/tools/common/m2/repository/jfree/jcommon/1.0.12/jcommon-1.0.12.jar \
175    prebuilts/tools/common/m2/repository/jfree/jfreechart/1.0.9/jfreechart-1.0.9.jar \
176    prebuilts/tools/common/m2/repository/jfree/jfreechart-swt/1.0.9/jfreechart-swt-1.0.9.jar"
177
178LIBS="$LIBS $DDMS_LIBS"
179CP_FILES="$CP_FILES @:$DDMS_DEST $DDMS_LIBS $DDMS_PREBUILTS"
180
181
182### TEST ###
183
184TEST_DEST="sdk/eclipse/plugins/com.android.ide.eclipse.tests"
185TEST_LIBS="make:easymock base:testutils"
186TEST_PREBUILTS="prebuilts/tools/common/m2/repository/net/sf/kxml/kxml2/2.3.0/kxml2-2.3.0.jar"
187
188LIBS="$LIBS $TEST_LIBS"
189CP_FILES="$CP_FILES @:$TEST_DEST $TEST_LIBS $TEST_PREBUILTS"
190
191
192### BRIDGE ###
193
194if [[ $PLATFORM != "windows-x86" ]]; then
195  # We can't build enough of the platform on Cygwin to create layoutlib
196  BRIDGE_LIBS="make:layoutlib base:ninepatch"
197
198  LIBS="$LIBS $BRIDGE_LIBS"
199fi
200
201
202### HIERARCHYVIEWER ###
203
204HV_DEST="sdk/eclipse/plugins/com.android.ide.eclipse.hierarchyviewer/libs"
205HV_LIBS="swt:hierarchyviewer2lib swt:swtmenubar"
206
207LIBS="$LIBS $HV_LIBS"
208CP_FILES="$CP_FILES @:$HV_DEST $HV_LIBS"
209
210
211### TRACEVIEW ###
212
213TV_DEST="sdk/eclipse/plugins/com.android.ide.eclipse.traceview/libs"
214TV_LIBS="swt:traceview"
215
216LIBS="$LIBS $TV_LIBS"
217CP_FILES="$CP_FILES @:$TV_DEST $TV_LIBS"
218
219
220### MONITOR ###
221
222MONITOR_DEST="sdk/eclipse/plugins/com.android.ide.eclipse.monitor/libs"
223MONITOR_LIBS="swt:sdkuilib"
224
225LIBS="$LIBS $MONITOR_LIBS"
226CP_FILES="$CP_FILES @:$MONITOR_DEST $MONITOR_LIBS"
227
228
229### SDKMANAGER ###
230
231SDKMAN_LIBS="swt:swtmenubar"
232
233LIBS="$LIBS $SDKMAN_LIBS"
234
235
236### GL DEBUGGER ###
237
238if [[ $PLATFORM != "windows-x86" ]]; then
239  # liblzf doesn't build under cygwin. If necessary, this should be fixed first.
240
241  GLD_DEST="sdk/eclipse/plugins/com.android.ide.eclipse.gldebugger/libs"
242  GLD_LIBS="make:host-libprotobuf-java-2.3.0-lite make:liblzf"
243
244  LIBS="$LIBS $GLD_LIBS"
245  CP_FILES="$CP_FILES @:$GLD_DEST $GLD_LIBS"
246fi
247
248
249#--- Determine what to build
250
251UNPROCESSED=""
252GRADLE_SWT=""
253GRADLE_BASE=""
254MAKE_TARGETS=""
255for LIB in $LIBS; do
256  if [[ "${LIB:0:5}" == "base:" ]]; then
257    GRADLE_BASE="$GRADLE_BASE :${LIB:5}:assemble"
258  elif [[ "${LIB:0:4}" == "swt:" ]]; then
259    GRADLE_SWT="$GRADLE_SWT :${LIB:4}:assemble"
260  elif [[ "${LIB:0:5}" == "make:" ]]; then
261    MAKE_TARGETS="$MAKE_TARGETS ${LIB:5}"
262  else
263    UNPROCESSED="$UNPROCESSED $LIB"
264  fi
265done
266
267unset LIBS   # we shouldn't use this anymore, it has been split up just above.
268
269
270if [[ -n $UNPROCESSED ]]; then
271  die "## The following libs lack a prefix (make:, base: or swt:): $UNPROCESSED"
272fi
273
274# In the mode to only echo dependencies, output them and we're done
275if [[ -n $ONLY_SHOW_DEPS ]]; then
276  echo $MAKE_TARGETS
277  exit 0
278fi
279
280# --- Gradle Build ---
281
282# tools/base: if we need it for SWT, we build them all and public local.
283# Otherwise we do a specific tools/base build on just the requested targets.
284
285if [[ -n "$GRADLE_SWT" ]]; then
286  echo "### Starting tools/base: gradlew assemble publishLocal"
287  (cd tools/base && ./gradlew assemble publishLocal)
288elif [[ -n "$GRADLE_BASE" ]]; then
289  echo "### Starting tools/base: gradlew $GRADLE_BASE"
290  (cd tools/base && ./gradlew $GRADLE_BASE)
291fi
292
293# tools/swt: build requested targets
294
295if [[ -n "$GRADLE_SWT" ]]; then
296  echo "### Starting tools/swt: gradlew $GRADLE_SWT"
297  (cd tools/swt && ./gradlew $GRADLE_SWT)
298fi
299
300# --- Android.mk Build ---
301
302# If some of the libs are available in prebuilts/devtools, use link to them directly
303# instead of trying to rebuild them so remove them from the libs to build. Note that
304# they are already listed in CP_FILES so we'll adjust the source to copy later.
305
306NEW_TARGETS=""
307for LIB in $MAKE_TARGETS; do
308  J="prebuilts/devtools/tools/lib/$LIB.jar"
309  if [[ ! -f $J ]]; then
310    J="prebuilts/devtools/adt/lib/$LIB.jar"
311  fi
312  if [[ -f $J ]]; then
313    warn "## Using existing $J"
314  else
315    NEW_TARGETS="$NEW_TARGETS $LIB"
316  fi
317done
318MAKE_TARGETS="$NEW_TARGETS"
319unset NEW_TARGETS
320
321if [[ -z $ONLY_COPY_DEPS ]]; then
322  if [[ -n $MAKE_TARGETS ]]; then
323    ( # Make sure we have lunch sdk-<something>
324      if [[ ! "$TARGET_PRODUCT" ]]; then
325        warn "## TARGET_PRODUCT is not set, running build/envsetup.sh"
326        . build/envsetup.sh
327        warn "## lunch sdk-eng"
328        lunch sdk-eng
329      fi
330
331      J="4"
332      [[ $(uname) == "Darwin" ]] && J=$(sysctl hw.ncpu | cut -d : -f 2 | tr -d ' ')
333      [[ $(uname) == "Linux"  ]] && J=$(cat /proc/cpuinfo | grep processor | wc -l)
334
335      warn "## Building libs: make -j$J $MAKE_TARGETS"
336      make -j${J} $MAKE_TARGETS
337    )
338  fi
339fi
340
341# --- Copy resulting files ---
342
343DEST=""
344for SRC in $CP_FILES; do
345  if [[ "${SRC:0:2}" == "@:" ]]; then
346    DEST="${SRC:2}"
347    mkdir -vp "$DEST"
348    continue
349  fi
350
351  ORIG_SRC="$SRC"
352  DEST_FILE=""
353
354  if [[ "${SRC:0:5}" == "base:" ]]; then
355    SRC="${SRC:5}"
356    ORIG_SRC="$SRC"
357    DEST_FILE="$SRC.jar"
358    SRC=$(printGradleJarPath tools/base $SRC)
359  elif [[ "${SRC:0:4}" == "swt:" ]]; then
360    SRC="${SRC:4}"
361    ORIG_SRC="$SRC"
362    DEST_FILE="$SRC.jar"
363    SRC=$(printGradleJarPath tools/swt $SRC)
364  elif [[ "${SRC:0:5}" == "make:" ]]; then
365    SRC="${SRC:5}"
366    ORIG_SRC="$SRC"
367  fi
368
369  if [[ ! -f "$SRC" ]]; then
370    # Take a prebuilts/devtools instead of a framework one if possible.
371    SRC="prebuilts/devtools/tools/lib/$SRC.jar"
372    if [[ ! -f "$SRC" ]]; then
373      SRC="prebuilts/devtools/adt/lib/$ORIG_SRC.jar"
374    fi
375    if [[ ! -f "$SRC" ]]; then
376      SRC="out/host/$PLATFORM/framework/$ORIG_SRC.jar"
377    fi
378  fi
379  if [[ -f "$SRC" ]]; then
380    if [[ ! -d "$DEST" ]]; then
381      die "Invalid cp_file dest directory: $DEST"
382    fi
383
384    cpfile "$SRC" "$DEST" "$DEST_FILE"
385  else
386    die "## Unknown source '$ORIG_SRC' to copy in '$DEST'"
387  fi
388done
389
390# OS-specific post operations
391
392if [ "${HOST:0:6}" == "CYGWIN" ]; then
393  chmod -v a+rx "$ADT_DEST"/*.jar
394fi
395
396echo "### $0 done"
397