proj-obj.el 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. ;;; ede/proj-obj.el --- EDE Generic Project Object code generation support
  2. ;;; Copyright (C) 1998-2000, 2005, 2008-2017 Free Software Foundation,
  3. ;;; Inc.
  4. ;; Author: Eric M. Ludlam <zappo@gnu.org>
  5. ;; Keywords: project, make
  6. ;; This file is part of GNU Emacs.
  7. ;; GNU Emacs is free software: you can redistribute it and/or modify
  8. ;; it under the terms of the GNU General Public License as published by
  9. ;; the Free Software Foundation, either version 3 of the License, or
  10. ;; (at your option) any later version.
  11. ;; GNU Emacs is distributed in the hope that it will be useful,
  12. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;; GNU General Public License for more details.
  15. ;; You should have received a copy of the GNU General Public License
  16. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  17. ;;; Commentary:
  18. ;;
  19. ;; Handles a superclass of target types which create object code in
  20. ;; and EDE Project file.
  21. (eval-when-compile (require 'cl))
  22. (require 'ede/proj)
  23. (declare-function ede-pmake-varname "ede/pmake")
  24. (defvar ede-proj-objectcode-dodependencies nil
  25. "Flag specifies to do automatic dependencies.")
  26. ;;; Code:
  27. (defclass ede-proj-target-makefile-objectcode (ede-proj-target-makefile)
  28. (;; Give this a new default
  29. (configuration-variables :initform ("debug" . (("CFLAGS" . "-g")
  30. ("LDFLAGS" . "-g"))))
  31. ;; @TODO - add an include path.
  32. (availablecompilers :initform '(ede-gcc-compiler
  33. ede-g++-compiler
  34. ede-gfortran-compiler
  35. ede-gfortran-module-compiler
  36. ede-lex-compiler
  37. ede-yacc-compiler
  38. ;; More C and C++ compilers, plus
  39. ;; fortran or pascal can be added here
  40. ))
  41. (availablelinkers :initform '(ede-g++-linker
  42. ede-cc-linker
  43. ede-ld-linker
  44. ede-gfortran-linker
  45. ;; Add more linker thingies here.
  46. ))
  47. (sourcetype :initform '(ede-source-c
  48. ede-source-c++
  49. ede-source-f77
  50. ede-source-f90
  51. ede-source-lex
  52. ede-source-yacc
  53. ;; ede-source-other
  54. ;; This object should take everything that
  55. ;; gets compiled into objects like fortran
  56. ;; and pascal.
  57. ))
  58. )
  59. "Abstract class for Makefile based object code generating targets.
  60. Belonging to this group assumes you could make a .o from an element source
  61. file.")
  62. (defclass ede-object-compiler (ede-compiler)
  63. ((uselinker :initform t)
  64. (dependencyvar :initarg :dependencyvar
  65. :type list
  66. :custom (cons (string :tag "Variable")
  67. (string :tag "Value"))
  68. :documentation
  69. "A variable dedicated to dependency generation."))
  70. "Ede compiler class for source which must compiler, and link.")
  71. ;;; C/C++ Compilers and Linkers
  72. ;;
  73. (defvar ede-source-c
  74. (ede-sourcecode "ede-source-c"
  75. :name "C"
  76. :sourcepattern "\\.c$"
  77. :auxsourcepattern "\\.h$"
  78. :garbagepattern '("*.o" "*.obj" ".deps/*.P" ".lo"))
  79. "C source code definition.")
  80. (defvar ede-gcc-compiler
  81. (ede-object-compiler
  82. "ede-c-compiler-gcc"
  83. :name "gcc"
  84. :dependencyvar '("C_DEPENDENCIES" . "-Wp,-MD,.deps/$(*F).P")
  85. :variables '(("CC" . "gcc")
  86. ("C_COMPILE" .
  87. "$(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)"))
  88. :rules (list (ede-makefile-rule
  89. "c-inference-rule"
  90. :target "%.o"
  91. :dependencies "%.c"
  92. :rules '("@echo '$(C_COMPILE) -c $<'; \\"
  93. "$(C_COMPILE) $(C_DEPENDENCIES) -o $@ -c $<"
  94. )
  95. ))
  96. :autoconf '("AC_PROG_CC" "AC_PROG_GCC_TRADITIONAL")
  97. :sourcetype '(ede-source-c)
  98. :objectextention ".o"
  99. :makedepends t
  100. :uselinker t)
  101. "Compiler for C sourcecode.")
  102. (defvar ede-cc-linker
  103. (ede-linker
  104. "ede-cc-linker"
  105. :name "cc"
  106. :sourcetype '(ede-source-c)
  107. :variables '(("C_LINK" . "$(CC) $(CFLAGS) $(LDFLAGS) -L."))
  108. :commands '("$(C_LINK) -o $@ $^ $(LDDEPS)")
  109. :objectextention "")
  110. "Linker for C sourcecode.")
  111. (defvar ede-source-c++
  112. (ede-sourcecode "ede-source-c++"
  113. :name "C++"
  114. :sourcepattern "\\.\\(c\\(pp?\\|c\\|xx\\|++\\)\\|C\\(PP\\)?\\)$"
  115. :auxsourcepattern "\\.\\(hpp?\\|hh?\\|hxx\\|H\\)$"
  116. :garbagepattern '("*.o" "*.obj" ".deps/*.P" ".lo"))
  117. "C++ source code definition.")
  118. (defvar ede-g++-compiler
  119. (ede-object-compiler
  120. "ede-c-compiler-g++"
  121. :name "g++"
  122. :dependencyvar '("CXX_DEPENDENCIES" . "-Wp,-MD,.deps/$(*F).P")
  123. :variables '(("CXX" "g++")
  124. ("CXX_COMPILE" .
  125. "$(CXX) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)")
  126. )
  127. :rules (list (ede-makefile-rule
  128. "c++-inference-rule"
  129. :target "%.o"
  130. :dependencies "%.cpp"
  131. :rules '("@echo '$(CXX_COMPILE) -c $<'; \\"
  132. "$(CXX_COMPILE) $(CXX_DEPENDENCIES) -o $@ -c $<"
  133. )
  134. ))
  135. :autoconf '("AC_PROG_CXX")
  136. :sourcetype '(ede-source-c++)
  137. :objectextention ".o"
  138. :makedepends t
  139. :uselinker t)
  140. "Compiler for C sourcecode.")
  141. (defvar ede-g++-linker
  142. (ede-linker
  143. "ede-g++-linker"
  144. :name "g++"
  145. ;; Only use this linker when c++ exists.
  146. :sourcetype '(ede-source-c++)
  147. :variables '(("CXX_LINK" . "$(CXX) $(CFLAGS) $(LDFLAGS) -L."))
  148. :commands '("$(CXX_LINK) -o $@ $^ $(LDDEPS)")
  149. :autoconf '("AC_PROG_CXX")
  150. :objectextention "")
  151. "Linker needed for c++ programs.")
  152. ;;; LEX
  153. (defvar ede-source-lex
  154. (ede-sourcecode "ede-source-lex"
  155. :name "lex"
  156. :sourcepattern "\\.l\\(l\\|pp\\|++\\)")
  157. "Lex source code definition.
  158. No garbage pattern since it creates C or C++ code.")
  159. (defvar ede-lex-compiler
  160. (ede-object-compiler
  161. "ede-lex-compiler"
  162. ;; Can we support regular makefiles too??
  163. :autoconf '("AC_PROG_LEX")
  164. :sourcetype '(ede-source-lex))
  165. "Compiler used for Lexical source.")
  166. ;;; YACC
  167. (defvar ede-source-yacc
  168. (ede-sourcecode "ede-source-yacc"
  169. :name "yacc"
  170. :sourcepattern "\\.y\\(y\\|pp\\|++\\)")
  171. "Yacc source code definition.
  172. No garbage pattern since it creates C or C++ code.")
  173. (defvar ede-yacc-compiler
  174. (ede-object-compiler
  175. "ede-yacc-compiler"
  176. ;; Can we support regular makefiles too??
  177. :autoconf '("AC_PROG_YACC")
  178. :sourcetype '(ede-source-yacc))
  179. "Compiler used for yacc/bison grammar files source.")
  180. ;;; Fortran Compiler/Linker
  181. ;;
  182. ;; Contributed by David Engster
  183. (defvar ede-source-f90
  184. (ede-sourcecode "ede-source-f90"
  185. :name "Fortran 90/95"
  186. :sourcepattern "\\.[fF]9[05]$"
  187. :auxsourcepattern "\\.incf$"
  188. :garbagepattern '("*.o" "*.mod" ".deps/*.P"))
  189. "Fortran 90/95 source code definition.")
  190. (defvar ede-source-f77
  191. (ede-sourcecode "ede-source-f77"
  192. :name "Fortran 77"
  193. :sourcepattern "\\.\\([fF]\\|for\\)$"
  194. :auxsourcepattern "\\.incf$"
  195. :garbagepattern '("*.o" ".deps/*.P"))
  196. "Fortran 77 source code definition.")
  197. (defvar ede-gfortran-compiler
  198. (ede-object-compiler
  199. "ede-f90-compiler-gfortran"
  200. :name "gfortran"
  201. :dependencyvar '("F90_DEPENDENCIES" . "-Wp,-MD,.deps/$(*F).P")
  202. :variables '(("F90" . "gfortran")
  203. ("F90_COMPILE" .
  204. "$(F90) $(DEFS) $(INCLUDES) $(F90FLAGS)"))
  205. :rules (list (ede-makefile-rule
  206. "f90-inference-rule"
  207. :target "%.o"
  208. :dependencies "%.f90"
  209. :rules '("@echo '$(F90_COMPILE) -c $<'; \\"
  210. "$(F90_COMPILE) $(F90_DEPENDENCIES) -o $@ -c $<"
  211. )
  212. ))
  213. :sourcetype '(ede-source-f90 ede-source-f77)
  214. :objectextention ".o"
  215. :makedepends t
  216. :uselinker t)
  217. "Compiler for Fortran sourcecode.")
  218. (defvar ede-gfortran-module-compiler
  219. (clone ede-gfortran-compiler
  220. "ede-f90-module-compiler-gfortran"
  221. :name "gfortranmod"
  222. :sourcetype '(ede-source-f90)
  223. :commands '("$(F90_COMPILE) -c $^")
  224. :objectextention ".mod"
  225. :uselinker nil)
  226. "Compiler for Fortran 90/95 modules.")
  227. (defvar ede-gfortran-linker
  228. (ede-linker
  229. "ede-gfortran-linker"
  230. :name "gfortran"
  231. :sourcetype '(ede-source-f90 ede-source-f77)
  232. :variables '(("F90_LINK" . "$(F90) $(CFLAGS) $(LDFLAGS) -L."))
  233. :commands '("$(F90_LINK) -o $@ $^")
  234. :objectextention "")
  235. "Linker needed for Fortran programs.")
  236. ;;; Generic Linker
  237. ;;
  238. (defvar ede-ld-linker
  239. (ede-linker
  240. "ede-ld-linker"
  241. :name "ld"
  242. :variables '(("LD" . "ld")
  243. ("LD_LINK" . "$(LD) $(LDFLAGS) -L."))
  244. :commands '("$(LD_LINK) -o $@ $^ $(LDDEPS)")
  245. :objectextention "")
  246. "Linker needed for c++ programs.")
  247. ;;; The EDE object compiler
  248. ;;
  249. (cl-defmethod ede-proj-makefile-insert-variables ((this ede-object-compiler))
  250. "Insert variables needed by the compiler THIS."
  251. (cl-call-next-method)
  252. (if (eieio-instance-inheritor-slot-boundp this 'dependencyvar)
  253. (with-slots (dependencyvar) this
  254. (insert (car dependencyvar) "=")
  255. (let ((cd (cdr dependencyvar)))
  256. (if (listp cd)
  257. (mapc (lambda (c) (insert " " c)) cd)
  258. (insert cd))
  259. (insert "\n")))))
  260. ;;; EDE Object target type methods
  261. ;;
  262. (cl-defmethod ede-proj-makefile-sourcevar
  263. ((this ede-proj-target-makefile-objectcode))
  264. "Return the variable name for THIS's sources."
  265. (require 'ede/pmake)
  266. (concat (ede-pmake-varname this) "_SOURCES"))
  267. (cl-defmethod ede-proj-makefile-dependency-files
  268. ((this ede-proj-target-makefile-objectcode))
  269. "Return a list of source files to convert to dependencies.
  270. Argument THIS is the target to get sources from."
  271. (append (oref this source) (oref this auxsource)))
  272. (cl-defmethod ede-proj-makefile-insert-variables ((this ede-proj-target-makefile-objectcode)
  273. &optional moresource)
  274. "Insert variables needed by target THIS.
  275. Optional argument MORESOURCE is not used."
  276. (let ((ede-proj-objectcode-dodependencies
  277. (oref (ede-target-parent this) automatic-dependencies)))
  278. (cl-call-next-method)))
  279. (cl-defmethod ede-buffer-header-file((this ede-proj-target-makefile-objectcode)
  280. buffer)
  281. "There are no default header files."
  282. (or (cl-call-next-method)
  283. ;; Ok, nothing obvious. Try looking in ourselves.
  284. (let ((h (oref this auxsource)))
  285. ;; Add more logic here when the problem is better understood.
  286. (car-safe h))))
  287. (provide 'ede/proj-obj)
  288. ;;; ede/proj-obj.el ends here