Merge: doc: fixed some typos and other misc. corrections
[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 a `static` `c_function` to be strictly 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 a public `c_function` accessible from outside this compilation unit
59 fun add_exported_function(c_function: CFunction)
60 do
61 body_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
109 # Filename relative to the nit-compile folder
110 var filename: String
111
112 # The name of the target in the Makefile
113 # Usually the produced .o file
114 fun makefile_rule_name: String is abstract
115
116 # The content of the rule in the make
117 # Usually the one-line shell command after the tabulation
118 fun makefile_rule_content: String is abstract
119
120 fun compiles_to_o_file: Bool do return false
121
122 # Is `self` a Java file to include in the JAR archive?
123 fun add_to_jar: Bool do return false
124
125 # Additional libraries needed for the compilation
126 # Will be used with pkg-config
127 var pkgconfigs = new Array[String]
128 end
129
130 # An extern C file to compile
131 class ExternCFile
132 super ExternFile
133
134 # Custom options for the C compiler (CFLAGS)
135 var cflags: String
136
137 redef fun hash do return filename.hash
138 redef fun ==(o) do return o isa ExternCFile and filename == o.filename
139
140 redef fun makefile_rule_name do
141 var basename = filename.basename(".c")
142 var res = "{basename}.extern.o"
143 return res
144 end
145
146 redef fun makefile_rule_content do
147 var ff = filename.basename
148 var o = makefile_rule_name
149 var pkg = ""
150 if not pkgconfigs.is_empty then
151 pkg = "`pkg-config --cflags {pkgconfigs.join(" ")}`"
152 end
153 return "$(CC) $(CFLAGS) -Wall -Wno-unused-function {self.cflags} {pkg} -c -o {o} {ff}"
154 end
155
156 redef fun compiles_to_o_file do return true
157 end
158