Rename REAMDE to README.md
[nit.git] / src / c_tools.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2012 Alexis Laferrière <alexis.laf@xymus.net>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # provides tools to write C .c and .h files
18 module c_tools
19
20 import template
21
22 # Accumulates all C code for a compilation unit
23 class CCompilationUnit
24 ## header
25 # comments and native interface imports
26 var header_c_base = new Template
27
28 # custom C header code or generated for other languages
29 var header_custom = new Template
30
31 # types of extern classes and friendly types
32 var header_c_types = new Template
33
34 # implementation declaration for extern methods
35 var header_decl = new Template
36
37 ## body
38 # comments, imports, etc
39 var body_decl = new Template
40
41 # custom code and generated for ffi
42 var body_custom = new Template
43
44 # implementation body of extern methods
45 var body_impl = new Template
46
47 # files to compile TODO check is appropriate
48 var files = new Array[String]
49
50 # Add `c_function` as a `static` function local to this unit
51 fun add_local_function(c_function: CFunction)
52 do
53 body_decl.add "static {c_function.signature};\n"
54 body_impl.add "\n"
55 body_impl.add c_function.to_writer
56 end
57
58 # Add `c_function` as a public function to this unit
59 fun add_exported_function(c_function: CFunction)
60 do
61 header_decl.add "{c_function.signature};\n"
62 body_impl.add "\n"
63 body_impl.add c_function.to_writer
64 end
65
66 # Write the core of the header to `stream`
67 fun compile_header_core(stream: Writer)
68 do
69 header_c_base.write_to stream
70 header_custom.write_to stream
71 header_c_types.write_to stream
72 header_decl.write_to stream
73 end
74
75 # Write the core of the body to `stream`
76 fun compile_body_core(stream: Writer)
77 do
78 body_decl.write_to stream
79 body_custom.write_to stream
80 body_impl.write_to stream
81 end
82 end
83
84 # Accumulates C code related to a specific function
85 class CFunction
86 var signature : String
87
88 var decls = new Template
89 var exprs = new Template
90
91 fun to_writer: Template
92 do
93 var w = new Template
94
95 w.add(signature)
96 w.add("\n\{\n")
97 w.add(decls)
98 w.add("\n")
99 w.add(exprs)
100 w.add("\}\n")
101
102 return w
103 end
104 end
105
106 # An extern file to compile
107 class ExternFile
108 # The filename of the file
109 var filename: String
110
111 # The name of the target in the Makefile
112 # Usually the produced .o file
113 fun makefile_rule_name: String is abstract
114
115 # The content of the rule in the make
116 # Usually the one-line shell command after the tabulation
117 fun makefile_rule_content: String is abstract
118
119 fun compiles_to_o_file: Bool do return false
120
121 fun add_to_jar: Bool do return false
122
123 # Additional libraries needed for the compilation
124 # Will be used with pkg-config
125 var pkgconfigs = new Array[String]
126 end
127
128 # An extern C file to compile
129 class ExternCFile
130 super ExternFile
131
132 # Custom options for the C compiler (CFLAGS)
133 var cflags: String
134
135 redef fun hash do return filename.hash
136 redef fun ==(o) do return o isa ExternCFile and filename == o.filename
137
138 redef fun makefile_rule_name do
139 var basename = filename.basename(".c")
140 var res = "{basename}.extern.o"
141 return res
142 end
143
144 redef fun makefile_rule_content do
145 var ff = filename.basename("")
146 var o = makefile_rule_name
147 var pkg = ""
148 if not pkgconfigs.is_empty then
149 pkg = "`pkg-config --cflags {pkgconfigs.join(" ")}`"
150 end
151 return "$(CC) $(CFLAGS) {self.cflags} {pkg} -c -o {o} {ff}"
152 end
153
154 redef fun compiles_to_o_file do return true
155 end
156