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
|