Mercurial > emacs
comparison lisp/cedet/ede/pmake.el @ 104496:8c4870c15962
* cedet/ede.el, cedet/ede/*.el: New files.
* cedet/cedet.el: Require ede.
* cedet/semantic/symref/filter.el (semantic-symref-hits-in-region):
Require semantic/idle.
author | Chong Yidong <cyd@stupidchicken.com> |
---|---|
date | Sun, 20 Sep 2009 15:06:05 +0000 |
parents | |
children | cdbbb89893d5 |
comparison
equal
deleted
inserted
replaced
104495:4659ddbe20bf | 104496:8c4870c15962 |
---|---|
1 ;;; ede-pmake.el --- EDE Generic Project Makefile code generator. | |
2 | |
3 ;;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, | |
4 ;;; 2007, 2008, 2009 Free Software Foundation, Inc. | |
5 | |
6 ;; Author: Eric M. Ludlam <zappo@gnu.org> | |
7 ;; Keywords: project, make | |
8 | |
9 ;; This file is part of GNU Emacs. | |
10 | |
11 ;; GNU Emacs is free software: you can redistribute it and/or modify | |
12 ;; it under the terms of the GNU General Public License as published by | |
13 ;; the Free Software Foundation, either version 3 of the License, or | |
14 ;; (at your option) any later version. | |
15 | |
16 ;; GNU Emacs is distributed in the hope that it will be useful, | |
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 ;; GNU General Public License for more details. | |
20 | |
21 ;; You should have received a copy of the GNU General Public License | |
22 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |
23 | |
24 ;;; Commentary: | |
25 ;; | |
26 ;; Code generator for Makefiles. | |
27 ;; | |
28 ;; Here is how it should work: | |
29 ;; 1) Collect information about the project and targets | |
30 ;; 2) Insert header into the Makefile | |
31 ;; 3) Insert basic variables (target/source) | |
32 ;; 4) Conditional | |
33 ;; a) Makefile | |
34 ;; 1) Insert support variables (compiler variables, etc) | |
35 ;; 2) Insert VERSION and DISTDIR | |
36 ;; 3) Specify top build dir if necessary | |
37 ;; 4) Specify compile/link commands (c, etc) | |
38 ;; 5) Specify dependency files | |
39 ;; 6) Specify all: target | |
40 ;; 7) Include dependency files | |
41 ;; 8) Insert commonized target specify rules | |
42 ;; 9) Insert clean: and dist: rules | |
43 ;; b) Automake file | |
44 ;; 1) Insert distribution source variables for targets | |
45 ;; 2) Insert user requested rules | |
46 | |
47 (require 'ede/proj) | |
48 (require 'ede/proj-obj) | |
49 (require 'ede/proj-comp) | |
50 | |
51 ;;; Code: | |
52 (defmethod ede-proj-makefile-create ((this ede-proj-project) mfilename) | |
53 "Create a Makefile for all Makefile targets in THIS. | |
54 MFILENAME is the makefile to generate." | |
55 (let ((mt nil) | |
56 (isdist (string= mfilename (ede-proj-dist-makefile this))) | |
57 (depth 0) | |
58 (orig-buffer nil) | |
59 (buff-to-kill nil) | |
60 ) | |
61 ;; Find out how deep this project is. | |
62 (let ((tmp this)) | |
63 (while (setq tmp (ede-parent-project tmp)) | |
64 (setq depth (1+ depth)))) | |
65 ;; Collect the targets that belong in a makefile. | |
66 (mapc | |
67 (lambda (obj) | |
68 (if (and (obj-of-class-p obj 'ede-proj-target-makefile) | |
69 (string= (oref obj makefile) mfilename)) | |
70 (setq mt (cons obj mt)))) | |
71 (oref this targets)) | |
72 ;; Fix the order so things compile in the right direction. | |
73 (setq mt (nreverse mt)) | |
74 ;; Add in the header part of the Makefile* | |
75 (save-excursion | |
76 (setq orig-buffer (get-file-buffer mfilename)) | |
77 (set-buffer (setq buff-to-kill (find-file-noselect mfilename))) | |
78 (goto-char (point-min)) | |
79 (if (and | |
80 (not (eobp)) | |
81 (not (looking-at "# Automatically Generated \\w+ by EDE."))) | |
82 (if (not (y-or-n-p (format "Really replace %s? " mfilename))) | |
83 (error "Not replacing Makefile")) | |
84 (message "Replace EDE Makefile")) | |
85 (erase-buffer) | |
86 (ede-srecode-setup) | |
87 ;; Insert a giant pile of stuff that is common between | |
88 ;; one of our Makefiles, and a Makefile.in | |
89 (ede-srecode-insert | |
90 "file:ede-empty" | |
91 "MAKETYPE" | |
92 (with-slots (makefile-type) this | |
93 (cond ((eq makefile-type 'Makefile) "make") | |
94 ((eq makefile-type 'Makefile.in) "autoconf") | |
95 ((eq makefile-type 'Makefile.am) "automake") | |
96 (t (error ":makefile-type in project invalid"))))) | |
97 | |
98 ;; Just this project's variables | |
99 (ede-proj-makefile-insert-variables this) | |
100 | |
101 ;; Space | |
102 (insert "\n") | |
103 | |
104 (cond | |
105 ((eq (oref this makefile-type) 'Makefile) | |
106 ;; Make sure the user has the right kind of make | |
107 (ede-make-check-version) | |
108 | |
109 (let* ((targ (if isdist (oref this targets) mt)) | |
110 (sp (oref this subproj)) | |
111 (df (apply 'append | |
112 (mapcar (lambda (tg) | |
113 (ede-proj-makefile-dependency-files tg)) | |
114 targ)))) | |
115 ;; Distribution variables | |
116 (ede-compiler-begin-unique | |
117 (mapc 'ede-proj-makefile-insert-variables targ)) | |
118 ;; Only add the distribution stuff in when depth != 0 | |
119 (let ((top (ede-toplevel this)) | |
120 (tmp this) | |
121 (subdir "")) | |
122 (insert "VERSION=" (oref top version) "\n" | |
123 "DISTDIR=$(top)" (oref top name) "-$(VERSION)") | |
124 (while (ede-parent-project tmp) | |
125 (setq subdir | |
126 (concat | |
127 "/" | |
128 (file-name-nondirectory | |
129 (directory-file-name | |
130 (file-name-directory (oref tmp file)))) | |
131 subdir) | |
132 tmp (ede-parent-project tmp))) | |
133 (insert subdir "\n")) | |
134 ;; Some built in variables for C code | |
135 (if df | |
136 (let ((tc depth)) | |
137 (insert "top_builddir = ") | |
138 (while (/= 0 tc) | |
139 (setq tc (1- tc)) | |
140 (insert "..") | |
141 (if (/= tc 0) (insert "/"))) | |
142 (insert "\n"))) | |
143 (insert "\n") | |
144 ;; Create a variable with all the dependency files to include | |
145 ;; These methods borrowed from automake. | |
146 (if (and (oref this automatic-dependencies) df) | |
147 (progn | |
148 (insert "DEP_FILES=" | |
149 (mapconcat (lambda (f) | |
150 (concat ".deps/" | |
151 (file-name-nondirectory | |
152 (file-name-sans-extension | |
153 f)) ".P")) | |
154 df " ")))) | |
155 ;; | |
156 ;; Insert ALL Rule | |
157 ;; | |
158 (insert "\n\nall:") | |
159 (mapc (lambda (c) | |
160 (if (and (slot-exists-p c 'partofall) (oref c partofall)) | |
161 ;; Only insert this rule if it is a part of ALL. | |
162 (insert " " (ede-proj-makefile-target-name c)))) | |
163 targ) | |
164 (mapc (lambda (c) | |
165 (insert " " (ede-name c)) | |
166 ) | |
167 sp) | |
168 (insert "\n\n") | |
169 ;; | |
170 ;; Add in the include files | |
171 ;; | |
172 (mapc (lambda (c) | |
173 (insert "include " c "\n\n")) | |
174 (oref this include-file)) | |
175 ;; Some C inference rules | |
176 ;; Dependency rules borrowed from automake. | |
177 ;; | |
178 ;; NOTE: This is GNU Make specific. | |
179 (if (and (oref this automatic-dependencies) df) | |
180 (insert "DEPS_MAGIC := $(shell mkdir .deps > /dev/null " | |
181 "2>&1 || :)\n" | |
182 "-include $(DEP_FILES)\n\n")) | |
183 ;; | |
184 ;; General makefile rules stored in the individual targets | |
185 ;; | |
186 (ede-compiler-begin-unique | |
187 (ede-proj-makefile-insert-rules this) | |
188 (mapc 'ede-proj-makefile-insert-rules targ)) | |
189 ;; | |
190 ;; phony targets for sub projects | |
191 ;; | |
192 (mapc 'ede-proj-makefile-insert-subproj-rules sp) | |
193 ;; | |
194 ;; Distribution rules such as CLEAN and DIST | |
195 ;; | |
196 (when isdist | |
197 (ede-proj-makefile-tags this mt) | |
198 (ede-proj-makefile-insert-dist-rules this))) | |
199 (save-buffer)) | |
200 ((eq (oref this makefile-type) 'Makefile.in) | |
201 (error "Makefile.in is not supported")) | |
202 ((eq (oref this makefile-type) 'Makefile.am) | |
203 (require 'ede-pconf) | |
204 ;; Distribution variables | |
205 (let ((targ (if isdist (oref this targets) mt))) | |
206 (ede-compiler-begin-unique | |
207 (mapc 'ede-proj-makefile-insert-automake-pre-variables targ)) | |
208 (ede-compiler-begin-unique | |
209 (mapc 'ede-proj-makefile-insert-source-variables targ)) | |
210 (ede-compiler-begin-unique | |
211 (mapc 'ede-proj-makefile-insert-automake-post-variables targ)) | |
212 (ede-compiler-begin-unique | |
213 (ede-proj-makefile-insert-user-rules this)) | |
214 (insert "\n# End of Makefile.am\n") | |
215 (save-buffer)) | |
216 ) | |
217 (t (error "Unknown makefile type when generating Makefile"))) | |
218 ;; Put the cursor in a nice place | |
219 (goto-char (point-min))) | |
220 ;; If we have an original buffer, then don't kill it. | |
221 (when (not orig-buffer) | |
222 (kill-buffer buff-to-kill)) | |
223 )) | |
224 | |
225 ;;; VARIABLE insertion | |
226 ;; | |
227 (defun ede-pmake-end-of-variable () | |
228 "Move to the end of the variable declaration under point." | |
229 (end-of-line) | |
230 (while (= (preceding-char) ?\\) | |
231 (forward-char 1) | |
232 (end-of-line)) | |
233 ) | |
234 | |
235 (defmacro ede-pmake-insert-variable-shared (varname &rest body) | |
236 "Add VARNAME into the current Makefile. | |
237 Execute BODY in a location where a value can be placed." | |
238 `(let ((addcr t) (v ,varname)) | |
239 (if (re-search-backward (concat "^" v "\\s-*=") nil t) | |
240 (progn | |
241 (ede-pmake-end-of-variable) | |
242 (if (< (current-column) 40) | |
243 (if (and (/= (preceding-char) ?=) | |
244 (/= (preceding-char) ? )) | |
245 (insert " ")) | |
246 (insert "\\\n ")) | |
247 (setq addcr nil)) | |
248 (insert v "=")) | |
249 ,@body | |
250 (if addcr (insert "\n")) | |
251 (goto-char (point-max)))) | |
252 (put 'ede-pmake-insert-variable-shared 'lisp-indent-function 1) | |
253 | |
254 ;;; SOURCE VARIABLE NAME CONSTRUCTION | |
255 | |
256 (defsubst ede-pmake-varname (obj) | |
257 "Convert OBJ into a variable name name. | |
258 Change . to _ in the variable name." | |
259 (let ((name (oref obj name))) | |
260 (while (string-match "\\." name) | |
261 (setq name (replace-match "_" nil t name))) | |
262 name)) | |
263 | |
264 (defmethod ede-proj-makefile-sourcevar ((this ede-proj-target)) | |
265 "Return the variable name for THIS's sources." | |
266 (concat (ede-pmake-varname this) "_YOU_FOUND_A_BUG")) | |
267 | |
268 ;;; DEPENDENCY FILE GENERATOR LISTS | |
269 ;; | |
270 (defmethod ede-proj-makefile-dependency-files ((this ede-proj-target)) | |
271 "Return a list of source files to convert to dependencies. | |
272 Argument THIS is the target to get sources from." | |
273 nil) | |
274 | |
275 ;;; GENERIC VARIABLES | |
276 ;; | |
277 (defmethod ede-proj-makefile-configuration-variables ((this ede-proj-project) | |
278 configuration) | |
279 "Return a list of configuration variables from THIS. | |
280 Use CONFIGURATION as the current configuration to query." | |
281 (cdr (assoc configuration (oref this configuration-variables)))) | |
282 | |
283 (defmethod ede-proj-makefile-insert-variables-new ((this ede-proj-project)) | |
284 "Insert variables needed by target THIS. | |
285 | |
286 NOTE: Not yet in use! This is part of an SRecode conversion of | |
287 EDE that is in progress." | |
288 ; (let ((conf-table (ede-proj-makefile-configuration-variables | |
289 ; this (oref this configuration-default))) | |
290 ; (conf-done nil)) | |
291 ; | |
292 ; (ede-srecode-insert-with-dictionary | |
293 ; "declaration:ede-vars" | |
294 ; | |
295 ; ;; Insert all variables, and augment them with details from | |
296 ; ;; the current configuration. | |
297 ; (mapc (lambda (c) | |
298 ; | |
299 ; (let ((ldict (srecode-dictionary-add-section-dictionary | |
300 ; dict "VARIABLE")) | |
301 ; ) | |
302 ; (srecode-dictionary-set-value ldict "NAME" (car c)) | |
303 ; (if (assoc (car c) conf-table) | |
304 ; (let ((vdict (srecode-dictionary-add-section-dictionary | |
305 ; ldict "VALUE"))) | |
306 ; (srecode-dictionary-set-value | |
307 ; vdict "VAL" (cdr (assoc (car c) conf-table))) | |
308 ; (setq conf-done (cons (car c) conf-done)))) | |
309 ; (let ((vdict (srecode-dictionary-add-section-dictionary | |
310 ; ldict "VALUE"))) | |
311 ; (srecode-dictionary-set-value vdict "VAL" (cdr c)))) | |
312 ; ) | |
313 ; | |
314 ; (oref this variables)) | |
315 ; | |
316 ; ;; Add in all variables from the configuration not allready covered. | |
317 ; (mapc (lambda (c) | |
318 ; | |
319 ; (if (member (car c) conf-done) | |
320 ; nil | |
321 ; (let* ((ldict (srecode-dictionary-add-section-dictionary | |
322 ; dict "VARIABLE")) | |
323 ; (vdict (srecode-dictionary-add-section-dictionary | |
324 ; ldict "VALUE")) | |
325 ; ) | |
326 ; (srecode-dictionary-set-value ldict "NAME" (car c)) | |
327 ; (srecode-dictionary-set-value vdict "VAL" (cdr c)))) | |
328 ; ) | |
329 ; | |
330 ; conf-table) | |
331 ; | |
332 | |
333 ;; @TODO - finish off this function, and replace the below fcn | |
334 | |
335 ; )) | |
336 ) | |
337 | |
338 (defmethod ede-proj-makefile-insert-variables ((this ede-proj-project)) | |
339 "Insert variables needed by target THIS." | |
340 (let ((conf-table (ede-proj-makefile-configuration-variables | |
341 this (oref this configuration-default))) | |
342 (conf-done nil)) | |
343 ;; Insert all variables, and augment them with details from | |
344 ;; the current configuration. | |
345 (mapc (lambda (c) | |
346 (insert (car c) "=") | |
347 (if (assoc (car c) conf-table) | |
348 (progn | |
349 (insert (cdr (assoc (car c) conf-table)) " ") | |
350 (setq conf-done (cons (car c) conf-done)))) | |
351 (insert (cdr c) "\n")) | |
352 (oref this variables)) | |
353 ;; Add in all variables from the configuration not allready covered. | |
354 (mapc (lambda (c) | |
355 (if (member (car c) conf-done) | |
356 nil | |
357 (insert (car c) "=" (cdr c) "\n"))) | |
358 conf-table)) | |
359 (let* ((top "") | |
360 (tmp this)) | |
361 (while (ede-parent-project tmp) | |
362 (setq tmp (ede-parent-project tmp) | |
363 top (concat "../" top))) | |
364 (insert "\ntop=" top)) | |
365 (insert "\nede_FILES=" (file-name-nondirectory (oref this file)) " " | |
366 (file-name-nondirectory (ede-proj-dist-makefile this)) "\n")) | |
367 | |
368 (defmethod ede-proj-makefile-insert-source-variables ((this ede-proj-target) | |
369 &optional | |
370 moresource) | |
371 "Insert the source variables needed by THIS. | |
372 Optional argument MORESOURCE is a list of additional sources to add to the | |
373 sources variable." | |
374 (let ((sv (ede-proj-makefile-sourcevar this))) | |
375 ;; This variable may be shared between targets | |
376 (ede-pmake-insert-variable-shared (cond ((listp sv) (car sv)) | |
377 (t sv)) | |
378 (insert (mapconcat (lambda (a) a) (oref this source) " ")) | |
379 (if moresource | |
380 (insert " \\\n " (mapconcat (lambda (a) a) moresource " ") ""))))) | |
381 | |
382 (defmethod ede-proj-makefile-insert-variables ((this ede-proj-target) &optional | |
383 moresource) | |
384 "Insert variables needed by target THIS. | |
385 Optional argument MORESOURCE is a list of additional sources to add to the | |
386 sources variable." | |
387 (ede-proj-makefile-insert-source-variables this moresource) | |
388 ) | |
389 | |
390 (defmethod ede-proj-makefile-configuration-variables ((this ede-proj-target-makefile) | |
391 configuration) | |
392 "Return a list of configuration variables from THIS. | |
393 Use CONFIGURATION as the current configuration to query." | |
394 (cdr (assoc configuration (oref this configuration-variables)))) | |
395 | |
396 (defmethod ede-proj-makefile-insert-variables ((this ede-proj-target-makefile) | |
397 &optional moresource) | |
398 "Insert variables needed by target THIS. | |
399 Optional argument MORESOURCE is a list of additional sources to add to the | |
400 sources variable." | |
401 (call-next-method) | |
402 (let* ((proj (ede-target-parent this)) | |
403 (conf-table (ede-proj-makefile-configuration-variables | |
404 this (oref proj configuration-default))) | |
405 (conf-done nil) | |
406 ) | |
407 ;; Add in all variables from the configuration not allready covered. | |
408 (mapc (lambda (c) | |
409 (if (member (car c) conf-done) | |
410 nil | |
411 (insert (car c) "=" (cdr c) "\n"))) | |
412 conf-table)) | |
413 (let ((comp (ede-proj-compilers this)) | |
414 (link (ede-proj-linkers this)) | |
415 (name (ede-proj-makefile-target-name this)) | |
416 (src (oref this source))) | |
417 (while comp | |
418 (ede-compiler-only-once (car comp) | |
419 (ede-proj-makefile-insert-object-variables (car comp) name src) | |
420 (ede-proj-makefile-insert-variables (car comp))) | |
421 (setq comp (cdr comp))) | |
422 (while link | |
423 (ede-linker-only-once (car link) | |
424 (ede-proj-makefile-insert-variables (car link))) | |
425 (setq link (cdr link))))) | |
426 | |
427 (defmethod ede-proj-makefile-insert-automake-pre-variables | |
428 ((this ede-proj-target)) | |
429 "Insert variables needed by target THIS in Makefile.am before SOURCES." | |
430 nil) | |
431 | |
432 (defmethod ede-proj-makefile-insert-automake-post-variables | |
433 ((this ede-proj-target)) | |
434 "Insert variables needed by target THIS in Makefile.am after SOURCES." | |
435 nil) | |
436 | |
437 ;;; GARBAGE PATTERNS | |
438 ;; | |
439 (defmethod ede-proj-makefile-garbage-patterns ((this ede-proj-project)) | |
440 "Return a list of patterns that are considered garbage to THIS. | |
441 These are removed with make clean." | |
442 (let ((mc (ede-map-targets | |
443 this (lambda (c) (ede-proj-makefile-garbage-patterns c)))) | |
444 (uniq nil)) | |
445 (setq mc (sort (apply 'append mc) 'string<)) | |
446 ;; Filter out duplicates from the targets. | |
447 (while mc | |
448 (if (and (car uniq) (string= (car uniq) (car mc))) | |
449 nil | |
450 (setq uniq (cons (car mc) uniq))) | |
451 (setq mc (cdr mc))) | |
452 (nreverse uniq))) | |
453 | |
454 (defmethod ede-proj-makefile-garbage-patterns ((this ede-proj-target)) | |
455 "Return a list of patterns that are considered garbage to THIS. | |
456 These are removed with make clean." | |
457 ;; Get the the source object from THIS, and use the specified garbage. | |
458 (let ((src (ede-target-sourcecode this)) | |
459 (garb nil)) | |
460 (while src | |
461 (setq garb (append (oref (car src) garbagepattern) garb) | |
462 src (cdr src))) | |
463 garb)) | |
464 | |
465 | |
466 ;;; RULES | |
467 ;; | |
468 (defmethod ede-proj-makefile-insert-subproj-rules ((this ede-proj-project)) | |
469 "Insert a rule for the project THIS which should be a subproject." | |
470 (insert ".PHONY:" (ede-name this)) | |
471 (newline) | |
472 (insert (ede-name this) ":") | |
473 (newline) | |
474 (insert "\t$(MAKE) -C " (directory-file-name (ede-subproject-relative-path this))) | |
475 (newline) | |
476 (newline) | |
477 ) | |
478 | |
479 (defmethod ede-proj-makefile-insert-rules ((this ede-proj-project)) | |
480 "Insert rules needed by THIS target." | |
481 (mapc 'ede-proj-makefile-insert-rules (oref this inference-rules)) | |
482 ) | |
483 | |
484 (defmethod ede-proj-makefile-insert-dist-dependencies ((this ede-proj-project)) | |
485 "Insert any symbols that the DIST rule should depend on. | |
486 Argument THIS is the project that should insert stuff." | |
487 (mapc 'ede-proj-makefile-insert-dist-dependencies (oref this targets)) | |
488 ) | |
489 | |
490 (defmethod ede-proj-makefile-insert-dist-dependencies ((this ede-proj-target)) | |
491 "Insert any symbols that the DIST rule should depend on. | |
492 Argument THIS is the target that should insert stuff." | |
493 nil) | |
494 | |
495 (defmethod ede-proj-makefile-insert-dist-filepatterns ((this ede-proj-target)) | |
496 "Insert any symbols that the DIST rule should depend on. | |
497 Argument THIS is the target that should insert stuff." | |
498 (ede-proj-makefile-insert-dist-dependencies this) | |
499 ) | |
500 | |
501 (defmethod ede-proj-makefile-insert-dist-rules ((this ede-proj-project)) | |
502 "Insert distribution rules for THIS in a Makefile, such as CLEAN and DIST." | |
503 (let ((junk (ede-proj-makefile-garbage-patterns this)) | |
504 tmp) | |
505 ;; Build CLEAN, DIST, TAG, and other rules here. | |
506 (if junk | |
507 (insert "\nclean:\n" | |
508 "\trm -f " | |
509 (mapconcat (lambda (c) c) junk " ") | |
510 "\n\n")) | |
511 ;; @TODO: ^^^ Clean should also recurse. ^^^ | |
512 | |
513 (insert ".PHONY: dist\n") | |
514 (insert "\ndist:") | |
515 (ede-proj-makefile-insert-dist-dependencies this) | |
516 (insert "\n") | |
517 (unless (or (ede-subproject-p this) | |
518 (oref this metasubproject)) | |
519 ;; Only delete if we are the toplevel project. | |
520 (insert "\trm -rf $(DISTDIR)\n")) | |
521 (insert "\tmkdir $(DISTDIR)\n") ;We may need a -p, but I think not. | |
522 (setq tmp (oref this targets)) | |
523 (insert "\tcp") | |
524 (while tmp | |
525 (let ((sv (ede-proj-makefile-sourcevar (car tmp)))) | |
526 (if (listp sv) | |
527 ;; Handle special case variables. | |
528 (cond ((eq (cdr sv) 'share) | |
529 ;; This variable may be shared between multiple targets. | |
530 (if (re-search-backward (concat "\\$(" (car sv) ")") | |
531 (save-excursion | |
532 (beginning-of-line) | |
533 (point)) | |
534 t) | |
535 ;; If its already in the dist target, then skip it. | |
536 nil | |
537 (setq sv (car sv)))) | |
538 (t (setq sv (car sv))))) | |
539 (if (stringp sv) | |
540 (insert " $(" sv ")")) | |
541 (ede-proj-makefile-insert-dist-filepatterns (car tmp)) | |
542 (setq tmp (cdr tmp)))) | |
543 (insert " $(ede_FILES) $(DISTDIR)\n") | |
544 | |
545 ;; Call our sub projects. | |
546 (ede-map-subprojects | |
547 this (lambda (sproj) | |
548 (let ((rp (directory-file-name (ede-subproject-relative-path sproj)))) | |
549 (insert "\t$(MAKE) -C " rp " $(MFLAGS) DISTDIR=$(DISTDIR)/" rp | |
550 " dist" | |
551 "\n")))) | |
552 | |
553 ;; Tar up the stuff. | |
554 (unless (or (ede-subproject-p this) | |
555 (oref this metasubproject)) | |
556 (insert "\ttar -cvzf $(DISTDIR).tar.gz $(DISTDIR)\n" | |
557 "\trm -rf $(DISTDIR)\n")) | |
558 | |
559 ;; Make sure the Makefile is ok. | |
560 (insert "\n" | |
561 (file-name-nondirectory (buffer-file-name)) ": " | |
562 (file-name-nondirectory (oref this file)) "\n" | |
563 ;; "$(EMACS) -batch Project.ede -l ede -f ede-proj-regenerate" | |
564 "\t@echo Makefile is out of date! " | |
565 "It needs to be regenerated by EDE.\n" | |
566 "\t@echo If you have not modified Project.ede, you can" | |
567 " use 'touch' to update the Makefile time stamp.\n" | |
568 "\t@false\n\n" | |
569 "\n\n# End of Makefile\n"))) | |
570 | |
571 (defmethod ede-proj-makefile-insert-rules ((this ede-proj-target)) | |
572 "Insert rules needed by THIS target." | |
573 nil) | |
574 | |
575 (defmethod ede-proj-makefile-insert-rules ((this ede-proj-target-makefile)) | |
576 "Insert rules needed by THIS target." | |
577 (mapc 'ede-proj-makefile-insert-rules (oref this rules)) | |
578 (let ((c (ede-proj-compilers this))) | |
579 (when c | |
580 (mapc 'ede-proj-makefile-insert-rules c) | |
581 (if (oref this phony) | |
582 (insert ".PHONY: " (ede-proj-makefile-target-name this) "\n")) | |
583 (insert (ede-proj-makefile-target-name this) ": " | |
584 (ede-proj-makefile-dependencies this) "\n") | |
585 (ede-proj-makefile-insert-commands this) | |
586 ))) | |
587 | |
588 (defmethod ede-proj-makefile-insert-commands ((this ede-proj-target-makefile)) | |
589 "Insert the commands needed by target THIS. | |
590 For targets, insert the commands needed by the chosen compiler." | |
591 (mapc 'ede-proj-makefile-insert-commands (ede-proj-compilers this)) | |
592 (when (object-assoc t :uselinker (ede-proj-compilers this)) | |
593 (mapc 'ede-proj-makefile-insert-commands (ede-proj-linkers this)))) | |
594 | |
595 | |
596 (defmethod ede-proj-makefile-insert-user-rules ((this ede-proj-project)) | |
597 "Insert user specified rules needed by THIS target. | |
598 This is different from `ede-proj-makefile-insert-rules' in that this | |
599 function won't create the building rules which are auto created with | |
600 automake." | |
601 (mapc 'ede-proj-makefile-insert-user-rules (oref this inference-rules))) | |
602 | |
603 (defmethod ede-proj-makefile-insert-user-rules ((this ede-proj-target)) | |
604 "Insert user specified rules needed by THIS target." | |
605 (mapc 'ede-proj-makefile-insert-rules (oref this rules))) | |
606 | |
607 (defmethod ede-proj-makefile-dependencies ((this ede-proj-target-makefile)) | |
608 "Return a string representing the dependencies for THIS. | |
609 Some compilers only use the first element in the dependencies, others | |
610 have a list of intermediates (object files), and others don't care. | |
611 This allows customization of how these elements appear." | |
612 (let* ((c (ede-proj-compilers this)) | |
613 (io (ede-or (mapcar 'ede-compiler-intermediate-objects-p c))) | |
614 (out nil)) | |
615 (if io | |
616 (progn | |
617 (while c | |
618 (setq out | |
619 (concat out "$(" (ede-compiler-intermediate-object-variable | |
620 (car c) | |
621 (ede-proj-makefile-target-name this)) ")") | |
622 c (cdr c))) | |
623 out) | |
624 (let ((sv (ede-proj-makefile-sourcevar this)) | |
625 (aux (oref this auxsource))) | |
626 (setq out | |
627 (if (and (stringp sv) (not (string= sv ""))) | |
628 (concat "$(" sv ")") | |
629 "")) | |
630 (while aux | |
631 (setq out (concat out " " (car aux))) | |
632 (setq aux (cdr aux))) | |
633 out)))) | |
634 | |
635 ;; Tags | |
636 (defmethod ede-proj-makefile-tags ((this ede-proj-project) targets) | |
637 "Insert into the current location rules to make recursive TAGS files. | |
638 Argument THIS is the project to create tags for. | |
639 Argument TARGETS are the targets we should depend on for TAGS." | |
640 (insert "tags: ") | |
641 (let ((tg targets)) | |
642 ;; Loop over all source variables and insert them | |
643 (while tg | |
644 (insert "$(" (ede-proj-makefile-sourcevar (car tg)) ") ") | |
645 (setq tg (cdr tg))) | |
646 (insert "\n") | |
647 (if targets | |
648 (insert "\tetags $^\n")) | |
649 ;; Now recurse into all subprojects | |
650 (setq tg (oref this subproj)) | |
651 (while tg | |
652 (insert "\t$(MAKE) -C " (ede-subproject-relative-path (car tg)) " $(MFLAGS) $@\n") | |
653 (setq tg (cdr tg))) | |
654 (insert "\n"))) | |
655 | |
656 | |
657 (provide 'ede/pmake) | |
658 | |
659 ;;; ede/pmake.el ends here |