X-Git-Url: http://nitlanguage.org diff --git a/src/c_tools.nit b/src/c_tools.nit index 663a059..61c1f9c 100644 --- a/src/c_tools.nit +++ b/src/c_tools.nit @@ -17,63 +17,67 @@ # provides tools to write C .c and .h files module c_tools -import compiling_writer +import template # Accumulates all C code for a compilation unit class CCompilationUnit ## header # comments and native interface imports - var header_c_base : Writer = new Writer + var header_c_base = new Template # custom C header code or generated for other languages - var header_custom : Writer = new Writer + var header_custom = new Template # types of extern classes and friendly types - var header_c_types : Writer = new Writer + var header_c_types = new Template # implementation declaration for extern methods - var header_decl : Writer = new Writer + var header_decl = new Template ## body # comments, imports, etc - var body_decl : Writer = new Writer + var body_decl = new Template # custom code and generated for ffi - var body_custom : Writer = new Writer + var body_custom = new Template # implementation body of extern methods - var body_impl : Writer = new Writer + var body_impl = new Template # files to compile TODO check is appropriate - #var files = new Array[String] + var files = new Array[String] - fun add_local_function( efc : CFunction ) + # Add a `static` `c_function` to be strictly local to this unit + fun add_local_function(c_function: CFunction) do - body_decl.add( "{efc.signature};\n" ) - body_impl.add( "\n" ) - body_impl.append( efc.to_writer ) + body_decl.add "static {c_function.signature};\n" + body_impl.add "\n" + body_impl.add c_function.to_writer end - fun add_exported_function( efc : CFunction ) + # Add a public `c_function` accessible from outside this compilation unit + fun add_exported_function(c_function: CFunction) do - header_decl.add( "{efc.signature};\n" ) - body_impl.add( "\n" ) - body_impl.append( efc.to_writer ) + body_decl.add "{c_function.signature};\n" + body_impl.add "\n" + body_impl.add c_function.to_writer end - fun compile_header_core( stream : OStream ) + # Write the core of the header to `stream` + fun compile_header_core(stream: Writer) do - header_c_base.write_to_stream( stream ) - header_custom.write_to_stream( stream ) - header_c_types.write_to_stream( stream ) - header_decl.write_to_stream( stream ) + header_c_base.write_to stream + header_custom.write_to stream + header_c_types.write_to stream + header_decl.write_to stream end - fun compile_body_core( stream : OStream ) + # Write the core of the body to `stream` + fun compile_body_core(stream: Writer) do - body_decl.write_to_stream( stream ) - body_custom.write_to_stream( stream ) - body_impl.write_to_stream( stream ) + body_decl.write_to stream + body_custom.write_to stream + body_impl.write_to stream end end @@ -81,21 +85,74 @@ end class CFunction var signature : String - var decls : Writer = new Writer - var exprs : Writer = new Writer + var decls = new Template + var exprs = new Template - fun to_writer : Writer + fun to_writer: Template do - var w = new Writer + var w = new Template - w.add( "{signature}\n\{\n" ) + w.add(signature) + w.add("\n\{\n") + w.add(decls) + w.add("\n") + w.add(exprs) + w.add("\}\n") - w.append( decls ) - w.add( "\n" ) - w.append( exprs ) + return w + end +end - w.add( "\}\n" ) +# An extern file to compile +class ExternFile - return w + # 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 +