From 3952f6cb0d701223f0b60a52c9f10554a898e564 Mon Sep 17 00:00:00 2001 From: Michael Bestas Date: Fri, 26 Aug 2016 01:12:08 +0300 Subject: [PATCH] Import CM build additions Change-Id: Id1eb902129754e61dfcc2b5d95c3a75172ff0c5e --- build/core/mtk_target.mk | 13 + build/core/mtk_utils.mk | 5 + build/core/qcom_target.mk | 133 +++ build/core/qcom_utils.mk | 230 +++++ build/envsetup.sh | 931 ++++++++++++++++++ .../product/security/cm-devkey.x509.pem | 23 + build/target/product/security/cm.x509.pem | 21 + build/tasks/dt_image.mk | 53 + build/tasks/kernel.mk | 373 +++++++ build/tools/repopick.py | 407 ++++++++ build/tools/roomservice.py | 297 ++++++ config/common.mk | 6 + 12 files changed, 2492 insertions(+) create mode 100644 build/core/mtk_target.mk create mode 100755 build/core/mtk_utils.mk create mode 100644 build/core/qcom_target.mk create mode 100755 build/core/qcom_utils.mk create mode 100644 build/envsetup.sh create mode 100644 build/target/product/security/cm-devkey.x509.pem create mode 100644 build/target/product/security/cm.x509.pem create mode 100644 build/tasks/dt_image.mk create mode 100644 build/tasks/kernel.mk create mode 100755 build/tools/repopick.py create mode 100755 build/tools/roomservice.py diff --git a/build/core/mtk_target.mk b/build/core/mtk_target.mk new file mode 100644 index 00000000..7c3ba1f6 --- /dev/null +++ b/build/core/mtk_target.mk @@ -0,0 +1,13 @@ +ifeq ($(BOARD_USES_MTK_HARDWARE),true) + mtk_flags := -DMTK_HARDWARE + + TARGET_GLOBAL_CFLAGS += $(mtk_flags) + TARGET_GLOBAL_CPPFLAGS += $(mtk_flags) + CLANG_TARGET_GLOBAL_CFLAGS += $(mtk_flags) + CLANG_TARGET_GLOBAL_CPPFLAGS += $(mtk_flags) + + 2ND_TARGET_GLOBAL_CFLAGS += $(mtk_flags) + 2ND_TARGET_GLOBAL_CPPFLAGS += $(mtk_flags) + 2ND_CLANG_TARGET_GLOBAL_CFLAGS += $(mtk_flags) + 2ND_CLANG_TARGET_GLOBAL_CPPFLAGS += $(mtk_flags) +endif diff --git a/build/core/mtk_utils.mk b/build/core/mtk_utils.mk new file mode 100755 index 00000000..48fd6605 --- /dev/null +++ b/build/core/mtk_utils.mk @@ -0,0 +1,5 @@ +# Board platforms lists to be used for +# TARGET_BOARD_PLATFORM specific featurization +MTK_BOARD_PLATFORMS := mt6592 +MTK_BOARD_PLATFORMS += mt6582 +MTK_BOARD_PLATFORMS += mt6572 diff --git a/build/core/qcom_target.mk b/build/core/qcom_target.mk new file mode 100644 index 00000000..29e134a3 --- /dev/null +++ b/build/core/qcom_target.mk @@ -0,0 +1,133 @@ +# Target-specific configuration + +# Populate the qcom hardware variants in the project pathmap. +define ril-set-path-variant +$(call project-set-path-variant,ril,TARGET_RIL_VARIANT,hardware/$(1)) +endef +define wlan-set-path-variant +$(call project-set-path-variant,wlan,TARGET_WLAN_VARIANT,hardware/qcom/$(1)) +endef +define bt-vendor-set-path-variant +$(call project-set-path-variant,bt-vendor,TARGET_BT_VENDOR_VARIANT,hardware/qcom/$(1)) +endef + +# Set device-specific HALs into project pathmap +define set-device-specific-path +$(if $(USE_DEVICE_SPECIFIC_$(1)), \ + $(if $(DEVICE_SPECIFIC_$(1)_PATH), \ + $(eval path := $(DEVICE_SPECIFIC_$(1)_PATH)), \ + $(eval path := $(TARGET_DEVICE_DIR)/$(2))), \ + $(eval path := $(3))) \ +$(call project-set-path,qcom-$(2),$(strip $(path))) +endef + +ifeq ($(BOARD_USES_QCOM_HARDWARE),true) + + qcom_flags := -DQCOM_HARDWARE + qcom_flags += -DQCOM_BSP + qcom_flags += -DQTI_BSP + + TARGET_USES_QCOM_BSP := true + + # Tell HALs that we're compiling an AOSP build with an in-line kernel + TARGET_COMPILE_WITH_MSM_KERNEL := true + + ifneq ($(filter msm7x27a msm7x30 msm8660 msm8960,$(TARGET_BOARD_PLATFORM)),) + # Enable legacy graphics functions + qcom_flags += -DQCOM_BSP_LEGACY + # Enable legacy audio functions + ifeq ($(BOARD_USES_LEGACY_ALSA_AUDIO),true) + USE_CUSTOM_AUDIO_POLICY := 1 + qcom_flags += -DLEGACY_ALSA_AUDIO + endif + endif + + # Enable extra offloading for post-805 targets + ifneq ($(filter msm8992 msm8994,$(TARGET_BOARD_PLATFORM)),) + qcom_flags += -DHAS_EXTRA_FLAC_METADATA + endif + + TARGET_GLOBAL_CFLAGS += $(qcom_flags) + TARGET_GLOBAL_CPPFLAGS += $(qcom_flags) + CLANG_TARGET_GLOBAL_CFLAGS += $(qcom_flags) + CLANG_TARGET_GLOBAL_CPPFLAGS += $(qcom_flags) + + # Multiarch needs these too.. + 2ND_TARGET_GLOBAL_CFLAGS += $(qcom_flags) + 2ND_TARGET_GLOBAL_CPPFLAGS += $(qcom_flags) + 2ND_CLANG_TARGET_GLOBAL_CFLAGS += $(qcom_flags) + 2ND_CLANG_TARGET_GLOBAL_CPPFLAGS += $(qcom_flags) + + ifeq ($(QCOM_HARDWARE_VARIANT),) + ifneq ($(filter msm8610 msm8226 msm8974,$(TARGET_BOARD_PLATFORM)),) + QCOM_HARDWARE_VARIANT := msm8974 + else + ifneq ($(filter msm8909 msm8916,$(TARGET_BOARD_PLATFORM)),) + QCOM_HARDWARE_VARIANT := msm8916 + else + ifneq ($(filter msm8953 msm8937,$(TARGET_BOARD_PLATFORM)),) + QCOM_HARDWARE_VARIANT := msm8937 + else + ifneq ($(filter msm8992 msm8994,$(TARGET_BOARD_PLATFORM)),) + QCOM_HARDWARE_VARIANT := msm8994 + else + QCOM_HARDWARE_VARIANT := $(TARGET_BOARD_PLATFORM) + endif + endif + endif + endif + endif + +# HACK: check to see if build uses standard QC HAL paths by checking for CM path structure +AOSP_VARIANT_MAKEFILE := $(wildcard hardware/qcom/audio/default/Android.mk) +ifeq ("$(AOSP_VARIANT_MAKEFILE)","") +$(call project-set-path,qcom-audio,hardware/qcom/audio) +$(call project-set-path,qcom-display,hardware/qcom/display) +$(call project-set-path,qcom-media,hardware/qcom/media) +$(call set-device-specific-path,CAMERA,camera,hardware/qcom/camera) +$(call set-device-specific-path,GPS,gps,hardware/qcom/gps) +$(call set-device-specific-path,SENSORS,sensors,hardware/qcom/sensors) +$(call set-device-specific-path,LOC_API,loc-api,vendor/qcom/opensource/location) +$(call set-device-specific-path,DATASERVICES,dataservices,vendor/qcom/opensource/dataservices) +$(call project-set-path,ril,hardware/ril) +$(call project-set-path,wlan,hardware/qcom/wlan) +$(call project-set-path,bt-vendor,hardware/qcom/bt) +else +$(call project-set-path,qcom-audio,hardware/qcom/audio-caf/$(QCOM_HARDWARE_VARIANT)) + +ifeq ($(SONY_BF64_KERNEL_VARIANT),true) +$(call project-set-path,qcom-display,hardware/qcom/display-caf/sony) +$(call project-set-path,qcom-media,hardware/qcom/media-caf/sony) +else +$(call project-set-path,qcom-display,hardware/qcom/display-caf/$(QCOM_HARDWARE_VARIANT)) +$(call project-set-path,qcom-media,hardware/qcom/media-caf/$(QCOM_HARDWARE_VARIANT)) +endif + +$(call set-device-specific-path,CAMERA,camera,hardware/qcom/camera) +$(call set-device-specific-path,GPS,gps,hardware/qcom/gps) +$(call set-device-specific-path,SENSORS,sensors,hardware/qcom/sensors) +$(call set-device-specific-path,LOC_API,loc-api,vendor/qcom/opensource/location) +$(call set-device-specific-path,DATASERVICES,dataservices,vendor/qcom/opensource/dataservices) + +$(call ril-set-path-variant,ril) +$(call wlan-set-path-variant,wlan-caf) +$(call bt-vendor-set-path-variant,bt-caf) +endif # AOSP_VARIANT_MAKEFILE + +else + +$(call project-set-path,qcom-audio,hardware/qcom/audio/default) +$(call project-set-path,qcom-display,hardware/qcom/display/$(TARGET_BOARD_PLATFORM)) +$(call project-set-path,qcom-media,hardware/qcom/media) + +$(call project-set-path,qcom-camera,hardware/qcom/camera) +$(call project-set-path,qcom-gps,hardware/qcom/gps) +$(call project-set-path,qcom-sensors,hardware/qcom/sensors) +$(call project-set-path,qcom-loc-api,vendor/qcom/opensource/location) +$(call project-set-path,qcom-dataservices,$(TARGET_DEVICE_DIR)/dataservices) + +$(call ril-set-path-variant,ril) +$(call wlan-set-path-variant,wlan) +$(call bt-vendor-set-path-variant,bt) + +endif diff --git a/build/core/qcom_utils.mk b/build/core/qcom_utils.mk new file mode 100755 index 00000000..50e0b4e0 --- /dev/null +++ b/build/core/qcom_utils.mk @@ -0,0 +1,230 @@ +# Board platforms lists to be used for +# TARGET_BOARD_PLATFORM specific featurization +QCOM_BOARD_PLATFORMS += msm7x27a +QCOM_BOARD_PLATFORMS += msm7x30 +QCOM_BOARD_PLATFORMS += msm8226 +QCOM_BOARD_PLATFORMS += msm8610 +QCOM_BOARD_PLATFORMS += msm8660 +QCOM_BOARD_PLATFORMS += msm8909 +QCOM_BOARD_PLATFORMS += msm8916 +QCOM_BOARD_PLATFORMS += msm8960 +QCOM_BOARD_PLATFORMS += msm8974 +QCOM_BOARD_PLATFORMS += mpq8092 +QCOM_BOARD_PLATFORMS += msm8937 +QCOM_BOARD_PLATFORMS += msm8952 +QCOM_BOARD_PLATFORMS += msm8953 +QCOM_BOARD_PLATFORMS += msm8992 +QCOM_BOARD_PLATFORMS += msm8994 +QCOM_BOARD_PLATFORMS += msm8996 +QCOM_BOARD_PLATFORMS += msm_bronze +QCOM_BOARD_PLATFORMS += apq8084 + +MSM7K_BOARD_PLATFORMS := msm7x30 +MSM7K_BOARD_PLATFORMS += msm7x27 +MSM7K_BOARD_PLATFORMS += msm7x27a +MSM7K_BOARD_PLATFORMS += msm7k + +QSD8K_BOARD_PLATFORMS := qsd8k + + +# vars for use by utils +empty := +space := $(empty) $(empty) +colon := $(empty):$(empty) +underscore := $(empty)_$(empty) + +# $(call match-word,w1,w2) +# checks if w1 == w2 +# How it works +# if (w1-w2 not empty or w2-w1 not empty) then not_match else match +# +# returns true or empty +#$(warning :$(1): :$(2): :$(subst $(1),,$(2)):) \ +#$(warning :$(2): :$(1): :$(subst $(2),,$(1)):) \ +# +define match-word +$(strip \ + $(if $(or $(subst $(1),$(empty),$(2)),$(subst $(2),$(empty),$(1))),,true) \ +) +endef + +# $(call find-word-in-list,w,wlist) +# finds an exact match of word w in word list wlist +# +# How it works +# fill wlist spaces with colon +# wrap w with colon +# search word w in list wl, if found match m, return stripped word w +# +# returns stripped word or empty +define find-word-in-list +$(strip \ + $(eval wl:= $(colon)$(subst $(space),$(colon),$(strip $(2)))$(colon)) \ + $(eval w:= $(colon)$(strip $(1))$(colon)) \ + $(eval m:= $(findstring $(w),$(wl))) \ + $(if $(m),$(1),) \ +) +endef + +# $(call match-word-in-list,w,wlist) +# does an exact match of word w in word list wlist +# How it works +# if the input word is not empty +# return output of an exact match of word w in wordlist wlist +# else +# return empty +# returns true or empty +define match-word-in-list +$(strip \ + $(if $(strip $(1)), \ + $(call match-word,$(call find-word-in-list,$(1),$(2)),$(strip $(1))), \ + ) \ +) +endef + +# $(call match-prefix,p,delim,w/wlist) +# matches prefix p in wlist using delimiter delim +# +# How it works +# trim the words in wlist w +# if find-word-in-list returns not empty +# return true +# else +# return empty +# +define match-prefix +$(strip \ + $(eval w := $(strip $(1)$(strip $(2)))) \ + $(eval text := $(patsubst $(w)%,$(1),$(3))) \ + $(if $(call match-word-in-list,$(1),$(text)),true,) \ +) +endef + +# ---- +# The following utilities are meant for board platform specific +# featurisation + +# $(call get-vendor-board-platforms,v) +# returns list of board platforms for vendor v +define get-vendor-board-platforms +$(if $(call match-word,$(BOARD_USES_$(1)_HARDWARE),true),$($(1)_BOARD_PLATFORMS)) +endef + +# $(call is-board-platform,bp) +# returns true or empty +define is-board-platform +$(call match-word,$(1),$(TARGET_BOARD_PLATFORM)) +endef + +# $(call is-not-board-platform,bp) +# returns true or empty +define is-not-board-platform +$(if $(call match-word,$(1),$(TARGET_BOARD_PLATFORM)),,true) +endef + +# $(call is-board-platform-in-list,bpl) +# returns true or empty +define is-board-platform-in-list +$(call match-word-in-list,$(TARGET_BOARD_PLATFORM),$(1)) +endef + +# $(call is-vendor-board-platform,vendor) +# returns true or empty +define is-vendor-board-platform +$(strip \ + $(call match-word-in-list,$(TARGET_BOARD_PLATFORM),\ + $(call get-vendor-board-platforms,$(1)) \ + ) \ +) +endef + +# $(call is-chipset-in-board-platform,chipset) +# does a prefix match of chipset in TARGET_BOARD_PLATFORM +# uses underscore as a delimiter +# +# returns true or empty +define is-chipset-in-board-platform +$(call match-prefix,$(1),$(underscore),$(TARGET_BOARD_PLATFORM)) +endef + +# $(call is-chipset-prefix-in-board-platform,prefix) +# does a chipset prefix match in TARGET_BOARD_PLATFORM +# assumes '_' and 'a' as the delimiter to the chipset prefix +# +# How it works +# if ($(prefix)_ or $(prefix)a match in board platform) +# return true +# else +# return empty +# +define is-chipset-prefix-in-board-platform +$(strip \ + $(eval delim_a := $(empty)a$(empty)) \ + $(if \ + $(or \ + $(call match-prefix,$(1),$(delim_a),$(TARGET_BOARD_PLATFORM)), \ + $(call match-prefix,$(1),$(underscore),$(TARGET_BOARD_PLATFORM)), \ + ), \ + true, \ + ) \ +) +endef + +#---- +# The following utilities are meant for Android Code Name +# specific featurisation +# +# refer http://source.android.com/source/build-numbers.html +# for code names and associated sdk versions +CUPCAKE_SDK_VERSIONS := 3 +DONUT_SDK_VERSIONS := 4 +ECLAIR_SDK_VERSIONS := 5 6 7 +FROYO_SDK_VERSIONS := 8 +GINGERBREAD_SDK_VERSIONS := 9 10 +HONEYCOMB_SDK_VERSIONS := 11 12 13 +ICECREAM_SANDWICH_SDK_VERSIONS := 14 15 +JELLY_BEAN_SDK_VERSIONS := 16 17 18 + +# $(call is-platform-sdk-version-at-least,version) +# version is a numeric SDK_VERSION defined above +define is-platform-sdk-version-at-least +$(strip \ + $(if $(filter 1,$(shell echo "$$(( $(PLATFORM_SDK_VERSION) >= $(1) ))" )), \ + true, \ + ) \ +) +endef + +# $(call is-android-codename,codename) +# codename is one of cupcake,donut,eclair,froyo,gingerbread,icecream +# please refer the $(codename)_SDK_VERSIONS declared above +define is-android-codename +$(strip \ + $(if \ + $(call match-word-in-list,$(PLATFORM_SDK_VERSION),$($(1)_SDK_VERSIONS)), \ + true, \ + ) \ +) +endef + +# $(call is-android-codename-in-list,cnlist) +# cnlist is combination/list of android codenames +define is-android-codename-in-list +$(strip \ + $(eval acn := $(empty)) \ + $(foreach \ + i,$(1),\ + $(eval acn += \ + $(if \ + $(call \ + match-word-in-list,\ + $(PLATFORM_SDK_VERSION),\ + $($(i)_SDK_VERSIONS)\ + ),\ + true,\ + )\ + )\ + ) \ + $(if $(strip $(acn)),true,) \ +) +endef diff --git a/build/envsetup.sh b/build/envsetup.sh new file mode 100644 index 00000000..f534eb8f --- /dev/null +++ b/build/envsetup.sh @@ -0,0 +1,931 @@ +function __print_cm_functions_help() { +cat < /dev/null` + do + echo "including $f" + . $f + done + unset f + + if [ $# -eq 0 ]; then + # No arguments, so let's have the full menu + lunch + else + echo "z$target" | grep -q "-" + if [ $? -eq 0 ]; then + # A buildtype was specified, assume a full device name + lunch $target + else + # This is probably just the CM model name + if [ -z "$variant" ]; then + variant="userdebug" + fi + lunch cm_$target-$variant + fi + fi + return $? +} + +alias bib=breakfast + +function eat() +{ + if [ "$OUT" ] ; then + MODVERSION=$(get_build_var CM_VERSION) + ZIPFILE=cm-$MODVERSION.zip + ZIPPATH=$OUT/$ZIPFILE + if [ ! -f $ZIPPATH ] ; then + echo "Nothing to eat" + return 1 + fi + adb start-server # Prevent unexpected starting server message from adb get-state in the next line + if [ $(adb get-state) != device -a $(adb shell test -e /sbin/recovery 2> /dev/null; echo $?) != 0 ] ; then + echo "No device is online. Waiting for one..." + echo "Please connect USB and/or enable USB debugging" + until [ $(adb get-state) = device -o $(adb shell test -e /sbin/recovery 2> /dev/null; echo $?) = 0 ];do + sleep 1 + done + echo "Device Found.." + fi + if (adb shell getprop ro.cm.device | grep -q "$CM_BUILD"); + then + # if adbd isn't root we can't write to /cache/recovery/ + adb root + sleep 1 + adb wait-for-device + cat << EOF > /tmp/command +--sideload_auto_reboot +EOF + if adb push /tmp/command /cache/recovery/ ; then + echo "Rebooting into recovery for sideload installation" + adb reboot recovery + adb wait-for-sideload + adb sideload $ZIPPATH + fi + rm /tmp/command + else + echo "Nothing to eat" + return 1 + fi + return $? + else + echo "The connected device does not appear to be $CM_BUILD, run away!" + fi +} + +function omnom() +{ + brunch $* + eat +} + +function cout() +{ + if [ "$OUT" ]; then + cd $OUT + else + echo "Couldn't locate out directory. Try setting OUT." + fi +} + +function dddclient() +{ + local OUT_ROOT=$(get_abs_build_var PRODUCT_OUT) + local OUT_SYMBOLS=$(get_abs_build_var TARGET_OUT_UNSTRIPPED) + local OUT_SO_SYMBOLS=$(get_abs_build_var TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED) + local OUT_VENDOR_SO_SYMBOLS=$(get_abs_build_var TARGET_OUT_VENDOR_SHARED_LIBRARIES_UNSTRIPPED) + local OUT_EXE_SYMBOLS=$(get_symbols_directory) + local PREBUILTS=$(get_abs_build_var ANDROID_PREBUILTS) + local ARCH=$(get_build_var TARGET_ARCH) + local GDB + case "$ARCH" in + arm) GDB=arm-linux-androideabi-gdb;; + arm64) GDB=arm-linux-androideabi-gdb; GDB64=aarch64-linux-android-gdb;; + mips|mips64) GDB=mips64el-linux-android-gdb;; + x86) GDB=x86_64-linux-android-gdb;; + x86_64) GDB=x86_64-linux-android-gdb;; + *) echo "Unknown arch $ARCH"; return 1;; + esac + + if [ "$OUT_ROOT" -a "$PREBUILTS" ]; then + local EXE="$1" + if [ "$EXE" ] ; then + EXE=$1 + if [[ $EXE =~ ^[^/].* ]] ; then + EXE="system/bin/"$EXE + fi + else + EXE="app_process" + fi + + local PORT="$2" + if [ "$PORT" ] ; then + PORT=$2 + else + PORT=":5039" + fi + + local PID="$3" + if [ "$PID" ] ; then + if [[ ! "$PID" =~ ^[0-9]+$ ]] ; then + PID=`pid $3` + if [[ ! "$PID" =~ ^[0-9]+$ ]] ; then + # that likely didn't work because of returning multiple processes + # try again, filtering by root processes (don't contain colon) + PID=`adb shell ps | \grep $3 | \grep -v ":" | awk '{print $2}'` + if [[ ! "$PID" =~ ^[0-9]+$ ]] + then + echo "Couldn't resolve '$3' to single PID" + return 1 + else + echo "" + echo "WARNING: multiple processes matching '$3' observed, using root process" + echo "" + fi + fi + fi + adb forward "tcp$PORT" "tcp$PORT" + local USE64BIT="$(is64bit $PID)" + adb shell gdbserver$USE64BIT $PORT --attach $PID & + sleep 2 + else + echo "" + echo "If you haven't done so already, do this first on the device:" + echo " gdbserver $PORT /system/bin/$EXE" + echo " or" + echo " gdbserver $PORT --attach " + echo "" + fi + + OUT_SO_SYMBOLS=$OUT_SO_SYMBOLS$USE64BIT + OUT_VENDOR_SO_SYMBOLS=$OUT_VENDOR_SO_SYMBOLS$USE64BIT + + echo >|"$OUT_ROOT/gdbclient.cmds" "set solib-absolute-prefix $OUT_SYMBOLS" + echo >>"$OUT_ROOT/gdbclient.cmds" "set solib-search-path $OUT_SO_SYMBOLS:$OUT_SO_SYMBOLS/hw:$OUT_SO_SYMBOLS/ssl/engines:$OUT_SO_SYMBOLS/drm:$OUT_SO_SYMBOLS/egl:$OUT_SO_SYMBOLS/soundfx:$OUT_VENDOR_SO_SYMBOLS:$OUT_VENDOR_SO_SYMBOLS/hw:$OUT_VENDOR_SO_SYMBOLS/egl" + echo >>"$OUT_ROOT/gdbclient.cmds" "source $ANDROID_BUILD_TOP/development/scripts/gdb/dalvik.gdb" + echo >>"$OUT_ROOT/gdbclient.cmds" "target remote $PORT" + # Enable special debugging for ART processes. + if [[ $EXE =~ (^|/)(app_process|dalvikvm)(|32|64)$ ]]; then + echo >> "$OUT_ROOT/gdbclient.cmds" "art-on" + fi + echo >>"$OUT_ROOT/gdbclient.cmds" "" + + local WHICH_GDB= + # 64-bit exe found + if [ "$USE64BIT" != "" ] ; then + WHICH_GDB=$ANDROID_TOOLCHAIN/$GDB64 + # 32-bit exe / 32-bit platform + elif [ "$(get_build_var TARGET_2ND_ARCH)" = "" ]; then + WHICH_GDB=$ANDROID_TOOLCHAIN/$GDB + # 32-bit exe / 64-bit platform + else + WHICH_GDB=$ANDROID_TOOLCHAIN_2ND_ARCH/$GDB + fi + + ddd --debugger $WHICH_GDB -x "$OUT_ROOT/gdbclient.cmds" "$OUT_EXE_SYMBOLS/$EXE" + else + echo "Unable to determine build system output dir." + fi +} + +function cmremote() +{ + if ! git rev-parse --git-dir &> /dev/null + then + echo ".git directory not found. Please run this from the root directory of the Android repository you wish to set up." + return 1 + fi + git remote rm cmremote 2> /dev/null + GERRIT_REMOTE=$(git config --get remote.github.projectname) + CMUSER=$(git config --get review.review.cyanogenmod.org.username) + if [ -z "$CMUSER" ] + then + git remote add cmremote ssh://review.cyanogenmod.org:29418/$GERRIT_REMOTE + else + git remote add cmremote ssh://$CMUSER@review.cyanogenmod.org:29418/$GERRIT_REMOTE + fi + echo "Remote 'cmremote' created" +} + +function aospremote() +{ + if ! git rev-parse --git-dir &> /dev/null + then + echo ".git directory not found. Please run this from the root directory of the Android repository you wish to set up." + return 1 + fi + git remote rm aosp 2> /dev/null + PROJECT=$(pwd -P | sed "s#$ANDROID_BUILD_TOP\/##") + if (echo $PROJECT | grep -qv "^device") + then + PFX="platform/" + fi + git remote add aosp https://android.googlesource.com/$PFX$PROJECT + echo "Remote 'aosp' created" +} + +function cafremote() +{ + if ! git rev-parse --git-dir &> /dev/null + then + echo ".git directory not found. Please run this from the root directory of the Android repository you wish to set up." + return 1 + fi + git remote rm caf 2> /dev/null + PROJECT=$(pwd -P | sed "s#$ANDROID_BUILD_TOP\/##") + if (echo $PROJECT | grep -qv "^device") + then + PFX="platform/" + fi + git remote add caf git://codeaurora.org/$PFX$PROJECT + echo "Remote 'caf' created" +} + +function installboot() +{ + if [ ! -e "$OUT/recovery/root/etc/recovery.fstab" ]; + then + echo "No recovery.fstab found. Build recovery first." + return 1 + fi + if [ ! -e "$OUT/boot.img" ]; + then + echo "No boot.img found. Run make bootimage first." + return 1 + fi + PARTITION=`grep "^\/boot" $OUT/recovery/root/etc/recovery.fstab | awk {'print $3'}` + if [ -z "$PARTITION" ]; + then + # Try for RECOVERY_FSTAB_VERSION = 2 + PARTITION=`grep "[[:space:]]\/boot[[:space:]]" $OUT/recovery/root/etc/recovery.fstab | awk {'print $1'}` + PARTITION_TYPE=`grep "[[:space:]]\/boot[[:space:]]" $OUT/recovery/root/etc/recovery.fstab | awk {'print $3'}` + if [ -z "$PARTITION" ]; + then + echo "Unable to determine boot partition." + return 1 + fi + fi + adb start-server + adb wait-for-online + adb root + sleep 1 + adb wait-for-online shell mount /system 2>&1 > /dev/null + adb wait-for-online remount + if (adb shell getprop ro.cm.device | grep -q "$CM_BUILD"); + then + adb push $OUT/boot.img /cache/ + for i in $OUT/system/lib/modules/*; + do + adb push $i /system/lib/modules/ + done + adb shell dd if=/cache/boot.img of=$PARTITION + adb shell chmod 644 /system/lib/modules/* + echo "Installation complete." + else + echo "The connected device does not appear to be $CM_BUILD, run away!" + fi +} + +function installrecovery() +{ + if [ ! -e "$OUT/recovery/root/etc/recovery.fstab" ]; + then + echo "No recovery.fstab found. Build recovery first." + return 1 + fi + if [ ! -e "$OUT/recovery.img" ]; + then + echo "No recovery.img found. Run make recoveryimage first." + return 1 + fi + PARTITION=`grep "^\/recovery" $OUT/recovery/root/etc/recovery.fstab | awk {'print $3'}` + if [ -z "$PARTITION" ]; + then + # Try for RECOVERY_FSTAB_VERSION = 2 + PARTITION=`grep "[[:space:]]\/recovery[[:space:]]" $OUT/recovery/root/etc/recovery.fstab | awk {'print $1'}` + PARTITION_TYPE=`grep "[[:space:]]\/recovery[[:space:]]" $OUT/recovery/root/etc/recovery.fstab | awk {'print $3'}` + if [ -z "$PARTITION" ]; + then + echo "Unable to determine recovery partition." + return 1 + fi + fi + adb start-server + adb wait-for-online + adb root + sleep 1 + adb wait-for-online shell mount /system 2>&1 >> /dev/null + adb wait-for-online remount + if (adb shell getprop ro.cm.device | grep -q "$CM_BUILD"); + then + adb push $OUT/recovery.img /cache/ + adb shell dd if=/cache/recovery.img of=$PARTITION + echo "Installation complete." + else + echo "The connected device does not appear to be $CM_BUILD, run away!" + fi +} + +function makerecipe() { + if [ -z "$1" ] + then + echo "No branch name provided." + return 1 + fi + cd android + sed -i s/'default revision=.*'/'default revision="refs\/heads\/'$1'"'/ default.xml + git commit -a -m "$1" + cd .. + + repo forall -c ' + + if [ "$REPO_REMOTE" = "github" ] + then + pwd + cmremote + git push cmremote HEAD:refs/heads/'$1' + fi + ' +} + +function cmgerrit() { + if [ "$(__detect_shell)" = "zsh" ]; then + # zsh does not define FUNCNAME, derive from funcstack + local FUNCNAME=$funcstack[1] + fi + + if [ $# -eq 0 ]; then + $FUNCNAME help + return 1 + fi + local user=`git config --get review.review.cyanogenmod.org.username` + local review=`git config --get remote.github.review` + local project=`git config --get remote.github.projectname` + local command=$1 + shift + case $command in + help) + if [ $# -eq 0 ]; then + cat <&2 "Gerrit username not found." + return 1 + fi + local local_branch remote_branch + case $1 in + *:*) + local_branch=${1%:*} + remote_branch=${1##*:} + ;; + *) + local_branch=HEAD + remote_branch=$1 + ;; + esac + shift + git push $@ ssh://$user@$review:29418/$project \ + $local_branch:refs/for/$remote_branch || return 1 + ;; + changes|for) + if [ "$FUNCNAME" = "cmgerrit" ]; then + echo >&2 "'$FUNCNAME $command' is deprecated." + fi + ;; + __cmg_err_no_arg) + if [ $# -lt 2 ]; then + echo >&2 "'$FUNCNAME $command' missing argument." + elif [ $2 -eq 0 ]; then + if [ -n "$3" ]; then + $FUNCNAME help $1 + else + echo >&2 "'$FUNCNAME $1' missing argument." + fi + else + return 1 + fi + ;; + __cmg_err_not_repo) + if [ -z "$review" -o -z "$project" ]; then + echo >&2 "Not currently in any reviewable repository." + else + return 1 + fi + ;; + __cmg_err_not_supported) + $FUNCNAME __cmg_err_no_arg $command $# && return + case $1 in + #TODO: filter more git commands that don't use refname + init|add|rm|mv|status|clone|remote|bisect|config|stash) + echo >&2 "'$FUNCNAME $1' is not supported." + ;; + *) return 1 ;; + esac + ;; + #TODO: other special cases? + *) + $FUNCNAME __cmg_err_not_supported $command && return 1 + $FUNCNAME __cmg_err_no_arg $command $# help && return 1 + $FUNCNAME __cmg_err_not_repo && return 1 + local args="$@" + local change pre_args refs_arg post_args + case "$args" in + *--\ *) + pre_args=${args%%-- *} + post_args="-- ${args#*-- }" + ;; + *) pre_args="$args" ;; + esac + args=($pre_args) + pre_args= + if [ ${#args[@]} -gt 0 ]; then + change=${args[${#args[@]}-1]} + fi + if [ ${#args[@]} -gt 1 ]; then + pre_args=${args[0]} + for ((i=1; i<${#args[@]}-1; i++)); do + pre_args="$pre_args ${args[$i]}" + done + fi + while ((1)); do + case $change in + ""|--) + $FUNCNAME help $command + return 1 + ;; + *@*) + if [ -z "$refs_arg" ]; then + refs_arg="@${change#*@}" + change=${change%%@*} + fi + ;; + *~*) + if [ -z "$refs_arg" ]; then + refs_arg="~${change#*~}" + change=${change%%~*} + fi + ;; + *^*) + if [ -z "$refs_arg" ]; then + refs_arg="^${change#*^}" + change=${change%%^*} + fi + ;; + *:*) + if [ -z "$refs_arg" ]; then + refs_arg=":${change#*:}" + change=${change%%:*} + fi + ;; + *) break ;; + esac + done + $FUNCNAME fetch $change \ + && git $command $pre_args FETCH_HEAD$refs_arg $post_args \ + || return 1 + ;; + esac +} + +function cmrebase() { + local repo=$1 + local refs=$2 + local pwd="$(pwd)" + local dir="$(gettop)/$repo" + + if [ -z $repo ] || [ -z $refs ]; then + echo "CyanogenMod Gerrit Rebase Usage: " + echo " cmrebase " + echo " The patch IDs appear on the Gerrit commands that are offered." + echo " They consist on a series of numbers and slashes, after the text" + echo " refs/changes. For example, the ID in the following command is 26/8126/2" + echo "" + echo " git[...]ges_apps_Camera refs/changes/26/8126/2 && git cherry-pick FETCH_HEAD" + echo "" + return + fi + + if [ ! -d $dir ]; then + echo "Directory $dir doesn't exist in tree." + return + fi + cd $dir + repo=$(cat .git/config | grep git://github.com | awk '{ print $NF }' | sed s#git://github.com/##g) + echo "Starting branch..." + repo start tmprebase . + echo "Bringing it up to date..." + repo sync . + echo "Fetching change..." + git fetch "http://review.cyanogenmod.org/p/$repo" "refs/changes/$refs" && git cherry-pick FETCH_HEAD + if [ "$?" != "0" ]; then + echo "Error cherry-picking. Not uploading!" + return + fi + echo "Uploading..." + repo upload . + echo "Cleaning up..." + repo abandon tmprebase . + cd $pwd +} + +function mka() { + local T=$(gettop) + if [ "$T" ]; then + case `uname -s` in + Darwin) + make -C $T -j `sysctl hw.ncpu|cut -d" " -f2` "$@" + ;; + *) + mk_timer schedtool -B -n 1 -e ionice -n 1 make -C $T -j$(cat /proc/cpuinfo | grep "^processor" | wc -l) "$@" + ;; + esac + + else + echo "Couldn't locate the top of the tree. Try setting TOP." + fi +} + +function cmka() { + if [ ! -z "$1" ]; then + for i in "$@"; do + case $i in + bacon|otapackage|systemimage) + mka installclean + mka $i + ;; + *) + mka clean-$i + mka $i + ;; + esac + done + else + mka clean + mka + fi +} + +function mms() { + local T=$(gettop) + if [ -z "$T" ] + then + echo "Couldn't locate the top of the tree. Try setting TOP." + return 1 + fi + + case `uname -s` in + Darwin) + local NUM_CPUS=$(sysctl hw.ncpu|cut -d" " -f2) + ONE_SHOT_MAKEFILE="__none__" \ + make -C $T -j $NUM_CPUS "$@" + ;; + *) + local NUM_CPUS=$(cat /proc/cpuinfo | grep "^processor" | wc -l) + ONE_SHOT_MAKEFILE="__none__" \ + mk_timer schedtool -B -n 1 -e ionice -n 1 \ + make -C $T -j $NUM_CPUS "$@" + ;; + esac +} + +function repolastsync() { + RLSPATH="$ANDROID_BUILD_TOP/.repo/.repo_fetchtimes.json" + RLSLOCAL=$(date -d "$(stat -c %z $RLSPATH)" +"%e %b %Y, %T %Z") + RLSUTC=$(date -d "$(stat -c %z $RLSPATH)" -u +"%e %b %Y, %T %Z") + echo "Last repo sync: $RLSLOCAL / $RLSUTC" +} + +function reposync() { + case `uname -s` in + Darwin) + repo sync -j 4 "$@" + ;; + *) + schedtool -B -n 1 -e ionice -n 1 `which repo` sync -j 4 "$@" + ;; + esac +} + +function repodiff() { + if [ -z "$*" ]; then + echo "Usage: repodiff [[ref-to] [--numstat]]" + return + fi + diffopts=$* repo forall -c \ + 'echo "$REPO_PATH ($REPO_REMOTE)"; git diff ${diffopts} 2>/dev/null ;' +} + +# Return success if adb is up and not in recovery +function _adb_connected { + { + if [[ "$(adb get-state)" == device && + "$(adb shell test -e /sbin/recovery; echo $?)" == 0 ]] + then + return 0 + fi + } 2>/dev/null + + return 1 +}; + +# Credit for color strip sed: http://goo.gl/BoIcm +function dopush() +{ + local func=$1 + shift + + adb start-server # Prevent unexpected starting server message from adb get-state in the next line + if ! _adb_connected; then + echo "No device is online. Waiting for one..." + echo "Please connect USB and/or enable USB debugging" + until _adb_connected; do + sleep 1 + done + echo "Device Found." + fi + + if (adb shell getprop ro.cm.device | grep -q "$CM_BUILD") || [ "$FORCE_PUSH" = "true" ]; + then + # retrieve IP and PORT info if we're using a TCP connection + TCPIPPORT=$(adb devices | egrep '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+[^0-9]+' \ + | head -1 | awk '{print $1}') + adb root &> /dev/null + sleep 0.3 + if [ -n "$TCPIPPORT" ] + then + # adb root just killed our connection + # so reconnect... + adb connect "$TCPIPPORT" + fi + adb wait-for-device &> /dev/null + sleep 0.3 + adb remount &> /dev/null + + mkdir -p $OUT + ($func $*|tee $OUT/.log;return ${PIPESTATUS[0]}) + ret=$?; + if [ $ret -ne 0 ]; then + rm -f $OUT/.log;return $ret + fi + + # Install: + if [ `uname` = "Linux" ]; then + LOC="$(cat $OUT/.log | sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' | grep '^Install: ' | cut -d ':' -f 2)" + else + LOC="$(cat $OUT/.log | sed -E "s/"$'\E'"\[([0-9]{1,3}((;[0-9]{1,3})*)?)?[m|K]//g" | grep '^Install: ' | cut -d ':' -f 2)" + fi + + # Copy: + if [ `uname` = "Linux" ]; then + LOC="$LOC $(cat $OUT/.log | sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' | grep '^Copy: ' | cut -d ':' -f 2)" + else + LOC="$LOC $(cat $OUT/.log | sed -E "s/"$'\E'"\[([0-9]{1,3}((;[0-9]{1,3})*)?)?[m|K]//g" | grep '^Copy: ' | cut -d ':' -f 2)" + fi + + # If any files are going to /data, push an octal file permissions reader to device + if [ -n "$(echo $LOC | egrep '(^|\s)/data')" ]; then + CHKPERM="/data/local/tmp/chkfileperm.sh" +( +cat <<'EOF' +#!/system/xbin/sh +FILE=$@ +if [ -e $FILE ]; then + ls -l $FILE | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf("%0o ",k);print}' | cut -d ' ' -f1 +fi +EOF +) > $OUT/.chkfileperm.sh + echo "Pushing file permissions checker to device" + adb push $OUT/.chkfileperm.sh $CHKPERM + adb shell chmod 755 $CHKPERM + rm -f $OUT/.chkfileperm.sh + fi + + stop_n_start=false + for FILE in $(echo $LOC | tr " " "\n"); do + # Make sure file is in $OUT/system or $OUT/data + case $FILE in + $OUT/system/*|$OUT/data/*) + # Get target file name (i.e. /system/bin/adb) + TARGET=$(echo $FILE | sed "s#$OUT##") + ;; + *) continue ;; + esac + + case $TARGET in + /data/*) + # fs_config only sets permissions and se labels for files pushed to /system + if [ -n "$CHKPERM" ]; then + OLDPERM=$(adb shell $CHKPERM $TARGET) + OLDPERM=$(echo $OLDPERM | tr -d '\r' | tr -d '\n') + OLDOWN=$(adb shell ls -al $TARGET | awk '{print $2}') + OLDGRP=$(adb shell ls -al $TARGET | awk '{print $3}') + fi + echo "Pushing: $TARGET" + adb push $FILE $TARGET + if [ -n "$OLDPERM" ]; then + echo "Setting file permissions: $OLDPERM, $OLDOWN":"$OLDGRP" + adb shell chown "$OLDOWN":"$OLDGRP" $TARGET + adb shell chmod "$OLDPERM" $TARGET + else + echo "$TARGET did not exist previously, you should set file permissions manually" + fi + adb shell restorecon "$TARGET" + ;; + /system/priv-app/SystemUI/SystemUI.apk|/system/framework/*) + # Only need to stop services once + if ! $stop_n_start; then + adb shell stop + stop_n_start=true + fi + echo "Pushing: $TARGET" + adb push $FILE $TARGET + ;; + *) + echo "Pushing: $TARGET" + adb push $FILE $TARGET + ;; + esac + done + if [ -n "$CHKPERM" ]; then + adb shell rm $CHKPERM + fi + if $stop_n_start; then + adb shell start + fi + rm -f $OUT/.log + return 0 + else + echo "The connected device does not appear to be $CM_BUILD, run away!" + fi +} + +alias mmp='dopush mm' +alias mmmp='dopush mmm' +alias mmap='dopush mma' +alias mkap='dopush mka' +alias cmkap='dopush cmka' + +function repopick() { + T=$(gettop) + $T/vendor/cm/build/tools/repopick.py $@ +} + +function fixup_common_out_dir() { + common_out_dir=$(get_build_var OUT_DIR)/target/common + target_device=$(get_build_var TARGET_DEVICE) + if [ ! -z $CM_FIXUP_COMMON_OUT ]; then + if [ -d ${common_out_dir} ] && [ ! -L ${common_out_dir} ]; then + mv ${common_out_dir} ${common_out_dir}-${target_device} + ln -s ${common_out_dir}-${target_device} ${common_out_dir} + else + [ -L ${common_out_dir} ] && rm ${common_out_dir} + mkdir -p ${common_out_dir}-${target_device} + ln -s ${common_out_dir}-${target_device} ${common_out_dir} + fi + else + [ -L ${common_out_dir} ] && rm ${common_out_dir} + mkdir -p ${common_out_dir} + fi +} diff --git a/build/target/product/security/cm-devkey.x509.pem b/build/target/product/security/cm-devkey.x509.pem new file mode 100644 index 00000000..b7a6ae40 --- /dev/null +++ b/build/target/product/security/cm-devkey.x509.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID1TCCAr2gAwIBAgIJANO67t8hIti6MA0GCSqGSIb3DQEBBQUAMIGAMQswCQYD +VQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEX +MBUGA1UECgwOQ3lhbm9nZW4sIEluYy4xGzAZBgNVBAsMElJlbGVhc2UgTWFuYWdl +bWVudDEUMBIGA1UEAwwLRGV2ZWxvcG1lbnQwHhcNMTQwNDI4MjAyODM3WhcNNDEw +OTEzMjAyODM3WjCBgDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24x +EDAOBgNVBAcMB1NlYXR0bGUxFzAVBgNVBAoMDkN5YW5vZ2VuLCBJbmMuMRswGQYD +VQQLDBJSZWxlYXNlIE1hbmFnZW1lbnQxFDASBgNVBAMMC0RldmVsb3BtZW50MIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz/V9RvYnr18fraPWNeQEZNeg +Kc0A3QskImQyGY22EGBZ63KUxa6zAfAug0OYSjofVJRaTtdvBXjO/C71XZRh4wun +xhOUAJt8zIJ0lRx8GMC0GHzePEnEVvoiu3zSAPHCNf5lmdhyhccMOtC18J+evPf4 +EVBb3cis+F1m6ZoZKPgSFBR5A9CV5Tai8iiZluGGg15Wt12Rp2vmbmQxiOJZxBs4 +Ps40XR5gjO1q4R3HiGnFyql9qeecwaTUWXAd76lhNiLUr7K8IRs+96i+t5vSKajB +M8O99BtYyBtf8ItMnHSZJxtsMw+TFXNLmMtaQarpsjp0LLGuHb/vsrjgBPvzsQID +AQABo1AwTjAdBgNVHQ4EFgQUTpNgXBqV7j+33bi8B80YLQq6EL8wHwYDVR0jBBgw +FoAUTpNgXBqV7j+33bi8B80YLQq6EL8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B +AQUFAAOCAQEAVlVBNksK+1C3J8uQ9kVemYMozfbboV9c4PLbtVzNSO8vwZ3X5E4T +2zfQPcFsfSMIa51a1tETBcDA6k+72xHZ+xEQJQNrX+o1F1RIIrXp0OKAz/k5cXyk +OS0+nd0EXP/A1EW0m8N/X6E9wpRkIhfqtEsqeCf8GH7O9Ua2qHZ9zkTBpbAVH0oe +ZWorHBdo3GdMJ5vcjFqnDdRs8F0BnZmjS+NrgXRLhLb6ZARS/bkUQyr5TX82dgG6 +vzvKsdKyX34gsKAsjxwLWo7XXgehFfjY+SGjjilJtardr+y/KlHNEw9s9aLe+Xny +Qoa9j9Ut6/KwRaC6lSEQ7HZk6SdzFsdugA== +-----END CERTIFICATE----- diff --git a/build/target/product/security/cm.x509.pem b/build/target/product/security/cm.x509.pem new file mode 100644 index 00000000..5ff19db7 --- /dev/null +++ b/build/target/product/security/cm.x509.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDZDCCAkygAwIBAgIEUfbexjANBgkqhkiG9w0BAQUFADB0MQswCQYDVQQGEwJV +UzELMAkGA1UECBMCV0ExEDAOBgNVBAcTB1NlYXR0bGUxFjAUBgNVBAoTDUN5YW5v +Z2VuIEluYy4xFjAUBgNVBAsTDUN5YW5vZ2VuIEluYy4xFjAUBgNVBAMTDUN5YW5v +Z2VuIEluYy4wHhcNMTMwNzI5MjEyOTQyWhcNNDAxMjE0MjEyOTQyWjB0MQswCQYD +VQQGEwJVUzELMAkGA1UECBMCV0ExEDAOBgNVBAcTB1NlYXR0bGUxFjAUBgNVBAoT +DUN5YW5vZ2VuIEluYy4xFjAUBgNVBAsTDUN5YW5vZ2VuIEluYy4xFjAUBgNVBAMT +DUN5YW5vZ2VuIEluYy4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCP ++K2NPqdZ6UmexXQ8tsc2TkLXYhiuEsifO66qlpwsTTw1522HcbKPVoPRr/JBXqOv +E3K0HuZ/IsYYGsP/wJWWvpaWs+5xC+YkLkittK2uUzTqndpLFiDRAeICKpvDJI57 +Z0DkzVYXBPn+yw+x8ttjT/vWcJ3PEVYuew8MYPUOgKpdZlQtUBeoEBDSL8JPGViq +e6jWOlSAWekhlgb+wb9RoXhu/v2HYzp89GG0sIrAgj7vZCior5XuFmm8eWhqUhTp +TUBv/nNI/ORYt3G8IQyI2pJN1GNPAAv1uA5i4y/deX1x4GCWyN9feiD9fOj2oc3z +Hwf5Frs9BjOb9XMXecbNAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAGudhFe9VnES +fWynTYO4kWNlMC++yB6qD3pHW6HtBiaANj9wxrLCTFzf+boHNPeZ8HDkW01zAaQK +fd9/fnGmHf4q/QvxrvGbnb3Fqhw+2hknbbMUoAa+Qp+2ouf9oJaNRquZ+rHEHX8g +Rx8wGyvjaWYfQrwyZRgXj/Jrc/NXxQCmSJeexHVNXgQD6aOLHJYrJ+s+U/hwVNiM +5L+psOh89itwt8DGGSLW16HjQKmPPbWbqxgnfRbOlxWrLDq3agcrskYpDP2aGGBA +5STq/bvh9yZkrNYvMGzrXDhcJ44QRS8e1Jw/ZtfFvJD192e7KKVdy7CJWmOckCNK +gl0KCQ3MBx4= +-----END CERTIFICATE----- diff --git a/build/tasks/dt_image.mk b/build/tasks/dt_image.mk new file mode 100644 index 00000000..0f849466 --- /dev/null +++ b/build/tasks/dt_image.mk @@ -0,0 +1,53 @@ +#---------------------------------------------------------------------- +# Generate device tree image (dt.img) +#---------------------------------------------------------------------- +ifeq ($(strip $(BOARD_CUSTOM_BOOTIMG_MK)),) +ifeq ($(strip $(BOARD_KERNEL_SEPARATED_DT)),true) +ifneq ($(strip $(BOARD_KERNEL_PREBUILT_DT)),true) +ifeq ($(strip $(BUILD_TINY_ANDROID)),true) +include device/qcom/common/dtbtool/Android.mk +endif + +ifeq ($(strip $(TARGET_CUSTOM_DTBTOOL)),) +DTBTOOL_NAME := dtbToolCM +else +DTBTOOL_NAME := $(TARGET_CUSTOM_DTBTOOL) +endif + +DTBTOOL := $(HOST_OUT_EXECUTABLES)/$(DTBTOOL_NAME)$(HOST_EXECUTABLE_SUFFIX) + +INSTALLED_DTIMAGE_TARGET := $(PRODUCT_OUT)/dt.img + +ifeq ($(strip $(TARGET_CUSTOM_DTBTOOL)),) +# dtbToolCM will search subdirectories +possible_dtb_dirs = $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/ +else +# Most specific paths must come first in possible_dtb_dirs +possible_dtb_dirs = $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/dts/ $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/ +endif + +define build-dtimage-target + $(call pretty,"Target dt image: $@") + $(hide) for dir in $(possible_dtb_dirs); do \ + if [ -d "$$dir" ]; then \ + dtb_dir="$$dir"; \ + break; \ + fi; \ + done; \ + $(DTBTOOL) $(BOARD_DTBTOOL_ARGS) -o $@ -s $(BOARD_KERNEL_PAGESIZE) -p $(KERNEL_OUT)/scripts/dtc/ "$$dtb_dir"; + $(hide) chmod a+r $@ +endef + +$(INSTALLED_DTIMAGE_TARGET): $(DTBTOOL) $(INSTALLED_KERNEL_TARGET) + $(build-dtimage-target) + @echo "Made DT image: $@" + +ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_DTIMAGE_TARGET) +ALL_MODULES.$(LOCAL_MODULE).INSTALLED += $(INSTALLED_DTIMAGE_TARGET) + +.PHONY: dtimage +dtimage: $(INSTALLED_DTIMAGE_TARGET) + +endif +endif +endif diff --git a/build/tasks/kernel.mk b/build/tasks/kernel.mk new file mode 100644 index 00000000..527fb543 --- /dev/null +++ b/build/tasks/kernel.mk @@ -0,0 +1,373 @@ +# Copyright (C) 2012 The CyanogenMod Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Android makefile to build kernel as a part of Android Build +# +# Configuration +# ============= +# +# These config vars are usually set in BoardConfig.mk: +# +# TARGET_KERNEL_SOURCE = Kernel source dir, optional, defaults +# to kernel/$(TARGET_DEVICE_DIR) +# TARGET_KERNEL_CONFIG = Kernel defconfig +# TARGET_KERNEL_VARIANT_CONFIG = Variant defconfig, optional +# TARGET_KERNEL_SELINUX_CONFIG = SELinux defconfig, optional +# TARGET_KERNEL_ADDITIONAL_CONFIG = Additional defconfig, optional +# TARGET_KERNEL_ARCH = Kernel Arch +# TARGET_KERNEL_HEADER_ARCH = Optional Arch for kernel headers if +# different from TARGET_KERNEL_ARCH +# TARGET_USES_UNCOMPRESSED_KERNEL = 'true' if Kernel is uncompressed, +# optional, defaults to false +# TARGET_KERNEL_CROSS_COMPILE_PREFIX = Compiler prefix (e.g. arm-eabi-) +# defaults to arm-linux-androideabi- for arm +# aarch64-linux-android- for arm64 +# x86_64-linux-android- for x86 +# +# BOARD_KERNEL_IMAGE_NAME = Built image name, optional, +# defaults to Image.gz on arm64 +# defaults to Image if TARGET_USES_UNCOMPRESSED_KERNEL +# defaults to zImage otherwise +# +# KERNEL_TOOLCHAIN_PREFIX = Overrides TARGET_KERNEL_CROSS_COMPILE_PREFIX, +# Set this var in shell to override +# toolchain specified in BoardConfig.mk +# KERNEL_TOOLCHAIN = Path to toolchain, if unset, assumes +# TARGET_KERNEL_CROSS_COMPILE_PREFIX +# is in PATH +# USE_CCACHE = Enable ccache (global Android flag) +# +# NEED_KERNEL_MODULE_ROOT = Optional, if true, install kernel +# modules in root instead of system + + +TARGET_AUTO_KDIR := $(shell echo $(TARGET_DEVICE_DIR) | sed -e 's/^device/kernel/g') + +## Externally influenced variables +# kernel location - optional, defaults to kernel// +TARGET_KERNEL_SOURCE ?= $(TARGET_AUTO_KDIR) +KERNEL_SRC := $(TARGET_KERNEL_SOURCE) +# kernel configuration - mandatory +KERNEL_DEFCONFIG := $(TARGET_KERNEL_CONFIG) +VARIANT_DEFCONFIG := $(TARGET_KERNEL_VARIANT_CONFIG) +SELINUX_DEFCONFIG := $(TARGET_KERNEL_SELINUX_CONFIG) + +## Internal variables +KERNEL_OUT := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ +KERNEL_CONFIG := $(KERNEL_OUT)/.config +KERNEL_OUT_STAMP := $(KERNEL_OUT)/.mkdir_stamp + +TARGET_KERNEL_ARCH := $(strip $(TARGET_KERNEL_ARCH)) +ifeq ($(TARGET_KERNEL_ARCH),) +KERNEL_ARCH := $(TARGET_ARCH) +else +KERNEL_ARCH := $(TARGET_KERNEL_ARCH) +endif + +ifeq ($(KERNEL_ARCH),x86_64) +KERNEL_DEFCONFIG_ARCH := x86 +else +KERNEL_DEFCONFIG_ARCH := $(KERNEL_ARCH) +endif +KERNEL_DEFCONFIG_SRC := $(KERNEL_SRC)/arch/$(KERNEL_DEFCONFIG_ARCH)/configs/$(KERNEL_DEFCONFIG) + +TARGET_KERNEL_HEADER_ARCH := $(strip $(TARGET_KERNEL_HEADER_ARCH)) +ifeq ($(TARGET_KERNEL_HEADER_ARCH),) +KERNEL_HEADER_ARCH := $(KERNEL_ARCH) +else +KERNEL_HEADER_ARCH := $(TARGET_KERNEL_HEADER_ARCH) +endif + +KERNEL_HEADER_DEFCONFIG := $(strip $(KERNEL_HEADER_DEFCONFIG)) +ifeq ($(KERNEL_HEADER_DEFCONFIG),) +KERNEL_HEADER_DEFCONFIG := $(KERNEL_DEFCONFIG) +endif + + +ifneq ($(BOARD_KERNEL_IMAGE_NAME),) + TARGET_PREBUILT_INT_KERNEL_TYPE := $(BOARD_KERNEL_IMAGE_NAME) +else + ifeq ($(TARGET_USES_UNCOMPRESSED_KERNEL),true) + TARGET_PREBUILT_INT_KERNEL_TYPE := Image + else + ifeq ($(KERNEL_ARCH),arm64) + TARGET_PREBUILT_INT_KERNEL_TYPE := Image.gz + else + TARGET_PREBUILT_INT_KERNEL_TYPE := zImage + endif + endif +endif + +TARGET_PREBUILT_INT_KERNEL := $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/$(TARGET_PREBUILT_INT_KERNEL_TYPE) + +# Clear this first to prevent accidental poisoning from env +MAKE_FLAGS := + +ifeq ($(KERNEL_ARCH),arm64) + # Avoid "unsupported RELA relocation: 311" errors (R_AARCH64_ADR_GOT_PAGE) + MAKE_FLAGS += CFLAGS_MODULE="-fno-pic" + ifeq ($(TARGET_ARCH),arm) + KERNEL_CONFIG_OVERRIDE := CONFIG_ANDROID_BINDER_IPC_32BIT=y + endif +endif + +ifneq ($(TARGET_KERNEL_ADDITIONAL_CONFIG),) +KERNEL_ADDITIONAL_CONFIG := $(TARGET_KERNEL_ADDITIONAL_CONFIG) +KERNEL_ADDITIONAL_CONFIG_SRC := $(KERNEL_SRC)/arch/$(KERNEL_ARCH)/configs/$(KERNEL_ADDITIONAL_CONFIG) + ifeq ("$(wildcard $(KERNEL_ADDITIONAL_CONFIG_SRC))","") + $(warning TARGET_KERNEL_ADDITIONAL_CONFIG '$(TARGET_KERNEL_ADDITIONAL_CONFIG)' doesn't exist) + KERNEL_ADDITIONAL_CONFIG_SRC := /dev/null + endif +else + KERNEL_ADDITIONAL_CONFIG_SRC := /dev/null +endif + +## Do be discontinued in a future version. Notify builder about target +## kernel format requirement +ifeq ($(BOARD_KERNEL_IMAGE_NAME),) +ifeq ($(BOARD_USES_UBOOT),true) + $(error "Please set BOARD_KERNEL_IMAGE_NAME to uImage") +else ifeq ($(BOARD_USES_UNCOMPRESSED_BOOT),true) + $(error "Please set BOARD_KERNEL_IMAGE_NAME to Image") +endif +endif + +ifeq "$(wildcard $(KERNEL_SRC) )" "" + ifneq ($(TARGET_PREBUILT_KERNEL),) + HAS_PREBUILT_KERNEL := true + NEEDS_KERNEL_COPY := true + else + $(foreach cf,$(PRODUCT_COPY_FILES), \ + $(eval _src := $(call word-colon,1,$(cf))) \ + $(eval _dest := $(call word-colon,2,$(cf))) \ + $(ifeq kernel,$(_dest), \ + $(eval HAS_PREBUILT_KERNEL := true))) + endif + + ifneq ($(HAS_PREBUILT_KERNEL),) + $(warning ***************************************************************) + $(warning * Using prebuilt kernel binary instead of source *) + $(warning * THIS IS DEPRECATED, AND WILL BE DISCONTINUED *) + $(warning * Please configure your device to download the kernel *) + $(warning * source repository to $(KERNEL_SRC)) + $(warning * See http://wiki.cyanogenmod.org/w/Doc:_integrated_kernel_building) + $(warning * for more information *) + $(warning ***************************************************************) + FULL_KERNEL_BUILD := false + KERNEL_BIN := $(TARGET_PREBUILT_KERNEL) + else + $(warning ***************************************************************) + $(warning * *) + $(warning * No kernel source found, and no fallback prebuilt defined. *) + $(warning * Please make sure your device is properly configured to *) + $(warning * download the kernel repository to $(KERNEL_SRC)) + $(warning * and add the TARGET_KERNEL_CONFIG variable to BoardConfig.mk *) + $(warning * *) + $(warning * As an alternative, define the TARGET_PREBUILT_KERNEL *) + $(warning * variable with the path to the prebuilt binary kernel image *) + $(warning * in your BoardConfig.mk file *) + $(warning * *) + $(warning ***************************************************************) + $(error "NO KERNEL") + endif +else + NEEDS_KERNEL_COPY := true + ifeq ($(TARGET_KERNEL_CONFIG),) + $(warning **********************************************************) + $(warning * Kernel source found, but no configuration was defined *) + $(warning * Please add the TARGET_KERNEL_CONFIG variable to your *) + $(warning * BoardConfig.mk file *) + $(warning **********************************************************) + # $(error "NO KERNEL CONFIG") + else + #$(info Kernel source found, building it) + FULL_KERNEL_BUILD := true + KERNEL_BIN := $(TARGET_PREBUILT_INT_KERNEL) + endif +endif + +ifeq ($(FULL_KERNEL_BUILD),true) + +KERNEL_HEADERS_INSTALL := $(KERNEL_OUT)/usr +KERNEL_HEADERS_INSTALL_STAMP := $(KERNEL_OUT)/.headers_install_stamp + +ifeq ($(NEED_KERNEL_MODULE_ROOT),true) +KERNEL_MODULES_INSTALL := root +KERNEL_MODULES_OUT := $(TARGET_ROOT_OUT)/lib/modules +else +KERNEL_MODULES_INSTALL := system +KERNEL_MODULES_OUT := $(TARGET_OUT)/lib/modules +endif + +TARGET_KERNEL_CROSS_COMPILE_PREFIX := $(strip $(TARGET_KERNEL_CROSS_COMPILE_PREFIX)) +ifneq ($(TARGET_KERNEL_CROSS_COMPILE_PREFIX),) +KERNEL_TOOLCHAIN_PREFIX ?= $(TARGET_KERNEL_CROSS_COMPILE_PREFIX) +else ifeq ($(TARGET_ARCH),arm64) +KERNEL_TOOLCHAIN_PREFIX ?= aarch64-linux-android- +else ifeq ($(TARGET_ARCH),arm) +KERNEL_TOOLCHAIN_PREFIX ?= arm-linux-androideabi- +else ifeq ($(TARGET_ARCH),x86) +KERNEL_TOOLCHAIN_PREFIX ?= x86_64-linux-android- +endif + +ifeq ($(KERNEL_TOOLCHAIN),) +KERNEL_TOOLCHAIN_PATH := $(KERNEL_TOOLCHAIN_PREFIX) +else +ifneq ($(KERNEL_TOOLCHAIN_PREFIX),) +KERNEL_TOOLCHAIN_PATH := $(KERNEL_TOOLCHAIN)/$(KERNEL_TOOLCHAIN_PREFIX) +endif +endif + +ifneq ($(USE_CCACHE),) + ccache := $(ANDROID_BUILD_TOP)/prebuilts/misc/$(HOST_PREBUILT_TAG)/ccache/ccache + # Check that the executable is here. + ccache := $(strip $(wildcard $(ccache))) +endif + +KERNEL_CROSS_COMPILE := CROSS_COMPILE="$(ccache) $(KERNEL_TOOLCHAIN_PATH)" +ccache = + +define mv-modules + mdpath=`find $(KERNEL_MODULES_OUT) -type f -name modules.order`;\ + if [ "$$mdpath" != "" ];then\ + mpath=`dirname $$mdpath`;\ + ko=`find $$mpath/kernel -type f -name *.ko`;\ + for i in $$ko; do $(KERNEL_TOOLCHAIN_PATH)strip --strip-unneeded $$i;\ + mv $$i $(KERNEL_MODULES_OUT)/; done;\ + fi +endef + +define clean-module-folder + mdpath=`find $(KERNEL_MODULES_OUT) -type f -name modules.order`;\ + if [ "$$mdpath" != "" ];then\ + mpath=`dirname $$mdpath`; rm -rf $$mpath;\ + fi +endef + +ifeq ($(HOST_OS),darwin) + MAKE_FLAGS += C_INCLUDE_PATH=$(ANDROID_BUILD_TOP)/external/elfutils/libelf/ +endif + +ifeq ($(TARGET_KERNEL_MODULES),) + TARGET_KERNEL_MODULES := no-external-modules +endif + +$(KERNEL_OUT_STAMP): + $(hide) mkdir -p $(KERNEL_OUT) + $(hide) rm -rf $(KERNEL_MODULES_OUT) + $(hide) mkdir -p $(KERNEL_MODULES_OUT) + $(hide) touch $@ + +KERNEL_ADDITIONAL_CONFIG_OUT := $(KERNEL_OUT)/.additional_config + +.PHONY: force_additional_config +$(KERNEL_ADDITIONAL_CONFIG_OUT): force_additional_config + $(hide) cmp -s $(KERNEL_ADDITIONAL_CONFIG_SRC) $@ || cp $(KERNEL_ADDITIONAL_CONFIG_SRC) $@; + +$(KERNEL_CONFIG): $(KERNEL_OUT_STAMP) $(KERNEL_DEFCONFIG_SRC) $(KERNEL_ADDITIONAL_CONFIG_OUT) + @echo "Building Kernel Config" + $(MAKE) $(MAKE_FLAGS) -C $(KERNEL_SRC) O=$(KERNEL_OUT) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) VARIANT_DEFCONFIG=$(VARIANT_DEFCONFIG) SELINUX_DEFCONFIG=$(SELINUX_DEFCONFIG) $(KERNEL_DEFCONFIG) + $(hide) if [ ! -z "$(KERNEL_CONFIG_OVERRIDE)" ]; then \ + echo "Overriding kernel config with '$(KERNEL_CONFIG_OVERRIDE)'"; \ + echo $(KERNEL_CONFIG_OVERRIDE) >> $(KERNEL_OUT)/.config; \ + $(MAKE) -C $(KERNEL_SRC) O=$(KERNEL_OUT) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) oldconfig; fi + $(hide) if [ ! -z "$(KERNEL_ADDITIONAL_CONFIG)" ]; then \ + echo "Using additional config '$(KERNEL_ADDITIONAL_CONFIG)'"; \ + $(KERNEL_SRC)/scripts/kconfig/merge_config.sh -m -O $(KERNEL_OUT) $(KERNEL_OUT)/.config $(KERNEL_SRC)/arch/$(KERNEL_ARCH)/configs/$(KERNEL_ADDITIONAL_CONFIG); \ + $(MAKE) -C $(KERNEL_SRC) O=$(KERNEL_OUT) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) KCONFIG_ALLCONFIG=$(KERNEL_OUT)/.config alldefconfig; fi + +TARGET_KERNEL_BINARIES: $(KERNEL_OUT_STAMP) $(KERNEL_CONFIG) $(KERNEL_HEADERS_INSTALL_STAMP) + @echo "Building Kernel" + $(MAKE) $(MAKE_FLAGS) -C $(KERNEL_SRC) O=$(KERNEL_OUT) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(TARGET_PREBUILT_INT_KERNEL_TYPE) + $(hide) if grep -q 'CONFIG_OF=y' $(KERNEL_CONFIG) ; \ + then \ + echo "Building DTBs" ; \ + $(MAKE) $(MAKE_FLAGS) -C $(KERNEL_SRC) O=$(KERNEL_OUT) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) dtbs ; \ + else \ + echo "DTBs not enabled" ; \ + fi ; + $(hide) if grep -q 'CONFIG_MODULES=y' $(KERNEL_CONFIG) ; \ + then \ + echo "Building Kernel Modules" ; \ + $(MAKE) $(MAKE_FLAGS) -C $(KERNEL_SRC) O=$(KERNEL_OUT) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) modules && \ + $(MAKE) $(MAKE_FLAGS) -C $(KERNEL_SRC) O=$(KERNEL_OUT) INSTALL_MOD_PATH=../../$(KERNEL_MODULES_INSTALL) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) modules_install && \ + $(mv-modules) && \ + $(clean-module-folder) ; \ + else \ + echo "Kernel Modules not enabled" ; \ + fi ; + + +$(TARGET_KERNEL_MODULES): TARGET_KERNEL_BINARIES + +$(TARGET_PREBUILT_INT_KERNEL): $(TARGET_KERNEL_MODULES) + $(mv-modules) + $(clean-module-folder) + +$(KERNEL_HEADERS_INSTALL_STAMP): $(KERNEL_OUT_STAMP) $(KERNEL_CONFIG) + @echo "Building Kernel Headers" + $(hide) if [ ! -z "$(KERNEL_HEADER_DEFCONFIG)" ]; then \ + rm -f ../$(KERNEL_CONFIG); \ + $(MAKE) $(MAKE_FLAGS) -C $(KERNEL_SRC) O=$(KERNEL_OUT) ARCH=$(KERNEL_HEADER_ARCH) $(KERNEL_CROSS_COMPILE) VARIANT_DEFCONFIG=$(VARIANT_DEFCONFIG) SELINUX_DEFCONFIG=$(SELINUX_DEFCONFIG) $(KERNEL_HEADER_DEFCONFIG); \ + $(MAKE) $(MAKE_FLAGS) -C $(KERNEL_SRC) O=$(KERNEL_OUT) ARCH=$(KERNEL_HEADER_ARCH) $(KERNEL_CROSS_COMPILE) headers_install; fi + $(hide) if [ "$(KERNEL_HEADER_DEFCONFIG)" != "$(KERNEL_DEFCONFIG)" ]; then \ + echo "Used a different defconfig for header generation"; \ + rm -f ../$(KERNEL_CONFIG); \ + $(MAKE) $(MAKE_FLAGS) -C $(KERNEL_SRC) O=$(KERNEL_OUT) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) VARIANT_DEFCONFIG=$(VARIANT_DEFCONFIG) SELINUX_DEFCONFIG=$(SELINUX_DEFCONFIG) $(KERNEL_DEFCONFIG); fi + $(hide) if [ ! -z "$(KERNEL_CONFIG_OVERRIDE)" ]; then \ + echo "Overriding kernel config with '$(KERNEL_CONFIG_OVERRIDE)'"; \ + echo $(KERNEL_CONFIG_OVERRIDE) >> $(KERNEL_OUT)/.config; \ + $(MAKE) $(MAKE_FLAGS) -C $(KERNEL_SRC) O=$(KERNEL_OUT) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) oldconfig; fi + $(hide) if [ ! -z "$(KERNEL_ADDITIONAL_CONFIG)" ]; then \ + echo "Using additional config '$(KERNEL_ADDITIONAL_CONFIG)'"; \ + $(KERNEL_SRC)/scripts/kconfig/merge_config.sh -m -O $(KERNEL_OUT) $(KERNEL_OUT)/.config $(KERNEL_SRC)/arch/$(KERNEL_ARCH)/configs/$(KERNEL_ADDITIONAL_CONFIG); \ + $(MAKE) $(MAKE_FLAGS) -C $(KERNEL_SRC) O=$(KERNEL_OUT) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) KCONFIG_ALLCONFIG=$(KERNEL_OUT)/.config alldefconfig; fi + $(hide) touch $@ + +# provide this rule because there are dependencies on this throughout the repo +$(KERNEL_HEADERS_INSTALL): $(KERNEL_HEADERS_INSTALL_STAMP) + +kerneltags: $(KERNEL_OUT_STAMP) $(KERNEL_CONFIG) + $(MAKE) -C $(KERNEL_SRC) O=$(KERNEL_OUT) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) tags + +kernelconfig: KERNELCONFIG_MODE := menuconfig +kernelxconfig: KERNELCONFIG_MODE := xconfig +kernelxconfig kernelconfig: $(KERNEL_OUT_STAMP) + $(MAKE) $(MAKE_FLAGS) -C $(KERNEL_SRC) O=$(KERNEL_OUT) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_DEFCONFIG) + env KCONFIG_NOTIMESTAMP=true \ + $(MAKE) -C $(KERNEL_SRC) O=$(KERNEL_OUT) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNELCONFIG_MODE) + env KCONFIG_NOTIMESTAMP=true \ + $(MAKE) -C $(KERNEL_SRC) O=$(KERNEL_OUT) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) savedefconfig + cp $(KERNEL_OUT)/defconfig $(KERNEL_DEFCONFIG_SRC) + +alldefconfig: $(KERNEL_OUT_STAMP) + env KCONFIG_NOTIMESTAMP=true \ + $(MAKE) -C $(KERNEL_SRC) O=$(KERNEL_OUT) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) alldefconfig + +endif # FULL_KERNEL_BUILD + +## Install it + +ifeq ($(NEEDS_KERNEL_COPY),true) +file := $(INSTALLED_KERNEL_TARGET) +ALL_PREBUILT += $(file) +$(file) : $(KERNEL_BIN) | $(ACP) + $(transform-prebuilt-to-target) + +ALL_PREBUILT += $(INSTALLED_KERNEL_TARGET) +endif + +.PHONY: kernel +kernel: $(INSTALLED_KERNEL_TARGET) diff --git a/build/tools/repopick.py b/build/tools/repopick.py new file mode 100755 index 00000000..5b0e065e --- /dev/null +++ b/build/tools/repopick.py @@ -0,0 +1,407 @@ +#!/usr/bin/env python +# +# Copyright (C) 2013-15 The CyanogenMod Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# +# Run repopick.py -h for a description of this utility. +# + +from __future__ import print_function + +import sys +import json +import os +import subprocess +import re +import argparse +import textwrap +from xml.etree import ElementTree + +try: + # For python3 + import urllib.error + import urllib.request +except ImportError: + # For python2 + import imp + import urllib2 + urllib = imp.new_module('urllib') + urllib.error = urllib2 + urllib.request = urllib2 + + +# Verifies whether pathA is a subdirectory (or the same) as pathB +def is_subdir(a, b): + a = os.path.realpath(a) + '/' + b = os.path.realpath(b) + '/' + return b == a[:len(b)] + + +def fetch_query_via_ssh(remote_url, query): + """Given a remote_url and a query, return the list of changes that fit it + This function is slightly messy - the ssh api does not return data in the same structure as the HTTP REST API + We have to get the data, then transform it to match what we're expecting from the HTTP RESET API""" + if remote_url.count(':') == 2: + (uri, userhost, port) = remote_url.split(':') + userhost = userhost[2:] + elif remote_url.count(':') == 1: + (uri, userhost) = remote_url.split(':') + userhost = userhost[2:] + port = 29418 + else: + raise Exception('Malformed URI: Expecting ssh://[user@]host[:port]') + + + out = subprocess.check_output(['ssh', '-x', '-p{0}'.format(port), userhost, 'gerrit', 'query', '--format=JSON --patch-sets --current-patch-set', query]) + if not hasattr(out, 'encode'): + out = out.decode() + reviews = [] + for line in out.split('\n'): + try: + data = json.loads(line) + # make our data look like the http rest api data + review = { + 'branch': data['branch'], + 'change_id': data['id'], + 'current_revision': data['currentPatchSet']['revision'], + 'number': int(data['number']), + 'revisions': {patch_set['revision']: { + 'number': int(patch_set['number']), + 'fetch': { + 'ssh': { + 'ref': patch_set['ref'], + 'url': 'ssh://{0}:{1}/{2}'.format(userhost, port, data['project']) + } + } + } for patch_set in data['patchSets']}, + 'subject': data['subject'], + 'project': data['project'], + 'status': data['status'] + } + reviews.append(review) + except: + pass + args.quiet or print('Found {0} reviews'.format(len(reviews))) + return reviews + + +def fetch_query_via_http(remote_url, query): + + """Given a query, fetch the change numbers via http""" + url = '{0}/changes/?q={1}&o=CURRENT_REVISION&o=ALL_REVISIONS'.format(remote_url, query) + data = urllib.request.urlopen(url).read().decode('utf-8') + reviews = json.loads(data[5:]) + + for review in reviews: + review['number'] = review.pop('_number') + + return reviews + + +def fetch_query(remote_url, query): + """Wrapper for fetch_query_via_proto functions""" + if remote_url[0:3] == 'ssh': + return fetch_query_via_ssh(remote_url, query) + elif remote_url[0:4] == 'http': + return fetch_query_via_http(remote_url, query.replace(' ', '+')) + else: + raise Exception('Gerrit URL should be in the form http[s]://hostname/ or ssh://[user@]host[:port]') + +if __name__ == '__main__': + # Default to CyanogenMod Gerrit + default_gerrit = 'http://review.cyanogenmod.org' + + parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, description=textwrap.dedent('''\ + repopick.py is a utility to simplify the process of cherry picking + patches from CyanogenMod's Gerrit instance (or any gerrit instance of your choosing) + + Given a list of change numbers, repopick will cd into the project path + and cherry pick the latest patch available. + + With the --start-branch argument, the user can specify that a branch + should be created before cherry picking. This is useful for + cherry-picking many patches into a common branch which can be easily + abandoned later (good for testing other's changes.) + + The --abandon-first argument, when used in conjunction with the + --start-branch option, will cause repopick to abandon the specified + branch in all repos first before performing any cherry picks.''')) + parser.add_argument('change_number', nargs='*', help='change number to cherry pick. Use {change number}/{patchset number} to get a specific revision.') + parser.add_argument('-i', '--ignore-missing', action='store_true', help='do not error out if a patch applies to a missing directory') + parser.add_argument('-s', '--start-branch', nargs=1, help='start the specified branch before cherry picking') + parser.add_argument('-a', '--abandon-first', action='store_true', help='before cherry picking, abandon the branch specified in --start-branch') + parser.add_argument('-b', '--auto-branch', action='store_true', help='shortcut to "--start-branch auto --abandon-first --ignore-missing"') + parser.add_argument('-q', '--quiet', action='store_true', help='print as little as possible') + parser.add_argument('-v', '--verbose', action='store_true', help='print extra information to aid in debug') + parser.add_argument('-f', '--force', action='store_true', help='force cherry pick even if change is closed') + parser.add_argument('-p', '--pull', action='store_true', help='execute pull instead of cherry-pick') + parser.add_argument('-P', '--path', help='use the specified path for the change') + parser.add_argument('-t', '--topic', help='pick all commits from a specified topic') + parser.add_argument('-Q', '--query', help='pick all commits using the specified query') + parser.add_argument('-g', '--gerrit', default=default_gerrit, help='Gerrit Instance to use. Form proto://[user@]host[:port]') + parser.add_argument('-e', '--exclude', nargs=1, help='exclude a list of commit numbers separated by a ,') + args = parser.parse_args() + if not args.start_branch and args.abandon_first: + parser.error('if --abandon-first is set, you must also give the branch name with --start-branch') + if args.auto_branch: + args.abandon_first = True + args.ignore_missing = True + if not args.start_branch: + args.start_branch = ['auto'] + if args.quiet and args.verbose: + parser.error('--quiet and --verbose cannot be specified together') + + if (1 << bool(args.change_number) << bool(args.topic) << bool(args.query)) != 2: + parser.error('One (and only one) of change_number, topic, and query are allowed') + + # Change current directory to the top of the tree + if 'ANDROID_BUILD_TOP' in os.environ: + top = os.environ['ANDROID_BUILD_TOP'] + + if not is_subdir(os.getcwd(), top): + sys.stderr.write('ERROR: You must run this tool from within $ANDROID_BUILD_TOP!\n') + sys.exit(1) + os.chdir(os.environ['ANDROID_BUILD_TOP']) + + # Sanity check that we are being run from the top level of the tree + if not os.path.isdir('.repo'): + sys.stderr.write('ERROR: No .repo directory found. Please run this from the top of your tree.\n') + sys.exit(1) + + # If --abandon-first is given, abandon the branch before starting + if args.abandon_first: + # Determine if the branch already exists; skip the abandon if it does not + plist = subprocess.check_output(['repo', 'info']) + if not hasattr(plist, 'encode'): + plist = plist.decode() + needs_abandon = False + for pline in plist.splitlines(): + matchObj = re.match(r'Local Branches.*\[(.*)\]', pline) + if matchObj: + local_branches = re.split('\s*,\s*', matchObj.group(1)) + if any(args.start_branch[0] in s for s in local_branches): + needs_abandon = True + + if needs_abandon: + # Perform the abandon only if the branch already exists + if not args.quiet: + print('Abandoning branch: %s' % args.start_branch[0]) + subprocess.check_output(['repo', 'abandon', args.start_branch[0]]) + if not args.quiet: + print('') + + # Get the master manifest from repo + # - convert project name and revision to a path + project_name_to_data = {} + manifest = subprocess.check_output(['repo', 'manifest']) + xml_root = ElementTree.fromstring(manifest) + projects = xml_root.findall('project') + remotes = xml_root.findall('remote') + default_revision = xml_root.findall('default')[0].get('revision') + + #dump project data into the a list of dicts with the following data: + #{project: {path, revision}} + + for project in projects: + name = project.get('name') + path = project.get('path') + revision = project.get('revision') + if revision is None: + for remote in remotes: + if remote.get('name') == project.get('remote'): + revision = remote.get('revision') + if revision is None: + revision = default_revision + + if not name in project_name_to_data: + project_name_to_data[name] = {} + revision = revision.split('refs/heads/')[-1] + project_name_to_data[name][revision] = path + + # get data on requested changes + reviews = [] + change_numbers = [] + if args.topic: + reviews = fetch_query(args.gerrit, 'topic:{0}'.format(args.topic)) + change_numbers = sorted([str(r['number']) for r in reviews]) + if args.query: + reviews = fetch_query(args.gerrit, args.query) + change_numbers = sorted([str(r['number']) for r in reviews]) + if args.change_number: + for c in args.change_number: + if '-' in c: + templist = c.split('-') + for i in range(int(templist[0]), int(templist[1]) + 1): + change_numbers.append(str(i)) + else: + change_numbers.append(c) + reviews = fetch_query(args.gerrit, ' OR '.join('change:{0}'.format(x.split('/')[0]) for x in change_numbers)) + + # make list of things to actually merge + mergables = [] + + # If --exclude is given, create the list of commits to ignore + exclude = [] + if args.exclude: + exclude = args.exclude[0].split(',') + + for change in change_numbers: + patchset = None + if '/' in change: + (change, patchset) = change.split('/') + + if change in exclude: + continue + + change = int(change) + review = next((x for x in reviews if x['number'] == change), None) + if review is None: + print('Change %d not found, skipping' % change) + continue + + mergables.append({ + 'subject': review['subject'], + 'project': review['project'], + 'branch': review['branch'], + 'change_id': review['change_id'], + 'change_number': review['number'], + 'status': review['status'], + 'fetch': None + }) + mergables[-1]['fetch'] = review['revisions'][review['current_revision']]['fetch'] + mergables[-1]['id'] = change + if patchset: + try: + mergables[-1]['fetch'] = [x['fetch'] for x in review['revisions'] if x['_number'] == patchset][0] + mergables[-1]['id'] = '{0}/{1}'.format(change, patchset) + except (IndexError, ValueError): + args.quiet or print('ERROR: The patch set {0}/{1} could not be found, using CURRENT_REVISION instead.'.format(change, patchset)) + + for item in mergables: + args.quiet or print('Applying change number {0}...'.format(item['id'])) + # Check if change is open and exit if it's not, unless -f is specified + if (item['status'] != 'OPEN' and item['status'] != 'NEW') and not args.query: + if args.force: + print('!! Force-picking a closed change !!\n') + else: + print('Change status is ' + item['status'] + '. Skipping the cherry pick.\nUse -f to force this pick.') + continue + + # Convert the project name to a project path + # - check that the project path exists + project_path = None + + if item['project'] in project_name_to_data and item['branch'] in project_name_to_data[item['project']]: + project_path = project_name_to_data[item['project']][item['branch']] + elif args.path: + project_path = args.path + elif args.ignore_missing: + print('WARNING: Skipping {0} since there is no project directory for: {1}\n'.format(item['id'], item['project'])) + continue + else: + sys.stderr.write('ERROR: For {0}, could not determine the project path for project {1}\n'.format(item['id'], item['project'])) + sys.exit(1) + + # If --start-branch is given, create the branch (more than once per path is okay; repo ignores gracefully) + if args.start_branch: + subprocess.check_output(['repo', 'start', args.start_branch[0], project_path]) + + # Determine the maximum commits to check already picked changes + check_picked_count = 10 + branch_commits_count = int(subprocess.check_output(['git', 'rev-list', '--count', 'HEAD'], cwd=project_path)) + if branch_commits_count <= check_picked_count: + check_picked_count = branch_commits_count - 1 + + # Check if change is already picked to HEAD...HEAD~check_picked_count + found_change = False + for i in range(0, check_picked_count): + output = subprocess.check_output(['git', 'show', '-q', 'HEAD~{0}'.format(i)], cwd=project_path).split() + if 'Change-Id:' in output: + head_change_id = '' + for j,t in enumerate(reversed(output)): + if t == 'Change-Id:': + head_change_id = output[len(output) - j] + break + if head_change_id.strip() == item['change_id']: + print('Skipping {0} - already picked in {1} as HEAD~{2}'.format(item['id'], project_path, i)) + found_change = True + break + if found_change: + continue + + # Print out some useful info + if not args.quiet: + print('--> Subject: "{0}"'.format(item['subject'])) + print('--> Project path: {0}'.format(project_path)) + print('--> Change number: {0} (Patch Set {0})'.format(item['id'])) + + if 'anonymous http' in item['fetch']: + method = 'anonymous http' + else: + method = 'ssh' + + # Try fetching from GitHub first if using default gerrit + if args.gerrit == default_gerrit: + if args.verbose: + print('Trying to fetch the change from GitHub') + + if args.pull: + cmd = ['git pull --no-edit github', item['fetch'][method]['ref']] + else: + cmd = ['git fetch github', item['fetch'][method]['ref']] + if args.quiet: + cmd.append('--quiet') + else: + print(cmd) + result = subprocess.call([' '.join(cmd)], cwd=project_path, shell=True) + FETCH_HEAD = '{0}/.git/FETCH_HEAD'.format(project_path) + if result != 0 and os.stat(FETCH_HEAD).st_size != 0: + print('ERROR: git command failed') + sys.exit(result) + # Check if it worked + if args.gerrit != default_gerrit or os.stat(FETCH_HEAD).st_size == 0: + # If not using the default gerrit or github failed, fetch from gerrit. + if args.verbose: + if args.gerrit == default_gerrit: + print('Fetching from GitHub didn\'t work, trying to fetch the change from Gerrit') + else: + print('Fetching from {0}'.format(args.gerrit)) + + if args.pull: + cmd = ['git pull --no-edit', item['fetch'][method]['url'], item['fetch'][method]['ref']] + else: + cmd = ['git fetch', item['fetch'][method]['url'], item['fetch'][method]['ref']] + if args.quiet: + cmd.append('--quiet') + else: + print(cmd) + result = subprocess.call([' '.join(cmd)], cwd=project_path, shell=True) + if result != 0: + print('ERROR: git command failed') + sys.exit(result) + # Perform the cherry-pick + if not args.pull: + cmd = ['git cherry-pick FETCH_HEAD'] + if args.quiet: + cmd_out = open(os.devnull, 'wb') + else: + cmd_out = None + result = subprocess.call(cmd, cwd=project_path, shell=True, stdout=cmd_out, stderr=cmd_out) + if result != 0: + print('ERROR: git command failed') + sys.exit(result) + if not args.quiet: + print('') diff --git a/build/tools/roomservice.py b/build/tools/roomservice.py new file mode 100755 index 00000000..a1b69cda --- /dev/null +++ b/build/tools/roomservice.py @@ -0,0 +1,297 @@ +#!/usr/bin/env python +# Copyright (C) 2012-2013, The CyanogenMod Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import base64 +import json +import netrc +import os +import re +import sys +try: + # For python3 + import urllib.error + import urllib.parse + import urllib.request +except ImportError: + # For python2 + import imp + import urllib2 + import urlparse + urllib = imp.new_module('urllib') + urllib.error = urllib2 + urllib.parse = urlparse + urllib.request = urllib2 + +from xml.etree import ElementTree + +product = sys.argv[1] + +if len(sys.argv) > 2: + depsonly = sys.argv[2] +else: + depsonly = None + +try: + device = product[product.index("_") + 1:] +except: + device = product + +if not depsonly: + print("Device %s not found. Attempting to retrieve device repository from CyanogenMod Github (http://github.com/CyanogenMod)." % device) + +repositories = [] + +try: + authtuple = netrc.netrc().authenticators("api.github.com") + + if authtuple: + auth_string = ('%s:%s' % (authtuple[0], authtuple[2])).encode() + githubauth = base64.encodestring(auth_string).decode().replace('\n', '') + else: + githubauth = None +except: + githubauth = None + +def add_auth(githubreq): + if githubauth: + githubreq.add_header("Authorization","Basic %s" % githubauth) + +if not depsonly: + githubreq = urllib.request.Request("https://api.github.com/search/repositories?q=%s+user:CyanogenMod+in:name+fork:true" % device) + add_auth(githubreq) + try: + result = json.loads(urllib.request.urlopen(githubreq).read().decode()) + except urllib.error.URLError: + print("Failed to search GitHub") + sys.exit() + except ValueError: + print("Failed to parse return data from GitHub") + sys.exit() + for res in result.get('items', []): + repositories.append(res) + +local_manifests = r'.repo/local_manifests' +if not os.path.exists(local_manifests): os.makedirs(local_manifests) + +def exists_in_tree(lm, path): + for child in lm.getchildren(): + if child.attrib['path'] == path: + return True + return False + +# in-place prettyprint formatter +def indent(elem, level=0): + i = "\n" + level*" " + if len(elem): + if not elem.text or not elem.text.strip(): + elem.text = i + " " + if not elem.tail or not elem.tail.strip(): + elem.tail = i + for elem in elem: + indent(elem, level+1) + if not elem.tail or not elem.tail.strip(): + elem.tail = i + else: + if level and (not elem.tail or not elem.tail.strip()): + elem.tail = i + +def get_default_revision(): + m = ElementTree.parse(".repo/manifest.xml") + d = m.findall('default')[0] + r = d.get('revision') + return r.replace('refs/heads/', '').replace('refs/tags/', '') + +def get_from_manifest(devicename): + try: + lm = ElementTree.parse(".repo/local_manifests/roomservice.xml") + lm = lm.getroot() + except: + lm = ElementTree.Element("manifest") + + for localpath in lm.findall("project"): + if re.search("android_device_.*_%s$" % device, localpath.get("name")): + return localpath.get("path") + + # Devices originally from AOSP are in the main manifest... + try: + mm = ElementTree.parse(".repo/manifest.xml") + mm = mm.getroot() + except: + mm = ElementTree.Element("manifest") + + for localpath in mm.findall("project"): + if re.search("android_device_.*_%s$" % device, localpath.get("name")): + return localpath.get("path") + + return None + +def is_in_manifest(projectpath): + try: + lm = ElementTree.parse(".repo/local_manifests/roomservice.xml") + lm = lm.getroot() + except: + lm = ElementTree.Element("manifest") + + for localpath in lm.findall("project"): + if localpath.get("path") == projectpath: + return True + + ## Search in main manifest, too + try: + lm = ElementTree.parse(".repo/manifest.xml") + lm = lm.getroot() + except: + lm = ElementTree.Element("manifest") + + for localpath in lm.findall("project"): + if localpath.get("path") == projectpath: + return True + + return False + +def add_to_manifest(repositories, fallback_branch = None): + try: + lm = ElementTree.parse(".repo/local_manifests/roomservice.xml") + lm = lm.getroot() + except: + lm = ElementTree.Element("manifest") + + for repository in repositories: + repo_name = repository['repository'] + repo_target = repository['target_path'] + print('Checking if %s is fetched from %s' % (repo_target, repo_name)) + if is_in_manifest(repo_target): + print('CyanogenMod/%s already fetched to %s' % (repo_name, repo_target)) + continue + + print('Adding dependency: CyanogenMod/%s -> %s' % (repo_name, repo_target)) + project = ElementTree.Element("project", attrib = { "path": repo_target, + "remote": "github", "name": "CyanogenMod/%s" % repo_name }) + + if 'branch' in repository: + project.set('revision',repository['branch']) + elif fallback_branch: + print("Using fallback branch %s for %s" % (fallback_branch, repo_name)) + project.set('revision', fallback_branch) + else: + print("Using default branch for %s" % repo_name) + + lm.append(project) + + indent(lm, 0) + raw_xml = ElementTree.tostring(lm).decode() + raw_xml = '\n' + raw_xml + + f = open('.repo/local_manifests/roomservice.xml', 'w') + f.write(raw_xml) + f.close() + +def fetch_dependencies(repo_path, fallback_branch = None): + print('Looking for dependencies') + dependencies_path = repo_path + '/cm.dependencies' + syncable_repos = [] + + if os.path.exists(dependencies_path): + dependencies_file = open(dependencies_path, 'r') + dependencies = json.loads(dependencies_file.read()) + fetch_list = [] + + for dependency in dependencies: + if not is_in_manifest(dependency['target_path']): + fetch_list.append(dependency) + syncable_repos.append(dependency['target_path']) + + dependencies_file.close() + + if len(fetch_list) > 0: + print('Adding dependencies to manifest') + add_to_manifest(fetch_list, fallback_branch) + else: + print('Dependencies file not found, bailing out.') + + if len(syncable_repos) > 0: + print('Syncing dependencies') + os.system('repo sync --force-sync %s' % ' '.join(syncable_repos)) + + for deprepo in syncable_repos: + fetch_dependencies(deprepo) + +def has_branch(branches, revision): + return revision in [branch['name'] for branch in branches] + +if depsonly: + repo_path = get_from_manifest(device) + if repo_path: + fetch_dependencies(repo_path) + else: + print("Trying dependencies-only mode on a non-existing device tree?") + + sys.exit() + +else: + for repository in repositories: + repo_name = repository['name'] + if repo_name.startswith("android_device_") and repo_name.endswith("_" + device): + print("Found repository: %s" % repository['name']) + + manufacturer = repo_name.replace("android_device_", "").replace("_" + device, "") + + default_revision = get_default_revision() + print("Default revision: %s" % default_revision) + print("Checking branch info") + githubreq = urllib.request.Request(repository['branches_url'].replace('{/branch}', '')) + add_auth(githubreq) + result = json.loads(urllib.request.urlopen(githubreq).read().decode()) + + ## Try tags, too, since that's what releases use + if not has_branch(result, default_revision): + githubreq = urllib.request.Request(repository['tags_url'].replace('{/tag}', '')) + add_auth(githubreq) + result.extend (json.loads(urllib.request.urlopen(githubreq).read().decode())) + + repo_path = "device/%s/%s" % (manufacturer, device) + adding = {'repository':repo_name,'target_path':repo_path} + + fallback_branch = None + if not has_branch(result, default_revision): + if os.getenv('ROOMSERVICE_BRANCHES'): + fallbacks = list(filter(bool, os.getenv('ROOMSERVICE_BRANCHES').split(' '))) + for fallback in fallbacks: + if has_branch(result, fallback): + print("Using fallback branch: %s" % fallback) + fallback_branch = fallback + break + + if not fallback_branch: + print("Default revision %s not found in %s. Bailing." % (default_revision, repo_name)) + print("Branches found:") + for branch in [branch['name'] for branch in result]: + print(branch) + print("Use the ROOMSERVICE_BRANCHES environment variable to specify a list of fallback branches.") + sys.exit() + + add_to_manifest([adding], fallback_branch) + + print("Syncing repository to retrieve project.") + os.system('repo sync --force-sync %s' % repo_path) + print("Repository synced!") + + fetch_dependencies(repo_path, fallback_branch) + print("Done") + sys.exit() + +print("Repository for %s not found in the CyanogenMod Github repository list. If this is in error, you may need to manually add it to your local_manifests/roomservice.xml." % device) diff --git a/config/common.mk b/config/common.mk index 6c3f7b16..ad2a8d73 100644 --- a/config/common.mk +++ b/config/common.mk @@ -351,6 +351,12 @@ PRODUCT_PROPERTY_OVERRIDES += \ ro.modversion=$(CM_VERSION) \ ro.cmlegal.url=https://cyngn.com/legal/privacy-policy +ifeq ($(OTA_PACKAGE_SIGNING_KEY),) + PRODUCT_EXTRA_RECOVERY_KEYS += \ + vendor/cm/build/target/product/security/cm \ + vendor/cm/build/target/product/security/cm-devkey +endif + -include vendor/cm-priv/keys/keys.mk CM_DISPLAY_VERSION := $(CM_VERSION)