Function: vhdl-generate-makefile-1
vhdl-generate-makefile-1 is a byte-compiled function defined in
vhdl-mode.el.gz.
Signature
(vhdl-generate-makefile-1)
Documentation
Generate Makefile for current project or directory.
Source Code
;; Defined in /usr/src/emacs/lisp/progmodes/vhdl-mode.el.gz
(defun vhdl-generate-makefile-1 ()
"Generate Makefile for current project or directory."
;; scan hierarchy if required
(if (vhdl-project-p)
(unless (or (assoc vhdl-project vhdl-file-alist)
(vhdl-load-cache vhdl-project))
(vhdl-scan-project-contents vhdl-project))
(let ((directory (abbreviate-file-name default-directory)))
(unless (or (assoc directory vhdl-file-alist)
(vhdl-load-cache directory))
(vhdl-scan-directory-contents directory))))
(defvar rule-alist) ; we need it to be dynamically bound
(let* ((directory (abbreviate-file-name (vhdl-default-directory)))
(project (vhdl-project-p))
(ent-alist (vhdl-aget vhdl-entity-alist (or project directory)))
(conf-alist (vhdl-aget vhdl-config-alist (or project directory)))
(pack-alist (vhdl-aget vhdl-package-alist (or project directory)))
(regexp-list (or (nth 12 (vhdl-aget vhdl-compiler-alist vhdl-compiler))
'("\\1.vhd" "\\2_\\1.vhd" "\\1.vhd"
"\\1.vhd" "\\1_body.vhd" identity)))
(mapping-exist
(if (nth 12 (vhdl-aget vhdl-compiler-alist vhdl-compiler)) t nil))
(ent-regexp (cons "\\(.*\\) \\(.*\\) \\(.*\\)" (nth 0 regexp-list)))
(arch-regexp (cons "\\(.*\\) \\(.*\\) \\(.*\\)" (nth 1 regexp-list)))
(conf-regexp (cons "\\(.*\\) \\(.*\\) \\(.*\\)" (nth 2 regexp-list)))
(pack-regexp (cons "\\(.*\\) \\(.*\\) \\(.*\\)" (nth 3 regexp-list)))
(pack-body-regexp (cons "\\(.*\\) \\(.*\\) \\(.*\\)" (nth 4 regexp-list)))
(adjust-case (nth 5 regexp-list))
(work-library (downcase (vhdl-work-library)))
(compile-directory (expand-file-name (vhdl-compile-directory)
default-directory))
(makefile-name (vhdl-makefile-name))
rule-alist arch-alist inst-alist
target-list depend-list unit-list prim-list second-list subcomp-list
lib-alist lib-body-alist pack-list all-pack-list
ent-key ent-file-name arch-key arch-file-name ent-arch-key
conf-key conf-file-name pack-key pack-file-name
ent-entry arch-entry conf-entry pack-entry inst-entry
pack-body-key pack-body-file-name inst-ent-key inst-conf-key
tmp-key tmp-list rule)
;; check prerequisites
(unless (file-exists-p compile-directory)
(make-directory compile-directory t))
(unless mapping-exist
(vhdl-warning
(format "No unit-to-file name mapping found for compiler \"%s\".\n Directory of dummy files is created instead (to be used as dependencies).\n Please contact the VHDL Mode maintainer for full support of \"%s\""
vhdl-compiler vhdl-compiler) t))
(message "Generating makefile \"%s\"..." makefile-name)
;; rules for all entities
(setq tmp-list ent-alist)
(while ent-alist
(setq ent-entry (car ent-alist)
ent-key (nth 0 ent-entry))
(when (nth 2 ent-entry)
(setq ent-file-name (if vhdl-compile-absolute-path
(nth 2 ent-entry)
(file-relative-name (nth 2 ent-entry)
compile-directory))
arch-alist (nth 4 ent-entry)
lib-alist (nth 6 ent-entry)
rule (vhdl-aget rule-alist ent-file-name)
target-list (nth 0 rule)
depend-list (nth 1 rule)
second-list nil
subcomp-list nil)
(setq tmp-key (vhdl-replace-string
ent-regexp
(funcall adjust-case
(concat ent-key " " work-library))))
(push (cons ent-key tmp-key) unit-list)
;; rule target for this entity
(push ent-key target-list)
;; rule dependencies for all used packages
(setq pack-list (vhdl-get-packages lib-alist work-library))
(setq depend-list (append depend-list pack-list))
(setq all-pack-list pack-list)
;; add rule
(vhdl-aput 'rule-alist ent-file-name (list target-list depend-list))
;; rules for all corresponding architectures
(while arch-alist
(setq arch-entry (car arch-alist)
arch-key (nth 0 arch-entry)
ent-arch-key (concat ent-key "-" arch-key)
arch-file-name (if vhdl-compile-absolute-path
(nth 2 arch-entry)
(file-relative-name (nth 2 arch-entry)
compile-directory))
inst-alist (nth 4 arch-entry)
lib-alist (nth 5 arch-entry)
rule (vhdl-aget rule-alist arch-file-name)
target-list (nth 0 rule)
depend-list (nth 1 rule))
(setq tmp-key (vhdl-replace-string
arch-regexp
(funcall adjust-case
(concat arch-key " " ent-key " "
work-library))))
(setq unit-list
(cons (cons ent-arch-key tmp-key) unit-list))
(push ent-arch-key second-list)
;; rule target for this architecture
(push ent-arch-key target-list)
;; rule dependency for corresponding entity
(push ent-key depend-list)
;; rule dependencies for contained component instantiations
(while inst-alist
(setq inst-entry (car inst-alist))
(when (or (null (nth 8 inst-entry))
(equal (downcase (nth 8 inst-entry)) work-library))
(setq inst-ent-key (or (nth 7 inst-entry)
(nth 5 inst-entry)))
(setq depend-list (cons inst-ent-key depend-list)
subcomp-list (cons inst-ent-key subcomp-list)))
(setq inst-alist (cdr inst-alist)))
;; rule dependencies for all used packages
(setq pack-list (vhdl-get-packages lib-alist work-library))
(setq depend-list (append depend-list pack-list))
(setq all-pack-list (append all-pack-list pack-list))
;; add rule
(vhdl-aput 'rule-alist arch-file-name (list target-list depend-list))
(setq arch-alist (cdr arch-alist)))
(push (list ent-key second-list (append subcomp-list all-pack-list))
prim-list))
(setq ent-alist (cdr ent-alist)))
(setq ent-alist tmp-list)
;; rules for all configurations
(setq tmp-list conf-alist)
(while conf-alist
(setq conf-entry (car conf-alist)
conf-key (nth 0 conf-entry)
conf-file-name (if vhdl-compile-absolute-path
(nth 2 conf-entry)
(file-relative-name (nth 2 conf-entry)
compile-directory))
ent-key (nth 4 conf-entry)
arch-key (nth 5 conf-entry)
inst-alist (nth 6 conf-entry)
lib-alist (nth 7 conf-entry)
rule (vhdl-aget rule-alist conf-file-name)
target-list (nth 0 rule)
depend-list (nth 1 rule)
subcomp-list (list ent-key))
(setq tmp-key (vhdl-replace-string
conf-regexp
(funcall adjust-case
(concat conf-key " " work-library))))
(push (cons conf-key tmp-key) unit-list)
;; rule target for this configuration
(push conf-key target-list)
;; rule dependency for corresponding entity and architecture
(setq depend-list
(cons ent-key (cons (concat ent-key "-" arch-key) depend-list)))
;; rule dependencies for used packages
(setq pack-list (vhdl-get-packages lib-alist work-library))
(setq depend-list (append depend-list pack-list))
;; rule dependencies for contained component configurations
(while inst-alist
(setq inst-entry (car inst-alist))
(setq inst-ent-key (nth 2 inst-entry)
inst-conf-key (nth 4 inst-entry))
(when (equal (downcase (nth 5 inst-entry)) work-library)
(when inst-ent-key
(setq depend-list (cons inst-ent-key depend-list)
subcomp-list (cons inst-ent-key subcomp-list)))
(when inst-conf-key
(setq depend-list (cons inst-conf-key depend-list)
subcomp-list (cons inst-conf-key subcomp-list))))
(setq inst-alist (cdr inst-alist)))
;; add rule
(vhdl-aput 'rule-alist conf-file-name (list target-list depend-list))
(push (list conf-key nil (append subcomp-list pack-list)) prim-list)
(setq conf-alist (cdr conf-alist)))
(setq conf-alist tmp-list)
;; rules for all packages
(setq tmp-list pack-alist)
(while pack-alist
(setq pack-entry (car pack-alist)
pack-key (nth 0 pack-entry)
pack-body-key nil)
(when (nth 2 pack-entry)
(setq pack-file-name (if vhdl-compile-absolute-path
(nth 2 pack-entry)
(file-relative-name (nth 2 pack-entry)
compile-directory))
lib-alist (nth 6 pack-entry) lib-body-alist (nth 10 pack-entry)
rule (vhdl-aget rule-alist pack-file-name)
target-list (nth 0 rule) depend-list (nth 1 rule))
(setq tmp-key (vhdl-replace-string
pack-regexp
(funcall adjust-case
(concat pack-key " " work-library))))
(push (cons pack-key tmp-key) unit-list)
;; rule target for this package
(push pack-key target-list)
;; rule dependencies for all used packages
(setq pack-list (vhdl-get-packages lib-alist work-library))
(setq depend-list (append depend-list pack-list))
(setq all-pack-list pack-list)
;; add rule
(vhdl-aput 'rule-alist pack-file-name (list target-list depend-list))
;; rules for this package's body
(when (nth 7 pack-entry)
(setq pack-body-key (concat pack-key "-body")
pack-body-file-name (if vhdl-compile-absolute-path
(nth 7 pack-entry)
(file-relative-name (nth 7 pack-entry)
compile-directory))
rule (vhdl-aget rule-alist pack-body-file-name)
target-list (nth 0 rule)
depend-list (nth 1 rule))
(setq tmp-key (vhdl-replace-string
pack-body-regexp
(funcall adjust-case
(concat pack-key " " work-library))))
(setq unit-list
(cons (cons pack-body-key tmp-key) unit-list))
;; rule target for this package's body
(push pack-body-key target-list)
;; rule dependency for corresponding package declaration
(push pack-key depend-list)
;; rule dependencies for all used packages
(setq pack-list (vhdl-get-packages lib-body-alist work-library))
(setq depend-list (append depend-list pack-list))
(setq all-pack-list (append all-pack-list pack-list))
;; add rule
(vhdl-aput 'rule-alist pack-body-file-name
(list target-list depend-list)))
(setq prim-list
(cons (list pack-key (when pack-body-key (list pack-body-key))
all-pack-list)
prim-list)))
(setq pack-alist (cdr pack-alist)))
(setq pack-alist tmp-list)
;; generate Makefile
(let* ((project (vhdl-aget vhdl-project-alist project))
(compiler (vhdl-aget vhdl-compiler-alist vhdl-compiler))
(compiler-id (nth 9 compiler))
(library-directory
(vhdl-resolve-env-variable
(vhdl-replace-string
(cons "\\(.*\\)" (or (nth 7 project) (nth 7 compiler)))
compiler-id)))
(makefile-path-name (expand-file-name
makefile-name compile-directory))
(orig-buffer (current-buffer))
cell second-list subcomp-list options unit-key unit-name)
;; sort lists
(setq unit-list (vhdl-sort-alist unit-list))
(setq prim-list (vhdl-sort-alist prim-list))
(setq tmp-list rule-alist)
(while tmp-list ; pre-sort rule targets
(setq cell (cdar tmp-list))
(setcar cell (sort (car cell) #'string<))
(setq tmp-list (cdr tmp-list)))
(setq rule-alist ; sort by first rule target
(sort rule-alist
(lambda (a b)
(string< (car (cadr a)) (car (cadr b))))))
;; open and clear Makefile
(set-buffer (find-file-noselect makefile-path-name t t))
(erase-buffer)
(insert "# -*- Makefile -*-\n"
"### " (file-name-nondirectory makefile-name)
" - VHDL Makefile generated by Emacs VHDL Mode " vhdl-version
"\n")
(if project
(insert "\n# Project : " (nth 0 project))
(insert "\n# Directory : \"" directory "\""))
(insert "\n# Platform : " vhdl-compiler
"\n# Generated : " (format-time-string "%Y-%m-%d %T ")
(user-login-name) "\n")
;; insert compile and option variable settings
(insert "\n\n# Define compilation command and options\n"
"\nCOMPILE = " (nth 0 compiler)
"\nOPTIONS = " (vhdl-get-compile-options project compiler nil)
(if (equal vhdl-compile-post-command "") ""
(concat "\nPOST-COMPILE = " vhdl-compile-post-command))
"\n")
;; insert library paths
(setq library-directory
(directory-file-name
(if (file-name-absolute-p library-directory)
library-directory
(file-relative-name
(expand-file-name library-directory directory)
compile-directory))))
(insert "\n\n# Define library paths\n"
"\nLIBRARY-" work-library " = " library-directory "\n")
(unless mapping-exist
(insert "LIBRARY-" work-library "-make = " "$(LIBRARY-" work-library
")/make" "\n"))
;; insert variable definitions for all library unit files
(insert "\n\n# Define library unit files\n")
(setq tmp-list unit-list)
(while unit-list
(insert "\nUNIT-" work-library "-" (caar unit-list)
" = \\\n\t$(LIBRARY-" work-library
(if mapping-exist "" "-make") ")/" (cdar unit-list))
(setq unit-list (cdr unit-list)))
;; insert variable definition for list of all library unit files
(insert "\n\n\n# Define list of all library unit files\n"
"\nALL_UNITS =")
(setq unit-list tmp-list)
(while unit-list
(insert " \\\n\t" "$(UNIT-" work-library "-" (caar unit-list) ")")
(setq unit-list (cdr unit-list)))
(insert "\n")
(setq unit-list tmp-list)
;; insert `make all' rule
(insert "\n\n\n# Rule for compiling entire design\n"
"\n" (nth 0 vhdl-makefile-default-targets) " :"
" \\\n\t\t" (nth 2 vhdl-makefile-default-targets)
" \\\n\t\t$(ALL_UNITS)\n")
;; insert `make clean' rule
(insert "\n\n# Rule for cleaning entire design\n"
"\n" (nth 1 vhdl-makefile-default-targets) " : "
"\n\t-rm -f $(ALL_UNITS)\n")
;; insert `make library' rule
(insert "\n\n# Rule for creating library directory\n"
"\n" (nth 2 vhdl-makefile-default-targets) " :"
" \\\n\t\t$(LIBRARY-" work-library ")"
(if mapping-exist ""
(concat " \\\n\t\t$(LIBRARY-" work-library "-make)\n"))
"\n"
"\n$(LIBRARY-" work-library ") :"
"\n\t"
(vhdl-replace-string
(cons "\\(.*\\)\n\\(.*\\)" (nth 5 compiler))
(concat "$(LIBRARY-" work-library ")\n" (vhdl-work-library)))
"\n")
(unless mapping-exist
(insert "\n$(LIBRARY-" work-library "-make) :"
"\n\t"
"mkdir -p $(LIBRARY-" work-library "-make)\n"))
;; insert '.PHONY' declaration
(insert "\n\n.PHONY : "
(nth 0 vhdl-makefile-default-targets) " "
(nth 1 vhdl-makefile-default-targets) " "
(nth 2 vhdl-makefile-default-targets) "\n")
;; insert rule for each library unit
(insert "\n\n# Rules for compiling single library units and their subhierarchy\n")
(while prim-list
(setq second-list (sort (nth 1 (car prim-list)) #'string<))
(setq subcomp-list
(sort (vhdl-uniquify (nth 2 (car prim-list))) #'string<))
(setq unit-key (caar prim-list)
unit-name (or (nth 0 (vhdl-aget ent-alist unit-key))
(nth 0 (vhdl-aget conf-alist unit-key))
(nth 0 (vhdl-aget pack-alist unit-key))))
(insert "\n" unit-key)
(unless (equal unit-key unit-name)
(insert " \\\n" unit-name))
(insert " :"
" \\\n\t\t" (nth 2 vhdl-makefile-default-targets))
(while subcomp-list
(when (and (assoc (car subcomp-list) unit-list)
(not (equal unit-key (car subcomp-list))))
(insert " \\\n\t\t" (car subcomp-list)))
(setq subcomp-list (cdr subcomp-list)))
(insert " \\\n\t\t$(UNIT-" work-library "-" unit-key ")")
(while second-list
(insert " \\\n\t\t$(UNIT-" work-library "-" (car second-list) ")")
(setq second-list (cdr second-list)))
(insert "\n")
(setq prim-list (cdr prim-list)))
;; insert rule for each library unit file
(insert "\n\n# Rules for compiling single library unit files\n")
(while rule-alist
(setq rule (car rule-alist))
;; get compiler options for this file
(setq options
(vhdl-get-compile-options project compiler (nth 0 rule) t))
;; insert rule if file is supposed to be compiled
(setq target-list (nth 1 rule)
depend-list (sort (vhdl-uniquify (nth 2 rule)) #'string<))
;; insert targets
(setq tmp-list target-list)
(while target-list
(insert "\n$(UNIT-" work-library "-" (car target-list) ")"
(if (cdr target-list) " \\" " :"))
(setq target-list (cdr target-list)))
(setq target-list tmp-list)
;; insert file name as first dependency
(insert " \\\n\t\t" (nth 0 rule))
;; insert dependencies (except if also target or unit does not exist)
(while depend-list
(when (and (not (member (car depend-list) target-list))
(assoc (car depend-list) unit-list))
(insert " \\\n\t\t"
"$(UNIT-" work-library "-" (car depend-list) ")"))
(setq depend-list (cdr depend-list)))
;; insert compile command
(if options
(insert "\n\t$(COMPILE) "
(if (eq options 'default) "$(OPTIONS)" options) " "
(nth 0 rule)
(if (equal vhdl-compile-post-command "") ""
" $(POST-COMPILE)")
"\n")
(insert "\n"))
(unless (and options mapping-exist)
(setq tmp-list target-list)
(while target-list
(insert "\t@touch $(UNIT-" work-library "-" (car target-list) ")\n")
(setq target-list (cdr target-list)))
(setq target-list tmp-list))
(setq rule-alist (cdr rule-alist)))
(insert "\n\n### " makefile-name " ends here\n")
;; run Makefile generation hook
(run-hooks 'vhdl-makefile-generation-hook)
(message "Generating makefile \"%s\"...done" makefile-name)
;; save and close file
(if (file-writable-p makefile-path-name)
(progn (save-buffer)
(kill-buffer (current-buffer))
(set-buffer orig-buffer)
(when (fboundp 'add-to-history)
(add-to-history 'file-name-history makefile-path-name)))
(vhdl-warning-when-idle
(format "File not writable: \"%s\""
(abbreviate-file-name makefile-path-name)))
(switch-to-buffer (current-buffer))))))