1#!/bin/bash 2 3# Ensure that GNU parallel is installed. 4# We use this to build multiple targets at the same time. 5if [[ -z $(command -v parallel) ]]; then 6 echo "Please install GNU Parallel." 7 exit 8fi 9 10if [[ $# -lt 2 ]]; then 11 echo "Usage: $0 <Android root directory> <output directory> [specific targets to build]" 12 exit 13fi 14 15android_root_dir=$1 16export out_dir=$2 17shift 2 18all_targets="$@" 19 20echo "Android tree: $android_root_dir" 21echo "Output directory: $out_dir" 22 23mkdir -p $out_dir 24 25cd $android_root_dir 26source build/envsetup.sh > /dev/null 27 28# Collect the list of targets by parsing the output of lunch. 29# TODO: This misses some targets. 30if [[ "$all_targets" = "" ]]; then 31 all_targets=`lunch 2>/dev/null <<< _ | grep "[0-9]" | sed 's/^.* //'` 32fi 33 34# Clean up targets by replacing eng with userdebug using non-aosp variants. 35declare -A targets_map 36for target in $all_targets; do 37 targets_map[$target]=$target 38done 39targets="" 40for target in $all_targets; do 41 clean_target=$(echo $target | sed 's/-eng/-userdebug/' | sed 's/aosp_//') 42 if [[ $clean_target != $target ]] && [[ ${targets_map[$clean_target]} == $clean_target ]]; then 43 echo "Ignoring $target in favor of $clean_target" 44 else 45 if [[ -z $targets ]]; then 46 targets=$target 47 else 48 targets="$targets $target" 49 fi 50 fi 51done 52 53# Calculate the number of targets to build at once. 54# This heuristic could probably be improved. 55cores=$(nproc --all) 56num_targets=$(echo "$targets" | sed 's/ /\n/g' | wc -l) 57parallel_jobs=$(expr $cores / 4) 58if [[ $num_targets -lt $parallel_jobs ]]; then 59 export mmma_jobs=$(expr $cores / $num_targets \* 2) 60else 61 export mmma_jobs=4 62fi 63 64echo "$num_targets target(s): $(echo $targets | paste -sd' ')" 65 66compile_target () { 67 target=$1 68 source build/envsetup.sh > /dev/null 69 lunch $target &> /dev/null 70 # Some targets can't lunch properly. 71 if [ $? -ne 0 ]; then 72 echo "$target cannot be lunched" 73 return 1 74 fi 75 my_out_file="$out_dir/log.$target" 76 rm -f $my_out_file 77 # Build the policy. 78 OUT_DIR=$out_dir/out.$target mmma -j$mmma_jobs system/sepolicy &>> $my_out_file 79 if [ $? -ne 0 ]; then 80 echo "$target failed to build" 81 return 2 82 fi 83 return 0 84} 85export -f compile_target 86 87parallel --no-notice -j $parallel_jobs --bar --joblog $out_dir/joblog compile_target ::: $targets 88 89echo "Failed to lunch: $(grep "\s1\s0\scompile_target" $out_dir/joblog | sed 's/^.* //' | sort | paste -sd' ')" 90echo "Failed to build: $(grep "\s2\s0\scompile_target" $out_dir/joblog | sed 's/^.* //' | sort | paste -sd' ')" 91