c.pm 3.3 KB

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