c.pm 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. -- This file is part of Prime Mover v0.1pre1.
  2. -- (C) 2006 David Given
  3. --
  4. -- pm includefile to compile *host* C programs.
  5. -- Standard Lua boilerplate.
  6. local io_open = io.open
  7. local string_gsub = string.gsub
  8. local string_gfind = string.gfind
  9. local table_insert = table.insert
  10. local table_getn = table.getn
  11. local filetime = pm.filetime
  12. -- Define some variables.
  13. CC = "gcc %CBUILDFLAGS% %CDYNINCLUDES% %CINCLUDES% %CEXTRAFLAGS% -c -o %out% %in%"
  14. CPROGRAM = "gcc %CBUILDFLAGS% %CLINKFLAGS% %CEXTRAFLAGS% -o %out% %in% %CLIBRARIES%"
  15. CDEPENDS = "gcc %CBUILDFLAGS% %CDYNINCLUDES% %CINCLUDES% %CEXTRAFLAGS% -MM -MG -MF %out% %in%"
  16. AR = "%RM% %out% && ar cr %out% %in%"
  17. CBUILDFLAGS = "-g -Os"
  18. CINCLUDES = {}
  19. CEXTRAFLAGS = ""
  20. CLINKFLAGS = ""
  21. CDYNINCLUDES = ""
  22. CLIBRARIES = ""
  23. --- Manage C file dependencies ----------------------------------------------
  24. local dependency_cache = {}
  25. local function load_dependency_file(fn)
  26. local o = dependency_cache[fn]
  27. if o then
  28. return o
  29. end
  30. -- Read in the dependency file.
  31. local f = io_open(fn)
  32. if not f then
  33. print("failed to open "..fn)
  34. return nil
  35. end
  36. f = f:read("*a")
  37. -- Massage the dependency file into a string containing one unescaped
  38. -- filename per line.
  39. f = string_gsub(f, "^.*[^\\]: *", "")
  40. f = string_gsub(f, "\\\r?\n", "")
  41. f = string_gsub(f, "([^\\]) +", "%1\n")
  42. f = string_gsub(f, "\\", "")
  43. -- Parse the string.
  44. o = {}
  45. for l in string_gfind(f, "[^\n]+") do
  46. table_insert(o, l)
  47. end
  48. dependency_cache[fn] = o
  49. return o
  50. end
  51. -- This clause specialises 'simple' to add support for smart dependencies of C
  52. -- files.
  53. simple_with_clike_dependencies = simple {
  54. class = "simple_with_clike_dependencies",
  55. makedepends = {"%CDEPENDS%"},
  56. __init = function(self, p)
  57. simple.__init(self, p)
  58. -- If we're a class, don't verify.
  59. if ((type(p) == "table") and p.class) then
  60. return
  61. end
  62. -- If dynamicheaders is an object, turn it into a singleton list.
  63. if self.dynamicheaders then
  64. if (type(self.dynamicheaders) ~= "table") then
  65. self:__error("doesn't know what to do with dynamicheaders, which ",
  66. "should be a list or an object but was a ", type(self.dynamicheaders))
  67. end
  68. if self.dynamicheaders.class then
  69. self.dynamicheaders = {self.dynamicheaders}
  70. end
  71. end
  72. end,
  73. __dependencies = function(self, inputs, outputs)
  74. local obj = simple {
  75. CDYNINCLUDES = self.CDYNINCLUDES,
  76. command = self.makedepends,
  77. outputs = {"%U%-%I%.d"},
  78. unpack(inputs)
  79. }
  80. local o = obj:__build()
  81. local depends = load_dependency_file(o[1])
  82. if not depends then
  83. self:__error("could not determine the dependencies for ",
  84. pm.rendertable(inputs))
  85. end
  86. return depends
  87. end,
  88. __buildadditionalchildren = function(self)
  89. self.CDYNINCLUDES = ""
  90. if self.dynamicheaders then
  91. for _, i in ipairs(self.dynamicheaders) do
  92. local o = i:__build()
  93. if o[1] then
  94. self.CDYNINCLUDES = self.CDYNINCLUDES..' "-I'..string_gsub(o[1], "/[^/]*$", "")..'"'
  95. end
  96. end
  97. end
  98. end
  99. }
  100. -- These are the publically useful clauses.
  101. cfile = simple_with_clike_dependencies {
  102. class = "cfile",
  103. command = {"%CC%"},
  104. outputs = {"%U%-%I%.o"},
  105. }
  106. cprogram = simple {
  107. class = "cprogram",
  108. command = {"%CPROGRAM%"},
  109. outputs = {"%U%-%I%"},
  110. }
  111. clibrary = simple {
  112. class = "clibrary",
  113. command = {
  114. "%AR%"
  115. },
  116. outputs = {"%U%-%I%.a"},
  117. }