nitc: refactor MModule cflags and ldflags to support different target platforms
authorAlexis Laferrière <alexis.laf@xymus.net>
Sun, 25 Jan 2015 16:10:52 +0000 (11:10 -0500)
committerAlexis Laferrière <alexis.laf@xymus.net>
Wed, 28 Jan 2015 14:42:36 +0000 (09:42 -0500)
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

src/c_tools.nit
src/compiler/abstract_compiler.nit
src/compiler/compiler_ffi.nit
src/ffi/c.nit
src/ffi/c_compiler_options.nit
src/ffi/cpp.nit
src/ffi/ffi.nit
src/ffi/java.nit
src/ffi/objc.nit

index b835f2a..6fa1f05 100644 (file)
@@ -125,7 +125,7 @@ end
 class ExternCFile
        super ExternFile
 
-       # Additional specific CC compiler -c flags
+       # Custom options for the C compiler (CFLAGS)
        var cflags: String
 
        redef fun hash do return filename.hash
index dfe463c..b1a5879 100644 (file)
@@ -2990,7 +2990,7 @@ redef class MModule
 
        # Give requided addinional system libraries (as given to LD_LIBS)
        # Note: can return null instead of an empty set
-       fun collect_linker_libs: nullable Set[String] do return null
+       fun collect_linker_libs: nullable Array[String] do return null
 end
 
 # Create a tool context to handle options and paths
index ac7bad3..dea917b 100644 (file)
@@ -49,6 +49,7 @@ extern void nitni_global_ref_incr(void*);
 extern void nitni_global_ref_decr(void*);
 """
 
+               var cflags = self.cflags[""].join(" ")
                nitni_ccu.write_as_nitni(self, v.compiler.modelbuilder.compile_dir)
 
                for file in nitni_ccu.files do
@@ -76,11 +77,8 @@ extern void nitni_global_ref_decr(void*);
 
        redef fun collect_linker_libs
        do
-               var s = ldflags
-               if s.is_empty then return null
-               var res = new ArraySet[String]
-               res.add s
-               return res
+               if not self.ldflags.keys.has("") then return null
+               return self.ldflags[""]
        end
 
        private var compiled_callbacks = new Array[NitniCallback]
index ebd2277..8da8ffe 100644 (file)
@@ -72,8 +72,14 @@ redef class Location
 end
 
 redef class MModule
-       var cflags = "" is writable
-       var ldflags = "" is writable
+       # FIXME make nullable the key of `cflags`, `ldflags` and `cppflags` when
+       # supported by the bootstrap
+
+       # Custom options for the C compiler (CFLAGS)
+       var cflags = new MultiHashMap[String, String]
+
+       # Custom options for the C linker (LDFLAGS)
+       var ldflags = new MultiHashMap[String, String]
 
        # Additional libraries needed for the compilation
        # Will be used with pkg-config
index e4756a8..4fbd5c4 100644 (file)
@@ -22,9 +22,11 @@ module c_compiler_options
 import c
 import cpp
 private import annotation
+private import platform
 
 redef class ToolContext
-       var cflags_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
@@ -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, "Annotation 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.cflags = "{mmodule.cflags} {opt}"
-       end
-
-       fun process_c_linker_annotation(mmodule: MModule, opt: String)
-       do
-               mmodule.ldflags = "{mmodule.ldflags} {opt}"
-       end
-
-       fun process_cpp_compiler_annotation(mmodule: MModule, opt: String)
-       do
-               mmodule.cppflags = "{mmodule.cppflags} {opt}"
-       end
 end
 
 abstract class CCompilerOption
index e114cd2..ba6c2e0 100644 (file)
@@ -27,7 +27,8 @@ end
 redef class MModule
        private var cpp_file: nullable CPPCompilationUnit = null
 
-       var cppflags = "" is writable
+       # Custom options for the C++ compiler (CPPFLAGS)
+       var cppflags = new MultiHashMap[String, String]
 end
 
 class CPPLanguage
@@ -133,7 +134,7 @@ class CPPLanguage
                mmodule.ffi_files.add(file)
 
                # add linked option to support C++
-               mmodule.ldflags = "{mmodule.ldflags} -lstdc++"
+               mmodule.ldflags.add_one("", "-lstdc++")
        end
 
        redef fun compile_callback(callback, mmodule, mainmodule, ecc)
@@ -180,7 +181,7 @@ class ExternCppFile
        var mmodule: MModule
 
        redef fun makefile_rule_name do return "{filename.basename("")}.o"
-       redef fun makefile_rule_content do return "$(CXX) $(CFLAGS) {mmodule.cppflags} -c {filename.basename("")} -o {filename.basename("")}.o"
+       redef fun makefile_rule_content do return "$(CXX) $(CFLAGS) {mmodule.cppflags[""].join(" ")} -c {filename.basename("")} -o {filename.basename("")}.o"
        redef fun compiles_to_o_file do return true
 end
 
index cccb7a0..93acf66 100644 (file)
@@ -60,6 +60,8 @@ redef class MModule
                        if mod.uses_ffi then ffi_ccu.header_custom.add("#include \"{mod.c_name}._ffi.h\"\n")
                end
 
+               var cflags = self.cflags[""].join(" ")
+
                ffi_ccu.write_as_impl(self, compdir)
                for filename in ffi_ccu.files do
                        var f = new ExternCFile(filename, cflags)
index 77c3c56..7827dac 100644 (file)
@@ -242,8 +242,8 @@ redef class MModule
        # Tell the C compiler where to find jni.h and how to link with libjvm
        private fun insert_compiler_options
        do
-               cflags = "{cflags} -I $(JAVA_HOME)/include/ -I $(JAVA_HOME)/include/linux/"
-               ldflags = "{ldflags} -L $(JNI_LIB_PATH) -ljvm"
+               cflags.add_one("", "-I $(JAVA_HOME)/include/ -I $(JAVA_HOME)/include/linux/")
+               ldflags.add_one("", "-L $(JNI_LIB_PATH) -ljvm")
        end
 
        # Name of the generated Java class where to store all implementation methods of this module
index 7e309bc..4aafb91 100644 (file)
@@ -154,7 +154,7 @@ private class ObjCCompilationUnit
 
                files.add compdir/c_file
 
-               mmodule.ldflags = "{mmodule.ldflags} -lobjc"
+               mmodule.ldflags.add_one("", "-lobjc")
 
                return new ExternObjCFile(compdir/c_file, mmodule)
        end