File: android-common.el

package info (click to toggle)
android-platform-development 7.0.0%2Br33-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 30,092 kB
  • sloc: ansic: 161,291; java: 15,681; cpp: 7,721; xml: 6,419; python: 5,456; sh: 1,748; lisp: 261; ruby: 183; asm: 132; perl: 88; makefile: 22
file content (181 lines) | stat: -rw-r--r-- 7,191 bytes parent folder | download | duplicates (3)
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
;;; android-common.el --- Common functions/variables to dev Android in Emacs.
;;
;; Copyright (C) 2009 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.

;;; Commentary:
;;
;; Variables to customize and common functions for the Android build
;; support in Emacs.
;; There should be no interactive function in this module.
;;
;; You need to have a proper buildspec.mk file in your root directory
;; for this module to work (see $TOP/build/buildspec.mk.default).
;; If the path the product's files/image uses an a product alias, you
;; need to add a mapping in `android-product-alias-map'. For instance
;; if TARGET_PRODUCT is foo but the build directory is out/target/product/bar,
;; you need to add a mapping Target:foo -> Alias:bar
;;

;;; Code:

(defgroup android nil
  "Support for android development in Emacs."
  :prefix "android-"                    ; Currently unused.
  :tag    "Android"
  :group  'tools)

;;;###autoload
(defcustom android-compilation-jobs 2
  "Number of jobs used to do a compilation (-j option of make)."
  :type 'integer
  :group 'android)

;;;###autoload
(defcustom android-compilation-no-buildenv-warning t
  "If not nil, suppress warnings from the build env (Makefile,
bash) from the compilation output since they interfere with
`next-error'."
  :type 'boolean
  :group 'android)

;;;###autoload
(defcustom android-product-alias-map nil
  "Alist between product targets (declared in buildspec.mk) and actual
 product build directory used by `android-product'.

For instance if TARGET_PRODUCT is 'foo' but the build directory
 is 'out/target/product/bar', you need to add a mapping Target:foo -> Alias:bar."
  :type '(repeat (list (string :tag "Target")
                       (string :tag "Alias")))
  :group 'android)

(defconst android-output-buffer-name "*Android Output*"
  "Name of the default buffer for the output of the commands.
There is only one instance of such a buffer.")

(defun android-find-build-tree-root ()
  "Ascend the current path until the root of the android build tree is found.
Similarly to the shell functions in envsetup.sh, for the root both ./Makefile
and ./build/core/envsetup.mk are exiting files.
Return the root of the build tree.  Signal an error if not found."
  (let ((default-directory default-directory))
    (while (and (> (length default-directory) 2)
                (not (file-exists-p (concat default-directory
                                            "Makefile")))
                (not (file-exists-p (concat default-directory
                                            "build/core/envsetup.mk"))))
      (setq default-directory
            (substring default-directory 0
                       (string-match "[^/]+/$" default-directory))))
    (if (> (length default-directory) 2)
        default-directory
      (error "Not in a valid android tree"))))

(defun android-project-p ()
  "Return nil if not in an android build tree."
  (condition-case nil
      (android-find-build-tree-root)
    (error nil)))

(defun android-host ()
  "Return the <system>-<arch> string (e.g linux-x86).
Only linux and darwin on x86 architectures are supported."
  (or (string-match "x86" system-configuration)
      (string-match "i386" system-configuration)
      (error "Unknown arch"))
  (or (and (string-match "darwin" system-configuration) "darwin-x86")
      (and (string-match "linux" system-configuration) "linux-x86")
      (error "Unknown system")))

(defun android-product ()
  "Return the product built according to the buildspec.mk.
You must have buildspec.mk file in the top directory.

Additional product aliases can be listed in `android-product-alias-map'
if the product actually built is different from the one listed
in buildspec.mk"
  (save-excursion
    (let* ((buildspec (concat (android-find-build-tree-root) "buildspec.mk"))
           (product (with-current-buffer (find-file-noselect buildspec)
                      (goto-char (point-min))
                      (search-forward "TARGET_PRODUCT:=")
                      (buffer-substring-no-properties (point)
                                                      (scan-sexps (point) 1))))
           (alias (assoc product android-product-alias-map)))
      ; Post processing, adjust the names.
      (if (not alias)
          product
        (nth 1 alias)))))

(defun android-product-path ()
  "Return the full path to the product directory.

Additional product aliases can be added in `android-product-alias-map'
if the product actually built is different from the one listed
in buildspec.mk"
  (let ((path (concat (android-find-build-tree-root) "out/target/product/"
                      (android-product))))
    (when (not (file-exists-p path))
      (error (format "%s does not exist. If product %s maps to another one,
add an entry to android-product-map." path (android-product))))
    path))

(defun android-find-host-bin (binary)
  "Return the full path to the host BINARY.
Binaries don't depend on the device, just on the host type.
Try first to locate BINARY in the out/host tree.  Fallback using
the shell exec PATH setup."
  (if (android-project-p)
      (let ((path (concat (android-find-build-tree-root) "out/host/"
                          (android-host) "/bin/" binary)))
        (if (file-exists-p path)
            path
          (error (concat binary " is missing."))))
    (executable-find binary)))

(defun android-adb ()
  "Return the path to the adb executable.
If not in the build tree use the PATH env variable."
  (android-find-host-bin "adb"))

(defun android-fastboot ()
  "Return the path to the fastboot executable.
If not in the build tree use the PATH env variable."
  ; For fastboot -p is the name of the product, *not* the full path to
  ; its directory like adb requests sometimes.
  (concat (android-find-host-bin "fastboot") " -p " (android-product)))

(defun android-adb-command (command &optional product)
  "Execute 'adb COMMAND'.
If the optional PRODUCT is not nil, -p (android-product-path) is used
when adb is invoked."
  (when (get-buffer android-output-buffer-name)
    (with-current-buffer android-output-buffer-name
      (erase-buffer)))
  (if product
      (shell-command (concat (android-adb) " -p " (android-product-path)
                             " " command)
                     android-output-buffer-name)
    (shell-command (concat (android-adb) " " command)
                   android-output-buffer-name)))

(defun android-adb-shell-command (command)
  "Execute 'adb shell COMMAND'."
  (android-adb-command (concat " shell " command)
                       android-output-buffer-name))

(provide 'android-common)

;;; android-common.el ends here