blob: 7bf82a2b7ba4d29f8ca5f5d4a18331254ccb1654 [file] [log] [blame]
Nicolas Catania081e65d2009-10-09 21:17:27 -07001;;; android-common.el --- Common functions/variables to dev Android in Emacs.
2;;
3;; Copyright (C) 2009 The Android Open Source Project
4;;
5;; Licensed under the Apache License, Version 2.0 (the "License");
6;; you may not use this file except in compliance with the License.
7;; You may obtain a copy of the License at
8;;
9;; http://www.apache.org/licenses/LICENSE-2.0
10;;
11;; Unless required by applicable law or agreed to in writing, software
12;; distributed under the License is distributed on an "AS IS" BASIS,
13;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14;; See the License for the specific language governing permissions and
15;; limitations under the License.
Nicolas Cataniaf94bca22009-10-06 10:45:44 -070016
Nicolas Catania081e65d2009-10-09 21:17:27 -070017;;; Commentary:
18;;
19;; Variables to customize and common functions for the Android build
20;; support in Emacs.
21;; There should be no interactive function in this module.
22;;
23;; You need to have a proper buildspec.mk file in your root directory
24;; for this module to work (see $TOP/build/buildspec.mk.default).
25;; If the path the product's files/image uses an a product alias, you
26;; need to add a mapping in `android-product-alias-map'. For instance
27;; if TARGET_PRODUCT is foo but the build directory is out/target/product/bar,
28;; you need to add a mapping Target:foo -> Alias:bar
29;;
30
31;;; Code:
Nicolas Cataniaf94bca22009-10-06 10:45:44 -070032
33(defgroup android nil
34 "Support for android development in Emacs."
Nicolas Catania2022dcd2009-10-13 09:10:19 -070035 :prefix "android-" ; Currently unused.
36 :tag "Android"
37 :group 'tools)
Nicolas Cataniaf94bca22009-10-06 10:45:44 -070038
39;;;###autoload
40(defcustom android-compilation-jobs 2
41 "Number of jobs used to do a compilation (-j option of make)."
42 :type 'integer
43 :group 'android)
44
Nicolas Catania081e65d2009-10-09 21:17:27 -070045;;;###autoload
46(defcustom android-product-alias-map nil
47 "Alist between product targets (declared in buildspec.mk) and actual
48 product build directory used by `android-product'.
49
50For instance if TARGET_PRODUCT is 'foo' but the build directory
51 is 'out/target/product/bar', you need to add a mapping Target:foo -> Alias:bar."
52 :type '(repeat (list (string :tag "Target")
53 (string :tag "Alias")))
54 :group 'android)
55
Nicolas Catania2022dcd2009-10-13 09:10:19 -070056(defconst android-output-buffer-name "*Android Output*"
57 "Name of the default buffer for the output of the commands.
58There is only one instance of such a buffer.")
59
Nicolas Cataniaf94bca22009-10-06 10:45:44 -070060(defun android-find-build-tree-root ()
61 "Ascend the current path until the root of the android build tree is found.
62Similarly to the shell functions in envsetup.sh, for the root both ./Makefile
63and ./build/core/envsetup.mk are exiting files.
Nicolas Catania081e65d2009-10-09 21:17:27 -070064Return the root of the build tree. Signal an error if not found."
Nicolas Cataniaf94bca22009-10-06 10:45:44 -070065 (let ((default-directory default-directory))
66 (while (and (> (length default-directory) 2)
Nicolas Catania081e65d2009-10-09 21:17:27 -070067 (not (file-exists-p (concat default-directory
68 "Makefile")))
69 (not (file-exists-p (concat default-directory
70 "build/core/envsetup.mk"))))
Nicolas Cataniaf94bca22009-10-06 10:45:44 -070071 (setq default-directory
72 (substring default-directory 0
73 (string-match "[^/]+/$" default-directory))))
74 (if (> (length default-directory) 2)
75 default-directory
Nicolas Catania081e65d2009-10-09 21:17:27 -070076 (error "Not in a valid android tree"))))
Nicolas Cataniaf94bca22009-10-06 10:45:44 -070077
78(defun android-project-p ()
Nicolas Catania081e65d2009-10-09 21:17:27 -070079 "Return nil if not in an android build tree."
Nicolas Cataniaf94bca22009-10-06 10:45:44 -070080 (condition-case nil
81 (android-find-build-tree-root)
82 (error nil)))
83
Nicolas Catania081e65d2009-10-09 21:17:27 -070084(defun android-host ()
85 "Return the <system>-<arch> string (e.g linux-x86).
86Only linux and darwin on x86 architectures are supported."
87 (or (string-match "x86" system-configuration)
88 (string-match "i386" system-configuration)
89 (error "Unknown arch"))
90 (or (and (string-match "darwin" system-configuration) "darwin-x86")
91 (and (string-match "linux" system-configuration) "linux-x86")
92 (error "Unknown system")))
93
94(defun android-product ()
95 "Return the product built according to the buildspec.mk.
96You must have buildspec.mk file in the top directory.
97
98Additional product aliases can be listed in `android-product-alias-map'
99if the product actually built is different from the one listed
100in buildspec.mk"
101 (save-excursion
102 (let* ((buildspec (concat (android-find-build-tree-root) "buildspec.mk"))
103 (product (with-current-buffer (find-file-noselect buildspec)
104 (goto-char (point-min))
105 (search-forward "TARGET_PRODUCT:=")
106 (buffer-substring-no-properties (point)
107 (scan-sexps (point) 1))))
108 (alias (assoc product android-product-alias-map)))
109 ; Post processing, adjust the names.
110 (if (not alias)
111 product
112 (nth 1 alias)))))
113
114(defun android-product-path ()
115 "Return the full path to the product directory.
116
117Additional product aliases can be added in `android-product-alias-map'
118if the product actually built is different from the one listed
119in buildspec.mk"
120 (let ((path (concat (android-find-build-tree-root) "out/target/product/"
121 (android-product))))
122 (when (not (file-exists-p path))
123 (error (format "%s does not exist. If product %s maps to another one,
124add an entry to android-product-map." path (android-product))))
125 path))
126
127(defun android-find-host-bin (binary)
128 "Return the full path to the host BINARY.
129Binaries don't depend on the device, just on the host type.
130Try first to locate BINARY in the out/host tree. Fallback using
131the shell exec PATH setup."
132 (if (android-project-p)
133 (let ((path (concat (android-find-build-tree-root) "out/host/"
134 (android-host) "/bin/" binary)))
135 (if (file-exists-p path)
136 path
137 (error (concat binary " is missing."))))
138 (executable-find binary)))
139
140(defun android-adb ()
141 "Return the path to the adb executable.
142If not in the build tree use the PATH env variable."
143 (android-find-host-bin "adb"))
144
145(defun android-fastboot ()
146 "Return the path to the fastboot executable.
147If not in the build tree use the PATH env variable."
148 ; For fastboot -p is the name of the product, *not* the full path to
149 ; its directory like adb requests sometimes.
150 (concat (android-find-host-bin "fastboot") " -p " (android-product)))
151
152(defun android-adb-command (command &optional product)
153 "Execute 'adb COMMAND'.
154If the optional PRODUCT is not nil, -p (android-product-path) is used
155when adb is invoked."
Nicolas Catania2022dcd2009-10-13 09:10:19 -0700156 (when (get-buffer android-output-buffer-name)
157 (with-current-buffer android-output-buffer-name
158 (erase-buffer)))
Nicolas Catania081e65d2009-10-09 21:17:27 -0700159 (if product
160 (shell-command (concat (android-adb) " -p " (android-product-path)
Nicolas Catania2022dcd2009-10-13 09:10:19 -0700161 " " command)
162 android-output-buffer-name)
163 (shell-command (concat (android-adb) " " command)
164 android-output-buffer-name)))
Nicolas Catania081e65d2009-10-09 21:17:27 -0700165
166(defun android-adb-shell-command (command)
167 "Execute 'adb shell COMMAND'."
Nicolas Catania2022dcd2009-10-13 09:10:19 -0700168 (android-adb-command (concat " shell " command)
169 android-output-buffer-name))
Nicolas Catania081e65d2009-10-09 21:17:27 -0700170
Nicolas Cataniaf94bca22009-10-06 10:45:44 -0700171(provide 'android-common)
Nicolas Catania081e65d2009-10-09 21:17:27 -0700172
173;;; android-common.el ends here