+ var cflags = self.cflags[""].join(" ")
+
+ ffi_ccu.write_as_impl(self, compdir)
+ for filename in ffi_ccu.files do
+ var f = new ExternCFile(filename, cflags)
+ f.pkgconfigs.add_all pkgconfigs
+ ffi_files.add(f)
+ end
+ end
+
+ # Avoid the compile a ffi propdef more than once
+ # See `AMethPropdef::compile_ffi_method`
+ # FIXME find a better way
+ private var compiled_ffi_methods = new HashSet[AMethPropdef]
+end
+
+redef class AModule
+
+ # Ensures all of the general foreign code of the module has been analyzed.
+ # Manages header blocks, extern class types and foreign dependancies between modules
+ fun ensure_compile_ffi_wrapper
+ do
+ var mmodule = mmodule
+ if mmodule == null or mmodule.ffi_ccu != null then return
+
+ # ready extern code compiler
+ var ffi_ccu = new CCompilationUnit
+ mmodule.ffi_ccu = ffi_ccu
+
+ # generate code
+ for block in n_extern_code_blocks do
+ var language = block.language
+ assert language != null
+ mmodule.present_languages.add(language)
+ language.compile_module_block(block, ffi_ccu, mmodule)
+ end
+
+ ffi_ccu.header_c_base.add( "#include \"{mmodule.c_name}._nitni.h\"\n" )
+
+ ffi_ccu.body_decl.add("#ifdef ANDROID\n")
+ ffi_ccu.body_decl.add(" #include <android/log.h>\n")
+ ffi_ccu.body_decl.add(" #define PRINT_ERROR(...) (void)__android_log_print(ANDROID_LOG_WARN, \"Nit\", __VA_ARGS__)\n")
+ ffi_ccu.body_decl.add("#else\n")
+ ffi_ccu.body_decl.add(" #define PRINT_ERROR(...) fprintf(stderr, __VA_ARGS__)\n")
+ ffi_ccu.body_decl.add("#endif\n")
+
+ for nclassdef in n_classdefs do
+ # Does it declares an extern type?
+ if nclassdef isa AStdClassdef and nclassdef.n_extern_code_block != null then
+ mmodule.uses_ffi = true
+ var language = nclassdef.n_extern_code_block.language
+ assert language != null
+ mmodule.present_languages.add(language)
+ nclassdef.n_extern_code_block.language.compile_extern_class(
+ nclassdef.n_extern_code_block.as(not null), nclassdef, ffi_ccu, mmodule)