Nicolas Catania | 4a5dc7e | 2009-10-09 09:24:42 -0700 | [diff] [blame] | 1 | ;;; android-compile.el --- Compile the Android source tree. |
| 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 | 1925281 | 2009-10-05 14:49:14 -0700 | [diff] [blame] | 16 | |
Nicolas Catania | 4a5dc7e | 2009-10-09 09:24:42 -0700 | [diff] [blame] | 17 | ;;; Commentary: |
| 18 | ;; |
| 19 | ;; Helper functions to compile Android file within emacs. |
| 20 | ;; This module ignores 'build/envsetup.sh' and any enviroment set by the |
| 21 | ;; 'lunch' shell function. |
| 22 | ;; Instead it relies solely on 'buildspec.mk', remember that when you |
| 23 | ;; switch configuration. |
| 24 | ;; |
| 25 | ;; The only interactive function is 'android-compile'. |
| 26 | ;; In your .emacs load this file (e.g (require 'android-compile)) then: |
| 27 | ;; |
| 28 | ;; (add-hook 'c++-mode-hook 'android-compile) |
| 29 | ;; (add-hook 'java-mode-hook 'android-compile) |
| 30 | ;; and/or |
| 31 | ;; (global-set-key [f9] 'android-compile) |
| 32 | ;; |
| 33 | ;; |
| 34 | ;; TODO: Maybe we could cache the result of the compile function in |
| 35 | ;; buffer local vars. |
Nicolas Catania | 1925281 | 2009-10-05 14:49:14 -0700 | [diff] [blame] | 36 | |
Nicolas Catania | 4a5dc7e | 2009-10-09 09:24:42 -0700 | [diff] [blame] | 37 | ;;; Code: |
Nicolas Catania | 1925281 | 2009-10-05 14:49:14 -0700 | [diff] [blame] | 38 | |
| 39 | (require 'compile) |
Nicolas Catania | f94bca2 | 2009-10-06 10:45:44 -0700 | [diff] [blame] | 40 | (require 'android-common) |
Nicolas Catania | 1925281 | 2009-10-05 14:49:14 -0700 | [diff] [blame] | 41 | |
Nicolas Catania | 4a5dc7e | 2009-10-09 09:24:42 -0700 | [diff] [blame] | 42 | (defun android-makefile-exists-p (directory) |
| 43 | "Return t if an Android makefile exists in DIRECTORY." |
| 44 | ; Test for Android.mk first: more likely. |
| 45 | (or (file-exists-p (concat directory "Android.mk")) |
| 46 | (file-exists-p (concat directory "Makefile")))) |
| 47 | |
Nicolas Catania | 1925281 | 2009-10-05 14:49:14 -0700 | [diff] [blame] | 48 | (defun android-find-makefile (topdir) |
| 49 | "Ascend the current path until an Android makefile is found. |
| 50 | Makefiles are named Android.mk except in the root directory where |
| 51 | the file is named Makefile. |
| 52 | TOPDIR is the root directory of the build. |
| 53 | Return a list with 2 elements (MAKEFILE_PATH IS_ROOT_MAKEFILE). |
Nicolas Catania | 4a5dc7e | 2009-10-09 09:24:42 -0700 | [diff] [blame] | 54 | MAKEFILE_PATH is the relative path of the makefile wrt TOPDIR. |
Nicolas Catania | 1925281 | 2009-10-05 14:49:14 -0700 | [diff] [blame] | 55 | Signal an error if no Makefile was found." |
Nicolas Catania | 4a5dc7e | 2009-10-09 09:24:42 -0700 | [diff] [blame] | 56 | ;; TODO: Could check that topdir is the start of default-directory. |
| 57 | (unless (> (length topdir) 2) |
| 58 | (error "Topdir invalid %s for current dir %s" topdir default-directory)) |
| 59 | (let ((default-directory default-directory) |
| 60 | file) |
| 61 | ;; Ascend the path. |
Nicolas Catania | 1925281 | 2009-10-05 14:49:14 -0700 | [diff] [blame] | 62 | (while (and (> (length default-directory) (length topdir)) |
Nicolas Catania | 4a5dc7e | 2009-10-09 09:24:42 -0700 | [diff] [blame] | 63 | (not (android-makefile-exists-p default-directory))) |
Nicolas Catania | 1925281 | 2009-10-05 14:49:14 -0700 | [diff] [blame] | 64 | (setq default-directory |
| 65 | (substring default-directory 0 |
| 66 | (string-match "[^/]+/$" default-directory)))) |
Nicolas Catania | 4a5dc7e | 2009-10-09 09:24:42 -0700 | [diff] [blame] | 67 | |
| 68 | (when (not (android-makefile-exists-p default-directory)) |
| 69 | (error "Not in a valid android tree")) |
| 70 | |
| 71 | (if (string= default-directory topdir) |
| 72 | (list "Makefile" t) |
| 73 | ;; Remove the root dir at the start of the filename |
| 74 | (setq default-directory (substring default-directory (length topdir) nil)) |
| 75 | (setq file (concat default-directory "Android.mk")) |
| 76 | (list file nil)))) |
| 77 | |
Nicolas Catania | 1925281 | 2009-10-05 14:49:14 -0700 | [diff] [blame] | 78 | |
Nicolas Catania | 1925281 | 2009-10-05 14:49:14 -0700 | [diff] [blame] | 79 | (defun android-compile () |
| 80 | "Elisp equivalent of mm shell function. |
| 81 | Walk up the path until a makefile is found and build it. |
Nicolas Catania | f94bca2 | 2009-10-06 10:45:44 -0700 | [diff] [blame] | 82 | You need to have a proper buildspec.mk in your top dir. |
| 83 | |
| 84 | Use `android-compilation-jobs' to control the number of jobs used |
| 85 | in a compilation." |
Nicolas Catania | 1925281 | 2009-10-05 14:49:14 -0700 | [diff] [blame] | 86 | (interactive) |
| 87 | (if (android-project-p) |
| 88 | (let* ((topdir (android-find-build-tree-root)) |
Nicolas Catania | f94bca2 | 2009-10-06 10:45:44 -0700 | [diff] [blame] | 89 | (makefile (android-find-makefile topdir)) |
| 90 | (options |
| 91 | (concat " -j " (number-to-string android-compilation-jobs)))) |
Nicolas Catania | 4a5dc7e | 2009-10-09 09:24:42 -0700 | [diff] [blame] | 92 | (unless (file-exists-p (concat topdir "buildspec.mk")) |
| 93 | (error "buildspec.mk missing in %s." topdir)) |
Nicolas Catania | 1925281 | 2009-10-05 14:49:14 -0700 | [diff] [blame] | 94 | (set (make-local-variable 'compile-command) |
| 95 | (if (cadr makefile) |
| 96 | ;; The root Makefile is not invoked using ONE_SHOT_MAKEFILE. |
Nicolas Catania | 2022dcd | 2009-10-13 09:10:19 -0700 | [diff] [blame] | 97 | (concat "make -C " topdir options) ; Build the whole image. |
Nicolas Catania | 1925281 | 2009-10-05 14:49:14 -0700 | [diff] [blame] | 98 | (concat "ONE_SHOT_MAKEFILE=" (car makefile) |
Nicolas Catania | f94bca2 | 2009-10-06 10:45:44 -0700 | [diff] [blame] | 99 | " make -C " topdir options " files "))) |
Nicolas Catania | 1925281 | 2009-10-05 14:49:14 -0700 | [diff] [blame] | 100 | (if (interactive-p) |
Nicolas Catania | f94bca2 | 2009-10-06 10:45:44 -0700 | [diff] [blame] | 101 | (call-interactively 'compile))))) |
Nicolas Catania | 1925281 | 2009-10-05 14:49:14 -0700 | [diff] [blame] | 102 | |
| 103 | (provide 'android-compile) |
Nicolas Catania | 4a5dc7e | 2009-10-09 09:24:42 -0700 | [diff] [blame] | 104 | |
| 105 | ;;; android-compile.el ends here |