Merge: Interpreter FFI: support the pkgconfig annotation
authorJean Privat <jean@pryen.org>
Fri, 11 Mar 2016 20:05:52 +0000 (15:05 -0500)
committerJean Privat <jean@pryen.org>
Fri, 11 Mar 2016 20:05:52 +0000 (15:05 -0500)
Pull-Request: #1980
Reviewed-by: Jean Privat <jean@pryen.org>

lib/libevent.nit
src/interpreter/dynamic_loading_ffi/on_demand_compiler.nit
tests/niti.skip
tests/nitvm.skip

index c01d417..84d21d7 100644 (file)
@@ -26,6 +26,7 @@ in "C header" `{
        #include <sys/types.h>
        #include <fcntl.h>
        #include <errno.h>
+       #include <string.h>
        #include <sys/socket.h>
 
        #include <event2/listener.h>
@@ -34,6 +35,10 @@ in "C header" `{
 `}
 
 in "C" `{
+
+// Protect callbacks for compatibility with light FFI
+#ifdef Connection_decr_ref
+
        // Callback forwarded to 'Connection.write_callback'
        static void c_write_cb(struct bufferevent *bev, Connection ctx) {
                Connection_write_callback(ctx);
@@ -58,6 +63,8 @@ in "C" `{
        {
                ConnectionFactory_accept_connection(ctx, listener, fd, address, socklen);
        }
+#endif
+
 `}
 
 # Structure to hold information and state for a Libevent dispatch loop.
index ab9e845..e826f05 100644 (file)
@@ -20,6 +20,7 @@ import c_tools
 import nitni
 import ffi
 import naive_interpreter
+import pkgconfig
 import debugger_socket # To linearize `ToolContext::init`
 
 redef class ToolContext
@@ -43,12 +44,16 @@ redef class AMethPropdef
                        n_extern_code_block.is_c) then return false
 
                for mparam in mpropdef.msignature.mparameters do
-                       var mtype = mparam.mtype
-                       if not mtype.is_cprimitive then
+                       if not mparam.mtype.is_cprimitive then
                                return false
                        end
                end
 
+               var return_mtype = mpropdef.msignature.return_mtype
+               if return_mtype != null and not return_mtype.is_cprimitive then
+                       return false
+               end
+
                return true
        end
 end
@@ -117,13 +122,29 @@ redef class AModule
                var srcs = [for file in ccu.files do new ExternCFile(file, ""): ExternFile]
                srcs.add_all mmodule.ffi_files
 
-               if mmodule.pkgconfigs.not_empty then
-                       fatal(v, "NOT YET IMPLEMENTED annotation `pkgconfig`")
-                       return false
-               end
-
+               # Compiler options specific to this module
                var ldflags = mmodule.ldflags[""].join(" ")
-               # TODO pkgconfig
+
+               # Protect pkg-config
+               var pkgconfigs = mmodule.pkgconfigs
+               var pkg_command = ""
+               if not pkgconfigs.is_empty then
+                       var cmd = "which pkg-config >/dev/null"
+                       if system(cmd) != 0 then
+                               v.fatal "FFI Error: Command `pkg-config` not found. Please install it"
+                               return false
+                       end
+
+                       for p in pkgconfigs do
+                               cmd = "pkg-config --exists '{p}'"
+                               if system(cmd) != 0 then
+                                       v.fatal "FFI Error: package {p} is not found by `pkg-config`. Please install it."
+                                       return false
+                               end
+                       end
+
+                       pkg_command = "`pkg-config --cflags --libs {pkgconfigs.join(" ")}`"
+               end
 
                # Compile each source file to an object file (or equivalent)
                var object_files = new Array[String]
@@ -132,9 +153,8 @@ redef class AModule
                end
 
                # Link everything in a shared library
-               # TODO customize the compiler
-               var cmd = "{v.c_compiler} -Wall -shared -o {foreign_code_lib_path} {object_files.join(" ")} {ldflags}"
-               if sys.system(cmd) != 0 then
+               var cmd = "{v.c_compiler} -Wall -shared -o {foreign_code_lib_path} {object_files.join(" ")} {ldflags} {pkg_command}"
+               if system(cmd) != 0 then
                        v.fatal "FFI Error: Failed to link native code using `{cmd}`"
                        return false
                end
index 0d45e5d..dae2c37 100644 (file)
@@ -36,3 +36,4 @@ test_ropebuffer
 ui_test
 test_text_stat
 nitsaf_args
+test_ffi_c_lots_of_refs
index 39ce010..6497642 100644 (file)
@@ -36,3 +36,4 @@ test_ropebuffer
 ui_test
 test_text_stat
 nitsaf.args
+test_ffi_c_lots_of_refs