Merge: doc: fixed some typos and other misc. corrections
[nit.git] / src / ffi / c_compiler_options.nit
index af4e938..8bb2e44 100644 (file)
@@ -14,7 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# Offers the annotations `c_compiler_option` and `c_linker_option` to specify
+# Offers the annotations `cflags` and `ldflags` to specify
 # options for the C compiler directly or indirectly. Differs from the `pkgconfig`
 # annotation by the separation of the options between the compiler and linker.
 module c_compiler_options
@@ -22,17 +22,19 @@ module c_compiler_options
 import c
 import cpp
 private import annotation
+private import platform
 
 redef class ToolContext
-       var c_compiler_options_phase: Phase = new CCompilerOptionsPhase(self, null)
+       # Phase to find `cflags`, `ldflags` and `cppflags`
+       var cflags_phase: Phase = new CCompilerOptionsPhase(self, [platform_phase])
 end
 
 private class CCompilerOptionsPhase
        super Phase
 
-       fun compiler_annotation_name: String do return "c_compiler_option"
-       fun linker_annotation_name: String do return "c_linker_option"
-       fun cpp_compiler_annotation_name: String do return "cpp_compiler_option"
+       fun compiler_annotation_name: String do return "cflags"
+       fun linker_annotation_name: String do return "ldflags"
+       fun cpp_compiler_annotation_name: String do return "cppflags"
 
        redef fun process_annotated_node(nmoduledecl, nat)
        do
@@ -46,13 +48,13 @@ private class CCompilerOptionsPhase
                var modelbuilder = toolcontext.modelbuilder
 
                if not nmoduledecl isa AModuledecl then
-                       modelbuilder.error(nat, "Syntax error: only the declaration of modules may use \"{annotation_name}\".")
+                       modelbuilder.error(nat, "Syntax Error: only the declaration of modules may use `{annotation_name}`.")
                        return
                end
 
                var args = nat.n_args
                if args.is_empty then
-                       modelbuilder.error(nat, "Syntax error: \"{annotation_name}\" expects at least one argument.")
+                       modelbuilder.error(nat, "Syntax Error: `{annotation_name}` expects at least one argument.")
                        return
                end
 
@@ -66,15 +68,15 @@ private class CCompilerOptionsPhase
                        else if expr isa ACallExpr then
                                # We support calls to "exec" only
                                var exec_args = expr.n_args.to_a
-                               if expr.n_id.text != "exec" or exec_args.is_empty then
-                                       modelbuilder.error(nat, "Syntax error: \"{annotation_name}\" accepts only calls to `exec` with the command as arguments.")
+                               if expr.n_qid.n_id.text != "exec" or exec_args.is_empty then
+                                       modelbuilder.error(nat, "Syntax Error: `{annotation_name}` accepts only calls to `exec` with the command as arguments.")
                                        return
                                end
 
                                var exec_args_as_strings = new Array[String]
                                for exec_arg in exec_args do
                                        if not exec_arg isa AStringFormExpr then
-                                               modelbuilder.error(nat, "Syntax error: calls to `exec` expects the arguments to be String literals.")
+                                               modelbuilder.error(nat, "Syntax Error: calls to `exec` expects the arguments to be String literals.")
                                                return
                                        else
                                                var arg_string = exec_arg.collect_text
@@ -86,7 +88,7 @@ private class CCompilerOptionsPhase
                                var opt = new ExecCCompilerOption(exec_args_as_strings, expr)
                                options.add(opt)
                        else
-                               modelbuilder.error(nat, "Syntax error: \"{annotation_name}\" expects its arguments to be the name of the package as String literals.")
+                               modelbuilder.error(nat, "Syntax Error: `{annotation_name}` expects its arguments to be the name of the package as String literals.")
                                return
                        end
                end
@@ -99,10 +101,10 @@ private class CCompilerOptionsPhase
                                var cmd_args = opt.command
                                var proc
                                if cmd_args.length == 1 then
-                                       proc = new IProcess.from_a(cmd_args[0], new Array[String])
+                                       proc = new ProcessReader.from_a(cmd_args[0], new Array[String])
                                else if cmd_args.length > 1 then
                                        var rest_args = cmd_args.subarray(1, cmd_args.length-1)
-                                       proc = new IProcess.from_a(cmd_args[0], rest_args)
+                                       proc = new ProcessReader.from_a(cmd_args[0], rest_args)
                                else abort
 
                                # wait for its completion
@@ -111,14 +113,14 @@ private class CCompilerOptionsPhase
                                # check result
                                var status = proc.status
                                if status != 0 then
-                                       modelbuilder.error(opt.exec_node, "Annotation error: Something went wrong executing the argument of annotation \"{annotation_name}\", make sure the command is valid.")
+                                       modelbuilder.error(opt.exec_node, "Error: something went wrong when executing the argument of `{annotation_name}`, make sure the command is valid.")
                                        return
                                end
 
                                # process result
                                var result = proc.read_all.replace("\n", " ")
                                if result.is_empty then
-                                       modelbuilder.error(opt.exec_node, "Annotation error: Got no result from the command, make sure it is valid.")
+                                       modelbuilder.error(opt.exec_node, "Error: got no result from the command, make sure it is valid.")
                                        return
                                end
                                simplified_options.add(new DirectCCompilerOption(result))
@@ -128,35 +130,45 @@ private class CCompilerOptionsPhase
                        end
                end
 
-               # retreive module
+               # Retrieve module
                var mmodule = nmoduledecl.parent.as(AModule).mmodule.as(not null)
 
+               # Get target platform from annotation on annotation
+               var platform = ""
+
+               ## Is there an imported platform?
+               var target_platform = mmodule.target_platform
+               if target_platform != null then
+                       platform = target_platform.name or else ""
+               end
+
+               ## Is the platform declared explicitly?
+               var annots = nat.n_annotations
+               if annots != null then
+                       var items = annots.n_items
+                       if items.length > 1 then
+                               modelbuilder.error(annots, "Syntax Error: `{annotation_name}` accepts only a single annotation, the platform name.")
+                               return
+                       end
+                       assert items.length == 1
+
+                       var item = items.first
+                       platform = item.name
+               end
+
+               # Store the flags in the module
                for opt in simplified_options do
-                       var cmd = opt.option
+                       var arg = opt.option
                        if annotation_name == compiler_annotation_name then
-                               process_c_compiler_annotation(mmodule, cmd)
+                               mmodule.cflags.add_one(platform, arg)
                        else if annotation_name == linker_annotation_name then
-                               process_c_linker_annotation(mmodule, cmd)
+                               mmodule.ldflags.add_one(platform, arg)
                        else if annotation_name == cpp_compiler_annotation_name then
-                               process_cpp_compiler_annotation(mmodule, cmd)
+                               mmodule.cppflags.add_one(platform, arg)
                        else abort
                end
        end
 
-       fun process_c_compiler_annotation(mmodule: MModule, opt: String)
-       do
-               mmodule.c_compiler_options = "{mmodule.c_compiler_options} {opt}"
-       end
-
-       fun process_c_linker_annotation(mmodule: MModule, opt: String)
-       do
-               mmodule.c_linker_options = "{mmodule.c_linker_options} {opt}"
-       end
-
-       fun process_cpp_compiler_annotation(mmodule: MModule, opt: String)
-       do
-               mmodule.cpp_compiler_options = "{mmodule.cpp_compiler_options} {opt}"
-       end
 end
 
 abstract class CCompilerOption