Nicolas Catania | 081e65d | 2009-10-09 21:17:27 -0700 | [diff] [blame] | 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. |
Nicolas Catania | f94bca2 | 2009-10-06 10:45:44 -0700 | [diff] [blame] | 16 | |
Nicolas Catania | 081e65d | 2009-10-09 21:17:27 -0700 | [diff] [blame] | 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: |
Nicolas Catania | f94bca2 | 2009-10-06 10:45:44 -0700 | [diff] [blame] | 32 | |
| 33 | (defgroup android nil |
| 34 | "Support for android development in Emacs." |
Nicolas Catania | 2022dcd | 2009-10-13 09:10:19 -0700 | [diff] [blame] | 35 | :prefix "android-" ; Currently unused. |
| 36 | :tag "Android" |
| 37 | :group 'tools) |
Nicolas Catania | f94bca2 | 2009-10-06 10:45:44 -0700 | [diff] [blame] | 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 | |
Nicolas Catania | 081e65d | 2009-10-09 21:17:27 -0700 | [diff] [blame] | 45 | ;;;###autoload |
Nicolas Catania | df098ce | 2009-10-15 10:48:01 -0700 | [diff] [blame] | 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 |
Nicolas Catania | 081e65d | 2009-10-09 21:17:27 -0700 | [diff] [blame] | 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 | |
Nicolas Catania | 2022dcd | 2009-10-13 09:10:19 -0700 | [diff] [blame] | 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 | |
Nicolas Catania | f94bca2 | 2009-10-06 10:45:44 -0700 | [diff] [blame] | 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. |
Nicolas Catania | 081e65d | 2009-10-09 21:17:27 -0700 | [diff] [blame] | 72 | Return the root of the build tree. Signal an error if not found." |
Nicolas Catania | f94bca2 | 2009-10-06 10:45:44 -0700 | [diff] [blame] | 73 | (let ((default-directory default-directory)) |
| 74 | (while (and (> (length default-directory) 2) |
Nicolas Catania | 081e65d | 2009-10-09 21:17:27 -0700 | [diff] [blame] | 75 | (not (file-exists-p (concat default-directory |
| 76 | "Makefile"))) |
| 77 | (not (file-exists-p (concat default-directory |
| 78 | "build/core/envsetup.mk")))) |
Nicolas Catania | f94bca2 | 2009-10-06 10:45:44 -0700 | [diff] [blame] | 79 | (setq default-directory |
| 80 | (substring default-directory 0 |
| 81 | (string-match "[^/]+/$" default-directory)))) |
| 82 | (if (> (length default-directory) 2) |
| 83 | default-directory |
Nicolas Catania | 081e65d | 2009-10-09 21:17:27 -0700 | [diff] [blame] | 84 | (error "Not in a valid android tree")))) |
Nicolas Catania | f94bca2 | 2009-10-06 10:45:44 -0700 | [diff] [blame] | 85 | |
| 86 | (defun android-project-p () |
Nicolas Catania | 081e65d | 2009-10-09 21:17:27 -0700 | [diff] [blame] | 87 | "Return nil if not in an android build tree." |
Nicolas Catania | f94bca2 | 2009-10-06 10:45:44 -0700 | [diff] [blame] | 88 | (condition-case nil |
| 89 | (android-find-build-tree-root) |
| 90 | (error nil))) |
| 91 | |
Nicolas Catania | 081e65d | 2009-10-09 21:17:27 -0700 | [diff] [blame] | 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." |
Nicolas Catania | 2022dcd | 2009-10-13 09:10:19 -0700 | [diff] [blame] | 164 | (when (get-buffer android-output-buffer-name) |
| 165 | (with-current-buffer android-output-buffer-name |
| 166 | (erase-buffer))) |
Nicolas Catania | 081e65d | 2009-10-09 21:17:27 -0700 | [diff] [blame] | 167 | (if product |
| 168 | (shell-command (concat (android-adb) " -p " (android-product-path) |
Nicolas Catania | 2022dcd | 2009-10-13 09:10:19 -0700 | [diff] [blame] | 169 | " " command) |
| 170 | android-output-buffer-name) |
| 171 | (shell-command (concat (android-adb) " " command) |
| 172 | android-output-buffer-name))) |
Nicolas Catania | 081e65d | 2009-10-09 21:17:27 -0700 | [diff] [blame] | 173 | |
| 174 | (defun android-adb-shell-command (command) |
| 175 | "Execute 'adb shell COMMAND'." |
Nicolas Catania | 2022dcd | 2009-10-13 09:10:19 -0700 | [diff] [blame] | 176 | (android-adb-command (concat " shell " command) |
| 177 | android-output-buffer-name)) |
Nicolas Catania | 081e65d | 2009-10-09 21:17:27 -0700 | [diff] [blame] | 178 | |
Nicolas Catania | f94bca2 | 2009-10-06 10:45:44 -0700 | [diff] [blame] | 179 | (provide 'android-common) |
Nicolas Catania | 081e65d | 2009-10-09 21:17:27 -0700 | [diff] [blame] | 180 | |
| 181 | ;;; android-common.el ends here |