]> code.citadel.org Git - citadel.git/blob - gaim-citadel/c.pm
Edit message : i agree with fleeb, i put the button on right top
[citadel.git] / gaim-citadel / c.pm
1 -- Prime Mover C plugin.
2 -- © 2006 David Given.
3 --
4 -- This code is part of Prime Mover and is licensed under the MIT public
5 -- license.
6
7 -- pm includefile to compile *host* C programs.
8
9 -- Standard Lua boilerplate.
10
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
17
18 -- Define some variables.
19
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%"
24
25 CBUILDFLAGS = "-g -Os"
26 CINCLUDES = {}
27 CEXTRAFLAGS = ""
28 CLINKFLAGS = ""
29 CDYNINCLUDES = ""
30 CLIBRARIES = ""
31
32 --- Manage C file dependencies ----------------------------------------------
33
34 local dependency_cache = {}
35 local function load_dependency_file(fn)
36         local o = dependency_cache[fn]
37         if o then
38                 return o
39         end
40         
41         -- Read in the dependency file.
42         
43         local f = io_open(fn)
44         if not f then
45                 print("failed to open "..fn)
46                 return nil
47         end
48         f = f:read("*a")
49         
50         -- Massage the dependency file into a string containing one unescaped
51         -- filename per line.
52         
53         f = string_gsub(f, "^.*[^\\]: *", "")
54         f = string_gsub(f, "\\\r?\n", "")
55         f = string_gsub(f, "([^\\]) +", "%1\n")
56         f = string_gsub(f, "\\", "")
57         
58         -- Parse the string.
59         
60         o = {}
61         for l in string_gfind(f, "[^\n]+") do
62                 table_insert(o, l)
63         end
64         
65         dependency_cache[fn] = o
66         return o
67 end
68
69 -- This clause specialises 'simple' to add support for smart dependencies of C
70 -- files.
71
72 simple_with_clike_dependencies = simple {
73         class = "simple_with_clike_dependencies",
74         makedepends = {"%CDEPENDS%"},
75
76         __init = function(self, p)
77                 simple.__init(self, p)
78                 
79                 -- If we're a class, don't verify.
80                 
81                 if ((type(p) == "table") and p.class) then
82                         return
83                 end
84
85                 -- If dynamicheaders is an object, turn it into a singleton list.
86                 
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))
91                         end
92                         if self.dynamicheaders.class then
93                                 self.dynamicheaders = {self.dynamicheaders}
94                         end
95                 end
96         end,
97         
98         __dependencies = function(self, inputs, outputs)
99                 local obj = simple {
100                         CDYNINCLUDES = self.CDYNINCLUDES,
101                         command = self.makedepends,
102                         outputs = {"%U%-%I%.d"},
103                         unpack(inputs)
104                 }
105                 local o = obj:__build()
106                 local depends = load_dependency_file(o[1])
107                 if not depends then
108                         self:__error("could not determine the dependencies for ",
109                                 pm.rendertable(inputs))
110                 end
111                 return depends
112         end,
113         
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()
119                                 if o[1] then
120                                         self.CDYNINCLUDES = self.CDYNINCLUDES..' "-I'..string_gsub(o[1], "/[^/]*$", "")..'"'
121                                 end
122                         end
123                 end
124         end
125 }
126
127 -- These are the publically useful clauses.
128
129 cfile = simple_with_clike_dependencies {
130         class = "cfile",
131         command = {"%CC%"},
132         outputs = {"%U%-%I%.o"},
133 }
134
135 cprogram = simple {
136         class = "cprogram",
137         command = {"%CPROGRAM%"},
138         outputs = {"%U%-%I%"},
139 }
140
141 clibrary = simple {
142         class = "clibrary",
143         command = {
144                 "%AR%"
145         },
146         outputs = {"%U%-%I%.a"},
147 }