Home | History | Annotate | Download | only in emacs
      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