genmk.rb 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. #! /usr/bin/ruby -w
  2. #
  3. # Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
  4. #
  5. # This genmk.rb is free software; the author
  6. # gives unlimited permission to copy and/or distribute it,
  7. # with or without modifications, as long as this notice is preserved.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY, to the extent permitted by law; without
  11. # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  12. # PARTICULAR PURPOSE.
  13. module Enumerable
  14. def collect_with_index
  15. ret = []
  16. self.each_with_index do |item, index|
  17. ret.push(yield(item, index))
  18. end
  19. ret
  20. end
  21. end
  22. class String
  23. def to_var
  24. self.gsub(/[^a-zA-Z0-9_@]/, '_')
  25. end
  26. def suffix(str)
  27. self.sub(/\.[^\.]*$/, '') + '.' + str
  28. end
  29. def to_obj
  30. self.sub(/\.[^\.]*$/, '').to_var + '.o'
  31. end
  32. end
  33. class Image
  34. def initialize(dir, name)
  35. @dir = dir
  36. @name = name
  37. @rule_count = 0
  38. end
  39. attr_reader :dir, :name
  40. def rule(sources)
  41. prefix = @name.to_var
  42. @rule_count += 1
  43. exe = @name.suffix('exec')
  44. objs = sources.collect do |src|
  45. raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src
  46. prefix + '-' + src.to_obj
  47. end
  48. objs_str = objs.join(' ')
  49. deps = objs.collect {|obj| obj.suffix('d')}
  50. deps_str = deps.join(' ')
  51. "
  52. clean-image-#{@name}.#{@rule_count}:
  53. rm -f #{@name} #{exe} #{objs_str}
  54. CLEAN_IMAGE_TARGETS += clean-image-#{@name}.#{@rule_count}
  55. mostlyclean-image-#{@name}.#{@rule_count}:
  56. rm -f #{deps_str}
  57. MOSTLYCLEAN_IMAGE_TARGETS += mostlyclean-image-#{@name}.#{@rule_count}
  58. #{@name}: #{objs_str} grub-mkimg
  59. $(call quiet-command,./grub-mkimg -o $@ -b $(#{prefix}_LINKADDR) $(filter %.o, $^),\" IMG #{@name}\")
  60. " + objs.collect_with_index do |obj, i|
  61. src = sources[i]
  62. fake_obj = File.basename(src).suffix('o')
  63. dep = deps[i]
  64. flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end
  65. dir = File.dirname(src)
  66. if /\.S$/ =~ src then
  67. "#{obj}: #{src} $(#{src}_DEPENDENCIES)
  68. ifeq ($(AS),)
  69. $(call quiet-command,$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_#{flag}) $(#{prefix}_#{flag}) -DGRUB_FILE=\\\"#{src}\\\" -MD -c -o $@ $<,\" AS #{obj}\")
  70. else
  71. $(call quiet-command,$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_#{flag}) $(#{prefix}_#{flag}) -DGRUB_FILE=\\\"#{src}\\\" -MD -S $< | $(AS) -o $@,\" AS #{obj}\")
  72. endif
  73. -include #{dep}
  74. "
  75. else
  76. "#{obj}: #{src} $(#{src}_DEPENDENCIES)
  77. $(call quiet-command,$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) $(TARGET_#{flag}) $(#{prefix}_#{flag}) -DGRUB_FILE=\\\"#{src}\\\" -MD -c -o $@ $<,\" CC #{obj}\")
  78. -include #{dep}
  79. "
  80. end
  81. end.join('')
  82. end
  83. end
  84. # Use PModule instead Module, to avoid name conflicting.
  85. class PModule
  86. def initialize(dir, name)
  87. @dir = dir
  88. @name = name
  89. @rule_count = 0
  90. end
  91. attr_reader :dir, :name
  92. def rule(sources)
  93. prefix = @name.to_var
  94. @rule_count += 1
  95. objs = sources.collect do |src|
  96. raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src
  97. prefix + '-' + src.to_obj
  98. end
  99. objs_str = objs.join(' ')
  100. deps = objs.collect {|obj| obj.suffix('d')}
  101. deps_str = deps.join(' ')
  102. mod_name = File.basename(@name, '.mod')
  103. symbolic_name = mod_name.sub(/\.[^\.]*$/, '')
  104. "
  105. clean-module-#{@name}.#{@rule_count}:
  106. rm -f #{@name} #{objs_str}
  107. CLEAN_MODULE_TARGETS += clean-module-#{@name}.#{@rule_count}
  108. mostlyclean-module-#{@name}.#{@rule_count}:
  109. rm -f #{deps_str}
  110. MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-#{@name}.#{@rule_count}
  111. ifeq ($(TARGET_NO_MODULES), yes)
  112. #{@name}: #{objs_str}
  113. $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ #{objs_str}
  114. # $(call quiet-command,$(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ #{objs_str},\" LINK #{@name}\")
  115. else
  116. #{@name}: #{objs_str} grub-mkmod
  117. $(call quiet-command,./grub-mkmod -o $@ $(filter %.o, $^),\" MOD #{@name}\")
  118. endif
  119. MODFILES += #{@name}
  120. " + objs.collect_with_index do |obj, i|
  121. src = sources[i]
  122. fake_obj = File.basename(src).suffix('o')
  123. extra_target = obj.sub(/\.[^\.]*$/, '') + '-extra'
  124. dep = deps[i]
  125. flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end
  126. dir = File.dirname(src)
  127. if /\.S$/ =~ src then
  128. "#{obj}: #{src} $(#{src}_DEPENDENCIES)
  129. ifeq ($(AS),)
  130. $(call quiet-command,$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_#{flag}) $(#{prefix}_#{flag}) -DGRUB_FILE=\\\"#{src}\\\" -MD -c -o $@ $<,\" AS #{obj}\")
  131. else
  132. $(call quiet-command,$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_#{flag}) $(#{prefix}_#{flag}) -DGRUB_FILE=\\\"#{src}\\\" -MD -S $< | $(AS) -o $@,\" AS #{obj}\")
  133. endif
  134. -include #{dep}
  135. "
  136. else
  137. "#{obj}: #{src} $(#{src}_DEPENDENCIES)
  138. $(call quiet-command,$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) $(TARGET_#{flag}) $(#{prefix}_#{flag}) -DGRUB_FILE=\\\"#{src}\\\" -MD -c -o $@ $<,\" CC #{obj}\")
  139. -include #{dep}
  140. "
  141. end
  142. end.join('')
  143. end
  144. end
  145. class Utility
  146. def initialize(dir, name)
  147. @dir = dir
  148. @name = name
  149. @rule_count = 0
  150. end
  151. def print_tail()
  152. prefix = @name.to_var
  153. print "#{@name}: $(#{prefix}_DEPENDENCIES) $(#{prefix}_OBJECTS)
  154. $(call quiet-command,$(CC) -o $@ $(#{prefix}_OBJECTS) $(LDFLAGS) $(#{prefix}_LDFLAGS),\" LINK #{@name}\")
  155. "
  156. end
  157. attr_reader :dir, :name
  158. def rule(sources)
  159. prefix = @name.to_var
  160. @rule_count += 1
  161. objs = sources.collect do |src|
  162. raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src
  163. prefix + '-' + src.to_obj
  164. end
  165. objs_str = objs.join(' ');
  166. deps = objs.collect {|obj| obj.suffix('d')}
  167. deps_str = deps.join(' ');
  168. "
  169. clean-utility-#{@name}.#{@rule_count}:
  170. rm -f #{@name}$(EXEEXT) #{objs_str}
  171. CLEAN_UTILITY_TARGETS += clean-utility-#{@name}.#{@rule_count}
  172. mostlyclean-utility-#{@name}.#{@rule_count}:
  173. rm -f #{deps_str}
  174. MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-#{@name}.#{@rule_count}
  175. #{prefix}_OBJECTS += #{objs_str}
  176. " + objs.collect_with_index do |obj, i|
  177. src = sources[i]
  178. fake_obj = File.basename(src).suffix('o')
  179. dep = deps[i]
  180. dir = File.dirname(src)
  181. "#{obj}: #{src} $(#{src}_DEPENDENCIES)
  182. $(call quiet-command,$(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(#{prefix}_CFLAGS) -DGRUB_FILE=\\\"#{src}\\\" -MD -c -o $@ $<,\" CC #{obj}\")
  183. -include #{dep}
  184. "
  185. end.join('')
  186. end
  187. end
  188. class Program
  189. def initialize(dir, name)
  190. @dir = dir
  191. @name = name
  192. end
  193. attr_reader :dir, :name
  194. def print_tail()
  195. prefix = @name.to_var
  196. print "CLEANFILES += #{@name} $(#{prefix}_OBJECTS)
  197. #{@name}: $(#{prefix}_DEPENDENCIES) $(#{prefix}_OBJECTS)
  198. $(call quiet-command,$(TARGET_CC) -o $@ $(#{prefix}_OBJECTS) $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS),\" LINK #{@name}\")
  199. if test x$(TARGET_NO_STRIP) != xyes ; then $(STRIP) -R .rel.dyn -R .reginfo -R .note -R .comment $@; fi
  200. "
  201. end
  202. def rule(sources)
  203. prefix = @name.to_var
  204. objs = sources.collect do |src|
  205. raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src
  206. prefix + '-' + src.to_obj
  207. end
  208. deps = objs.collect {|obj| obj.suffix('d')}
  209. deps_str = deps.join(' ');
  210. "MOSTLYCLEANFILES += #{deps_str}
  211. " + objs.collect_with_index do |obj, i|
  212. src = sources[i]
  213. fake_obj = File.basename(src).suffix('o')
  214. dep = deps[i]
  215. flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end
  216. extra_flags = if /\.S$/ =~ src then '-DASM_FILE=1' else '' end
  217. dir = File.dirname(src)
  218. "#{obj}: #{src} $(#{src}_DEPENDENCIES)
  219. $(call quiet-command,$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -DGRUB_FILE=\\\"#{src}\\\" -MD -c -o $@ $<,\" CC #{obj}\")
  220. -include #{dep}
  221. #{prefix}_OBJECTS += #{obj}
  222. "
  223. end.join('')
  224. end
  225. end
  226. class Script
  227. def initialize(dir, name)
  228. @dir = dir
  229. @name = name
  230. end
  231. attr_reader :dir, :name
  232. def rule(sources)
  233. if sources.length != 1
  234. raise "only a single source file must be specified for a script"
  235. end
  236. src = sources[0]
  237. if /\.in$/ !~ src
  238. raise "unknown source file `#{src}'"
  239. end
  240. "CLEANFILES += #{@name}
  241. #{@name}: #{src} $(#{src}_DEPENDENCIES) config.status
  242. ./config.status --file=-:#{src} | sed -e 's,@pkglib_DATA@,$(pkglib_DATA),g' > $@
  243. chmod +x $@
  244. "
  245. end
  246. end
  247. images = []
  248. utils = []
  249. pmodules = []
  250. programs = []
  251. scripts = []
  252. l = gets
  253. print l
  254. print "# Generated by genmk.rb, please don't edit!\n"
  255. cont = false
  256. str = nil
  257. while l = gets
  258. if cont
  259. str += l
  260. else
  261. str = l
  262. end
  263. print l
  264. cont = (/\\$/ =~ l)
  265. unless cont
  266. str.gsub!(/\\\n/, ' ')
  267. if /^([a-zA-Z0-9_]+)\s*\+?=\s*(.*?)\s*$/ =~ str
  268. var, args = $1, $2
  269. if var =~ /^([a-zA-Z0-9_]+)_([A-Z]+)$/
  270. prefix, type = $1, $2
  271. case type
  272. when 'IMAGES'
  273. images += args.split(/\s+/).collect do |img|
  274. Image.new(prefix, img)
  275. end
  276. when 'MODULES'
  277. pmodules += args.split(/\s+/).collect do |pmod|
  278. PModule.new(prefix, pmod)
  279. end
  280. when 'UTILITIES'
  281. utils += args.split(/\s+/).collect do |util|
  282. Utility.new(prefix, util)
  283. end
  284. when 'PROGRAMS'
  285. programs += args.split(/\s+/).collect do |prog|
  286. Program.new(prefix, prog)
  287. end
  288. when 'SCRIPTS'
  289. scripts += args.split(/\s+/).collect do |script|
  290. Script.new(prefix, script)
  291. end
  292. when 'SOURCES'
  293. if img = images.detect() {|i| i.name.to_var == prefix}
  294. print img.rule(args.split(/\s+/))
  295. elsif pmod = pmodules.detect() {|m| m.name.to_var == prefix}
  296. print pmod.rule(args.split(/\s+/))
  297. elsif util = utils.detect() {|u| u.name.to_var == prefix}
  298. print util.rule(args.split(/\s+/))
  299. elsif program = programs.detect() {|u| u.name.to_var == prefix}
  300. print program.rule(args.split(/\s+/))
  301. elsif script = scripts.detect() {|s| s.name.to_var == prefix}
  302. print script.rule(args.split(/\s+/))
  303. end
  304. end
  305. end
  306. end
  307. end
  308. end
  309. utils.each {|util| util.print_tail()}
  310. programs.each {|program| program.print_tail()}