From: Alexis Laferrière Date: Sun, 25 Jan 2015 16:10:52 +0000 (-0500) Subject: nitc: refactor MModule cflags and ldflags to support different target platforms X-Git-Tag: v0.7.1~3^2~3 X-Git-Url: http://nitlanguage.org nitc: refactor MModule cflags and ldflags to support different target platforms Signed-off-by: Alexis Laferrière --- diff --git a/src/c_tools.nit b/src/c_tools.nit index b835f2a..6fa1f05 100644 --- a/src/c_tools.nit +++ b/src/c_tools.nit @@ -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 diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index dfe463c..b1a5879 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -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 diff --git a/src/compiler/compiler_ffi.nit b/src/compiler/compiler_ffi.nit index ac7bad3..dea917b 100644 --- a/src/compiler/compiler_ffi.nit +++ b/src/compiler/compiler_ffi.nit @@ -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] diff --git a/src/ffi/c.nit b/src/ffi/c.nit index ebd2277..8da8ffe 100644 --- a/src/ffi/c.nit +++ b/src/ffi/c.nit @@ -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 diff --git a/src/ffi/c_compiler_options.nit b/src/ffi/c_compiler_options.nit index e4756a8..4fbd5c4 100644 --- a/src/ffi/c_compiler_options.nit +++ b/src/ffi/c_compiler_options.nit @@ -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 diff --git a/src/ffi/cpp.nit b/src/ffi/cpp.nit index e114cd2..ba6c2e0 100644 --- a/src/ffi/cpp.nit +++ b/src/ffi/cpp.nit @@ -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 diff --git a/src/ffi/ffi.nit b/src/ffi/ffi.nit index cccb7a0..93acf66 100644 --- a/src/ffi/ffi.nit +++ b/src/ffi/ffi.nit @@ -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) diff --git a/src/ffi/java.nit b/src/ffi/java.nit index 77c3c56..7827dac 100644 --- a/src/ffi/java.nit +++ b/src/ffi/java.nit @@ -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 diff --git a/src/ffi/objc.nit b/src/ffi/objc.nit index 7e309bc..4aafb91 100644 --- a/src/ffi/objc.nit +++ b/src/ffi/objc.nit @@ -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