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.
-class PkgconfigPhase
+# Detects the `pkgconfig` annotation on the module declaration only
+private class PkgconfigPhase
super Phase
redef fun process_annotated_node(nmoduledecl, nat)
var modelbuilder = toolcontext.modelbuilder
if not nmoduledecl isa AModuledecl then
- modelbuilder.error(nat, "Syntax error: only the declaration of modules may use \"pkgconfig\".")
+ modelbuilder.error(nat, "Syntax Error: only the declaration of modules may use `pkgconfig`.")
return
end
- # retreive module
+ # retrieve module
var nmodule = nmoduledecl.parent.as(AModule)
var mmodule = nmodule.mmodule.as(not null)
for arg in args do
var pkg = arg.as_string
if pkg == null then
- modelbuilder.error(nat, "Syntax error: \"pkgconfig\" expects its arguments to be the name of the package as String literals.")
+ modelbuilder.error(nat, "Syntax Error: `pkgconfig` expects its arguments to be the name of the package as String literals.")
return
end
end
end
- # check availability of pkg-config
- var proc_which = new IProcess("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: package \"{pkg}\" unknown by pkg-config, make sure the development package is be installed.")
- return
- else if status != 0 then
- modelbuilder.error(nat, "Error: something went wrong calling pkg-config, make sure it is correctly installed.")
- return
- end
-
- # compiler
- var proc = new IProcess("pkg-config", "--cflags", pkg)
- var compiler_opts = proc.read_all
- mmodule.c_compiler_options = "{mmodule.c_compiler_options} {compiler_opts.replace("\n", " ")}"
-
- # linker
- proc = new IProcess("pkg-config", "--libs", pkg)
- var linker_opts = proc.read_all
- mmodule.c_linker_options = "{mmodule.c_linker_options} {linker_opts.replace("\n", " ")}"
+ mmodule.pkgconfigs.add pkg
end
-
end
end