blob: bbe2afae705318f48f07333246aefba03f22533d [file] [log] [blame]
#
# Copyright 2015 The Android Open Source 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.
#
# This file supports wrapping of out of tree builds by enabling
# the injection of paths into a shadowed build tree. See create-shadow-bdk for
# more details on what this file does, and wrap-product.mk for usage.
#
# This file should only be included from other .mk files in tools/bdk/build.
# Require bash use for now.
SHELL := /bin/bash
R :=
ifneq ($(DRY_RUN),)
R := echo
endif
# Quiet prefix
Q ?= @
# Must not be passed in implicitly from the environment.
ifeq "$(origin Q)" "environment"
Q := @
endif
# Create a symlink farm from the BDK tree.
#
# Creating a symlink farm enables "in-tree" builds from an Android build
# perspective but without modifying the BDK tree at all. This allows for
# side-by-side hermetic builds for different out of tree products.
#
# A full shadow is expensive in both developer time and inodes. A shallow
# shadow doesn't allow effective injection. This macro creates a shallow farm
# for all the source code that should not be easily overriden during BDK use.
# For other pieces, the farm depth varies.
#
# The product and device trees are shadowed to the <vendor>/ path.
# The hardware builds paths down to bsp/<...> to allow injection underneath.
# Additionally, hardware/bsp/kernel allows link injection as well.
#
# TODO(wad)(b/25952676): Enable mapping in a product tree so that products can
# cross-inherit.
# Usage:
# $(call create-shadow-bdk,$(BDK_PATH),$(PRODUCT_BDK))
define create-shadow-bdk
$(Q)echo "Building a shadow BDK v$(shell cat $(1)/tools/bdk/VERSION) . . ."
$(Q)# Build the initial shallow farm (ignoring dot files)
$(Q)$(R) mkdir -p "$(2)"
$(Q)$(R) ln -s "$(1)"/* "$(2)"
$(Q)# Remove any errant 'out's.
$(Q)$(R) rm -f "$(2)"/out
$(Q)# TODO(wad)(b/25952641) figure out the best way to get the BSP brand.
$(Q)# TODO(wad)(b/25952916) Alternatively, should this always mkdir
$(Q)# down to the vendor level? find-/ln
$(Q)for p in \
hardware \
$$(find "$(1)/product" "$(1)/device" \
"$(1)/hardware/bsp" "$(1)/hardware/bsp/kernel" \
-maxdepth 1 -type d); do \
p="$${p#$(1)/}"; \
if test -L "$(2)/$$p"; then \
$(R) rm "$(2)/$$p"; \
$(R) mkdir "$(2)/$$p"; \
test -d "$(1)/$$p" && $(R) ln -s "$(1)/$$p/"* "$(2)/$$p/"; \
fi; \
done
$(Q)# Always remove the examples so they can be used as demos.
$(Q)$(R) rm "$(2)/product/google/example-"*
endef
# Usage:
# $(call fake-java,$(PRODUCT_BDK))
define fake-java
$(Q)# Create a fake java to remove it as a build prereq.
$(Q)mkdir -p "$(1)/java/bin"
$(Q)echo 'echo javac not openjdk version "1.7.0"' > "$(1)/java/bin/javac"
$(Q)echo 'echo java not openjdk version "1.7.0"' > "$(1)/java/bin/java"
$(Q)chmod a+x "$(1)/java/bin/java" "$(1)/java/bin/javac"
$(Q)mkdir -p "$(1)/java/lib"
$(Q)touch "$(1)/java/lib/tools.jar"
endef
# Inject the product into the shadow BDK.
# Usage:
# $(call inject-product,$(PRODUCT_DIR),$(PRODUCT_BDK),$(PRODUCT_OUT),$(PRODUCT_MANUFACTURER),$(PRODUCT_NAME))
define inject-product
$(Q)# Shallow link the product dir.
$(Q)$(R) mkdir -p "$(2)/product/$(4)/$(5)"
$(Q)$(R) ln -sf "$(1)/"* \
"$(2)/product/$(4)/$(5)/"
$(Q)# Remove 'out' if it is under the product dir to avoid cycles.
$(Q)find "$(2)/product/$(4)/$(5)" -lname "$(3)"'*' \
-exec bash -c '$(R) rm {}' \;
endef
# TODO(wad)(b/25952646) define inject-bsp
# Calls the android build in the shadow BDK
#
# Note: Kati's find emulation support is disabled to ensure findleaves.py
# properly traverses symlinks.
# https://github.com/google/kati/issues/30
# Usage:
# $(call build-product,$(BDK_PATH),$(PRODUCT_BDK),$(PRODUCT_NAME),$(PRODUCT_DEVICE),$(PRODUCT_OUT),$(BUILDTYPE))
# TODO(wad)(b/25952919) Make tee optional
define build-product
$(Q)(cd "$(2)" && \
unset MAKEFLAGS MAKEOVERRIDES MAKECMDGOALS MAKELEVEL && \
. build/envsetup.sh && \
add_lunch_combo "$(3)-$(6)" && \
lunch "$(3)-$(6)" && \
MAKEFLAGS="$(MAKEFLAGS)" PATH=$(2)/java/bin:$$PATH $(MAKE) $(MAKECMDGOALS) "OUT_DIR=$(5)/out-$(4)" KATI_EMULATE_FIND=false || \
exit $?) 2>&1 | tee "$(5)/last_build.log"
endef
# Calls the android build in the current directory mapped under the shadow BDK
#
# Usage:
# $(call build-product-here,$(BDK_PATH),$(PRODUCT_BDK),$(PRODUCT_NAME),$(PRODUCT_DEVICE),$(PRODUCT_OUT),$(BUILDTYPE),$(HERE),$(CMD))
# TODO(wad)(b/25952920) split mm and mma.
define build-product-here
$(Q)echo "Building in subtree $(7) . . ."
$(Q)(cd "$(2)" && \
unset MAKEFLAGS MAKEOVERRIDES MAKECMDGOALS MAKELEVEL && \
. build/envsetup.sh && \
add_lunch_combo "$(3)-$(6)" && \
lunch "$(3)-$(6)" && \
cd "product/$(PRODUCT_MANUFACTURER)/$(PRODUCT_NAME)/$(subst $(PRODUCT_DIR),,$(7))" && \
PATH=$(2)/java/bin:$$PATH \
MAKEFLAGS="$(MAKEFLAGS)" OUT_DIR="$(5)/out-$(4)" \
KATI_EMULATE_FIND=false $(8) || \
exit $?) 2>&1 | tee "$(5)/last_build.log"
endef
# Calls gdbclient.py using the shadow BDK build.
#
# Always returns true to avoid make printing a build error.
#
# Usage:
# $(call run-gdbclient,$(PRODUCT_BDK),$(PRODUCT_NAME),$(BUILDTYPE),$(ADB_PATH),$(GDBCLIENT_ARGS))
define run-gdbclient
$(Q)(cd "$(1)" && \
. build/envsetup.sh >/dev/null && \
add_lunch_combo "$(2)-$(3)" >/dev/null && \
lunch "$(2)-$(3)" >/dev/null && \
tools/bdk/debugging/gdbclient.py --adb $(4) $(5) || \
true)
endef