1 ;;; 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. 16 17 ;;; 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: 32 33 (defgroup android nil 34 "Support for android development in Emacs." 35 :prefix "android-" ; Currently unused. 36 :tag "Android" 37 :group 'tools) 38 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 45 ;;;###autoload 46 (defcustom android-compilation-no-buildenv-warning t 47 "If not nil, suppress warnings from the build env (Makefile, 48 bash) from the compilation output since they interfere with 49 `next-error'." 50 :type 'boolean 51 :group 'android) 52 53 ;;;###autoload 54 (defcustom android-product-alias-map nil 55 "Alist between product targets (declared in buildspec.mk) and actual 56 product build directory used by `android-product'. 57 58 For instance if TARGET_PRODUCT is 'foo' but the build directory 59 is 'out/target/product/bar', you need to add a mapping Target:foo -> Alias:bar." 60 :type '(repeat (list (string :tag "Target") 61 (string :tag "Alias"))) 62 :group 'android) 63 64 (defconst android-output-buffer-name "*Android Output*" 65 "Name of the default buffer for the output of the commands. 66 There is only one instance of such a buffer.") 67 68 (defun android-find-build-tree-root () 69 "Ascend the current path until the root of the android build tree is found. 70 Similarly to the shell functions in envsetup.sh, for the root both ./Makefile 71 and ./build/core/envsetup.mk are exiting files. 72 Return the root of the build tree. Signal an error if not found." 73 (let ((default-directory default-directory)) 74 (while (and (> (length default-directory) 2) 75 (not (file-exists-p (concat default-directory 76 "Makefile"))) 77 (not (file-exists-p (concat default-directory 78 "build/core/envsetup.mk")))) 79 (setq default-directory 80 (substring default-directory 0 81 (string-match "[^/]+/$" default-directory)))) 82 (if (> (length default-directory) 2) 83 default-directory 84 (error "Not in a valid android tree")))) 85 86 (defun android-project-p () 87 "Return nil if not in an android build tree." 88 (condition-case nil 89 (android-find-build-tree-root) 90 (error nil))) 91 92 (defun android-host () 93 "Return the <system>-<arch> string (e.g linux-x86). 94 Only linux and darwin on x86 architectures are supported." 95 (or (string-match "x86" system-configuration) 96 (string-match "i386" system-configuration) 97 (error "Unknown arch")) 98 (or (and (string-match "darwin" system-configuration) "darwin-x86") 99 (and (string-match "linux" system-configuration) "linux-x86") 100 (error "Unknown system"))) 101 102 (defun android-product () 103 "Return the product built according to the buildspec.mk. 104 You must have buildspec.mk file in the top directory. 105 106 Additional product aliases can be listed in `android-product-alias-map' 107 if the product actually built is different from the one listed 108 in buildspec.mk" 109 (save-excursion 110 (let* ((buildspec (concat (android-find-build-tree-root) "buildspec.mk")) 111 (product (with-current-buffer (find-file-noselect buildspec) 112 (goto-char (point-min)) 113 (search-forward "TARGET_PRODUCT:=") 114 (buffer-substring-no-properties (point) 115 (scan-sexps (point) 1)))) 116 (alias (assoc product android-product-alias-map))) 117 ; Post processing, adjust the names. 118 (if (not alias) 119 product 120 (nth 1 alias))))) 121 122 (defun android-product-path () 123 "Return the full path to the product directory. 124 125 Additional product aliases can be added in `android-product-alias-map' 126 if the product actually built is different from the one listed 127 in buildspec.mk" 128 (let ((path (concat (android-find-build-tree-root) "out/target/product/" 129 (android-product)))) 130 (when (not (file-exists-p path)) 131 (error (format "%s does not exist. If product %s maps to another one, 132 add an entry to android-product-map." path (android-product)))) 133 path)) 134 135 (defun android-find-host-bin (binary) 136 "Return the full path to the host BINARY. 137 Binaries don't depend on the device, just on the host type. 138 Try first to locate BINARY in the out/host tree. Fallback using 139 the shell exec PATH setup." 140 (if (android-project-p) 141 (let ((path (concat (android-find-build-tree-root) "out/host/" 142 (android-host) "/bin/" binary))) 143 (if (file-exists-p path) 144 path 145 (error (concat binary " is missing.")))) 146 (executable-find binary))) 147 148 (defun android-adb () 149 "Return the path to the adb executable. 150 If not in the build tree use the PATH env variable." 151 (android-find-host-bin "adb")) 152 153 (defun android-fastboot () 154 "Return the path to the fastboot executable. 155 If not in the build tree use the PATH env variable." 156 ; For fastboot -p is the name of the product, *not* the full path to 157 ; its directory like adb requests sometimes. 158 (concat (android-find-host-bin "fastboot") " -p " (android-product))) 159 160 (defun android-adb-command (command &optional product) 161 "Execute 'adb COMMAND'. 162 If the optional PRODUCT is not nil, -p (android-product-path) is used 163 when adb is invoked." 164 (when (get-buffer android-output-buffer-name) 165 (with-current-buffer android-output-buffer-name 166 (erase-buffer))) 167 (if product 168 (shell-command (concat (android-adb) " -p " (android-product-path) 169 " " command) 170 android-output-buffer-name) 171 (shell-command (concat (android-adb) " " command) 172 android-output-buffer-name))) 173 174 (defun android-adb-shell-command (command) 175 "Execute 'adb shell COMMAND'." 176 (android-adb-command (concat " shell " command) 177 android-output-buffer-name)) 178 179 (provide 'android-common) 180 181 ;;; android-common.el ends here 182