| ;;; 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 |