1 -- Prime Mover C plugin.
4 -- This code is part of Prime Mover and is licensed under the MIT public
7 -- pm includefile to compile *host* C programs.
9 -- Standard Lua boilerplate.
11 local io_open = io.open
12 local string_gsub = string.gsub
13 local string_gfind = string.gfind
14 local table_insert = table.insert
15 local table_getn = table.getn
16 local filetime = pm.filetime
18 -- Define some variables.
20 CC = "gcc %CBUILDFLAGS% %CDYNINCLUDES% %CINCLUDES% %CEXTRAFLAGS% -c -o %out% %in%"
21 CPROGRAM = "gcc %CBUILDFLAGS% %CLINKFLAGS% %CEXTRAFLAGS% -o %out% %in% %CLIBRARIES%"
22 CDEPENDS = "gcc %CBUILDFLAGS% %CDYNINCLUDES% %CINCLUDES% %CEXTRAFLAGS% -MM -MG -MF %out% %in%"
23 AR = "%RM% %out% && ar cr %out% %in%"
25 CBUILDFLAGS = "-g -Os"
32 --- Manage C file dependencies ----------------------------------------------
34 local dependency_cache = {}
35 local function load_dependency_file(fn)
36 local o = dependency_cache[fn]
41 -- Read in the dependency file.
45 print("failed to open "..fn)
50 -- Massage the dependency file into a string containing one unescaped
53 f = string_gsub(f, "^.*[^\\]: *", "")
54 f = string_gsub(f, "\\\r?\n", "")
55 f = string_gsub(f, "([^\\]) +", "%1\n")
56 f = string_gsub(f, "\\", "")
61 for l in string_gfind(f, "[^\n]+") do
65 dependency_cache[fn] = o
69 -- This clause specialises 'simple' to add support for smart dependencies of C
72 simple_with_clike_dependencies = simple {
73 class = "simple_with_clike_dependencies",
74 makedepends = {"%CDEPENDS%"},
76 __init = function(self, p)
77 simple.__init(self, p)
79 -- If we're a class, don't verify.
81 if ((type(p) == "table") and p.class) then
85 -- If dynamicheaders is an object, turn it into a singleton list.
87 if self.dynamicheaders then
88 if (type(self.dynamicheaders) ~= "table") then
89 self:__error("doesn't know what to do with dynamicheaders, which ",
90 "should be a list or an object but was a ", type(self.dynamicheaders))
92 if self.dynamicheaders.class then
93 self.dynamicheaders = {self.dynamicheaders}
98 __dependencies = function(self, inputs, outputs)
100 CDYNINCLUDES = self.CDYNINCLUDES,
101 command = self.makedepends,
102 outputs = {"%U%-%I%.d"},
105 local o = obj:__build()
106 local depends = load_dependency_file(o[1])
108 self:__error("could not determine the dependencies for ",
109 pm.rendertable(inputs))
114 __buildadditionalchildren = function(self)
115 self.CDYNINCLUDES = ""
116 if self.dynamicheaders then
117 for _, i in ipairs(self.dynamicheaders) do
118 local o = i:__build()
120 self.CDYNINCLUDES = self.CDYNINCLUDES..' "-I'..string_gsub(o[1], "/[^/]*$", "")..'"'
127 -- These are the publically useful clauses.
129 cfile = simple_with_clike_dependencies {
132 outputs = {"%U%-%I%.o"},
137 command = {"%CPROGRAM%"},
138 outputs = {"%U%-%I%"},
146 outputs = {"%U%-%I%.a"},