nitc & niti: move the duplicated pkg-config checks to the pkgconfig module
authorAlexis Laferrière <alexis.laf@xymus.net>
Tue, 23 Jan 2018 18:48:32 +0000 (13:48 -0500)
committerAlexis Laferrière <alexis.laf@xymus.net>
Fri, 26 Jan 2018 03:23:35 +0000 (22:23 -0500)
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

src/compiler/abstract_compiler.nit
src/ffi/pkgconfig.nit
src/interpreter/dynamic_loading_ffi/on_demand_compiler.nit
tests/sav/error_annot_pkgconfig_alt0.res
tests/sav/error_annot_pkgconfig_alt1.res

index a3a0bc8..1a1bb07 100644 (file)
@@ -24,6 +24,7 @@ import c_tools
 private import annotation
 import mixin
 import counter
+import pkgconfig
 
 # Add compiling options
 redef class ToolContext
@@ -188,6 +189,8 @@ class MakefileToolchain
                var time1 = get_time
                self.toolcontext.info("*** END WRITING C: {time1-time0} ***", 2)
 
+               if not toolcontext.check_errors then return
+
                # Execute the Makefile
 
                if self.toolcontext.opt_no_cc.value then return
@@ -466,14 +469,19 @@ endif
                        f.close
                end
 
-               var java_files = new Array[ExternFile]
-
+               # pkg-config annotation support
                var pkgconfigs = new Array[String]
                for f in compiler.extern_bodies do
                        pkgconfigs.add_all f.pkgconfigs
                end
-               # Protect pkg-config
+
+               # Only test if pkg-config is used
                if not pkgconfigs.is_empty then
+
+                       # Check availability of pkg-config, silence the proc output
+                       toolcontext.check_pkgconfig_packages pkgconfigs
+
+                       # Double the check in the Makefile in case it's distributed
                        makefile.write """
 # does pkg-config exists?
 ifneq ($(shell which pkg-config >/dev/null; echo $$?), 0)
@@ -491,6 +499,7 @@ endif
                end
 
                # Compile each required extern body into a specific .o
+               var java_files = new Array[ExternFile]
                for f in compiler.extern_bodies do
                        var o = f.makefile_rule_name
                        var ff = f.filename.basename
index 84c4274..74dc8fc 100644 (file)
@@ -25,6 +25,42 @@ private import literal
 redef class ToolContext
        # Detects the `pkgconfig` annotation on the module declaration only
        var pkgconfig_phase: Phase = new PkgconfigPhase(self, [literal_phase])
+
+       # Is the external program `pkg-config` available?
+       var pkgconfig_is_available: Bool is lazy do
+               # Ignore/silence the process output
+               var proc_which = new ProcessReader("which", "pkg-config")
+               proc_which.wait
+
+               var status = proc_which.status
+               if status != 0 then
+                       error(null, "Error: program `pkg-config` not found, make sure it is installed.")
+                       return false
+               end
+               return true
+       end
+
+       # Check if the `packages` are known by the external program `pkg-config`
+       #
+       # Missing packages are reported to the console via `ToolContext::error`.
+       # Check for errors using `check_errors`.
+       fun check_pkgconfig_packages(packages: Array[String])
+       do
+               if not pkgconfig_is_available then return
+
+               for pkg in packages do
+                       var proc_exist = new Process("pkg-config", "--exists", pkg)
+                       proc_exist.wait
+                       var status = proc_exist.status
+                       if status == 1 then
+                               error(null,
+                                       "Error: dev package for `{pkg}` unknown by `pkg-config`, install it with `apt-get`, `brew` or similar.")
+                       else if status != 0 then
+                               error(null,
+                                       "Error: something went wrong calling `pkg-config`, make sure it is correctly configured.")
+                       end
+               end
+       end
 end
 
 # Detects the `pkgconfig` annotation on the module declaration only
@@ -67,27 +103,7 @@ private class PkgconfigPhase
                        end
                end
 
-               # check availability of pkg-config
-               var proc_which = new ProcessReader("which", "pkg-config")
-               proc_which.wait
-               var status = proc_which.status
-               if status != 0 then
-                       modelbuilder.error(nat, "Error: program `pkg-config` not found, make sure it is installed.")
-                       return
-               end
-
                for pkg in pkgs do
-                       var proc_exist = new Process("pkg-config", "--exists", pkg)
-                       proc_exist.wait
-                       status = proc_exist.status
-                       if status == 1 then
-                               modelbuilder.error(nat, "Error: dev package for `{pkg}` unknown by `pkg-config`, install it with `apt-get`, `brew` or similar.")
-                               continue
-                       else if status != 0 then
-                               modelbuilder.error(nat, "Error: something went wrong calling `pkg-config`, make sure it is correctly installed.")
-                               continue
-                       end
-
                        mmodule.pkgconfigs.add pkg
                end
        end
index 3ac05af..44f6854 100644 (file)
@@ -138,19 +138,10 @@ redef class AModule
                var pkgconfigs = mmodule.pkgconfigs
                var pkg_cflags = ""
                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
+                       # Check if the pkgconfig packages are available
+                       v.modelbuilder.toolcontext.check_pkgconfig_packages pkgconfigs
+                       if not v.modelbuilder.toolcontext.check_errors then return false
 
                        pkg_cflags = "`pkg-config --cflags {pkgconfigs.join(" ")}`"
                        ldflags += " `pkg-config --libs {pkgconfigs.join(" ")}`"
index c8148e7..27eaad6 100644 (file)
@@ -1 +1 @@
-alt/error_annot_pkgconfig_alt0.nit:17,38--46: Error: dev package for `error_annot_pkgconfig_alt0` unknown by `pkg-config`, install it with `apt-get`, `brew` or similar.
+Error: dev package for `error_annot_pkgconfig_alt0` unknown by `pkg-config`, install it with `apt-get`, `brew` or similar.
index 4fb9358..2f724ff 100644 (file)
@@ -1,2 +1,2 @@
-alt/error_annot_pkgconfig_alt1.nit:18,38--82: Error: dev package for `missing-lib` unknown by `pkg-config`, install it with `apt-get`, `brew` or similar.
-alt/error_annot_pkgconfig_alt1.nit:18,38--82: Error: dev package for `other missing lib` unknown by `pkg-config`, install it with `apt-get`, `brew` or similar.
+Error: dev package for `missing-lib` unknown by `pkg-config`, install it with `apt-get`, `brew` or similar.
+Error: dev package for `other missing lib` unknown by `pkg-config`, install it with `apt-get`, `brew` or similar.