aboutsummaryrefslogtreecommitdiff
path: root/build/wrap-common.mk
blob: db9c614710f4b261703444a37f361ecd26558fc0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#
# 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 ?= @

# 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): 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) figure out the best way to get the BSP brand.
  $(Q)# TODO(wad) Alternatively, should this always mkdir 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) 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) Make tee optional
define build-product
 $(Q)(cd "$(2)" && \
  . build/envsetup.sh && \
  add_lunch_combo "$(3)-$(6)" && \
  lunch "$(3)-$(6)" && \
  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) split mm and mma.
define build-product-here
 $(Q)echo "Building in subtree $(7) . . ."
 $(Q)(cd "$(2)" && \
  . 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