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