b835f2aec9f58535b1e10ba23066b2577297fc6e
[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 fun add_local_function( efc : CFunction )
51 do
52 body_decl.add "static {efc.signature};\n"
53 body_impl.add "\n"
54 body_impl.add efc.to_writer
55 end
56
57 fun add_exported_function( efc : CFunction )
58 do
59 header_decl.add( "{efc.signature};\n" )
60 body_impl.add( "\n" )
61 body_impl.add( efc.to_writer )
62 end
63
64 fun compile_header_core( stream : OStream )
65 do
66 header_c_base.write_to( stream )
67 header_custom.write_to( stream )
68 header_c_types.write_to( stream )
69 header_decl.write_to( stream )
70 end
71
72 fun compile_body_core( stream : OStream )
73 do
74 body_decl.write_to( stream )
75 body_custom.write_to( stream )
76 body_impl.write_to( stream )
77 end
78 end
79
80 # Accumulates C code related to a specific function
81 class CFunction
82 var signature : String
83
84 var decls = new Template
85 var exprs = new Template
86
87 fun to_writer: Template
88 do
89 var w = new Template
90
91 w.add(signature)
92 w.add("\n\{\n")
93 w.add(decls)
94 w.add("\n")
95 w.add(exprs)
96 w.add("\}\n")
97
98 return w
99 end
100 end
101
102 # An extern file to compile
103 class ExternFile
104 # The filename of the file
105 var filename: String
106
107 # The name of the target in the Makefile
108 # Usually the produced .o file
109 fun makefile_rule_name: String is abstract
110
111 # The content of the rule in the make
112 # Usually the one-line shell command after the tabulation
113 fun makefile_rule_content: String is abstract
114
115 fun compiles_to_o_file: Bool do return false
116
117 fun add_to_jar: Bool do return false
118
119 # Additional libraries needed for the compilation
120 # Will be used with pkg-config
121 var pkgconfigs = new Array[String]
122 end
123
124 # An extern C file to compile
125 class ExternCFile
126 super ExternFile
127
128 # Additional specific CC compiler -c flags
129 var cflags: String
130
131 redef fun hash do return filename.hash
132 redef fun ==(o) do return o isa ExternCFile and filename == o.filename
133
134 redef fun makefile_rule_name do
135 var basename = filename.basename(".c")
136 var res = "{basename}.extern.o"
137 return res
138 end
139
140 redef fun makefile_rule_content do
141 var ff = filename.basename("")
142 var o = makefile_rule_name
143 var pkg = ""
144 if not pkgconfigs.is_empty then
145 pkg = "`pkg-config --cflags {pkgconfigs.join(" ")}`"
146 end
147 return "$(CC) $(CFLAGS) {self.cflags} {pkg} -c -o {o} {ff}"
148 end
149
150 redef fun compiles_to_o_file do return true
151 end
152