+
+ # Makefile
+
+ # The path to `self` Makefile
+ fun makefile_path: nullable String do
+ var path = package_path
+ if path == null then return null
+ if not is_expanded then return null
+ return path / "Makefile"
+ end
+
+ # Does `self` have a Makefile?
+ fun has_makefile: Bool do
+ var makefile_path = self.makefile_path
+ if makefile_path == null then return false
+ return makefile_path.file_exists
+ end
+
+ private fun check_makefile(toolcontext: ToolContext, mainmodule: MModule) do
+ var model = toolcontext.modelbuilder.model
+ var filter = new ModelFilter(accept_example = false, accept_test = false)
+ var view = new ModelView(model, mainmodule, filter)
+
+ var cmd_bin = new CmdMains(view, mentity = self)
+ var res_bin = cmd_bin.init_command
+ if not res_bin isa CmdSuccess then return
+
+ for mmodule in cmd_bin.results.as(not null) do
+ if not mmodule isa MModule then continue
+
+ if mmodule.makefile_path == null then
+ toolcontext.warning(location, "missing-makefile",
+ "Warning: no Makefile for executable module `{mmodule.full_name}`")
+ end
+ end
+ end
+
+ private fun gen_makefile(model: Model, mainmodule: MModule): nullable String do
+ var filter = new ModelFilter(accept_example = false, accept_test = false)
+ var view = new ModelView(model, mainmodule, filter)
+
+ var pkg_path = package_path.as(not null)
+ var makefile_path = makefile_path.as(not null)
+
+ var bins = new Array[String]
+ var cmd_bin = new CmdMains(view, mentity = self)
+ var res_bin = cmd_bin.init_command
+ if res_bin isa CmdSuccess then
+ for mmodule in cmd_bin.results.as(not null) do
+ if not mmodule isa MModule then continue
+ var mmodule_makefile = mmodule.makefile_path
+ if mmodule_makefile != null and mmodule_makefile != makefile_path then continue
+
+ var file = mmodule.location.file
+ if file == null then continue
+ # Remove package path prefix
+ var bin_path = file.filename
+ if pkg_path.has_suffix("/") then
+ bin_path = bin_path.replace(pkg_path, "")
+ else
+ bin_path = bin_path.replace("{pkg_path}/", "")
+ end
+ bins.add bin_path
+ end
+ end
+
+ if bins.is_empty then return null
+
+ var make = new NitMakefile(bins)
+ make.render.write_to_file(makefile_path)
+ return makefile_path
+ end
+end
+
+redef class MModule
+ private fun makefile_path: nullable String do
+ var file = location.file
+ if file == null then return null
+
+ var dir = file.filename.dirname
+ var makefile = (dir / "Makefile")
+ if not makefile.file_exists then return null
+
+ for line in makefile.to_path.read_lines do
+ if line.has_prefix("{name}:") then return makefile
+ end
+ return null
+ end