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