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
# 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
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
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]
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
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
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
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
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)
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
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)
# 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
files.add compdir/c_file
- mmodule.ldflags = "{mmodule.ldflags} -lobjc"
+ mmodule.ldflags.add_one("", "-lobjc")
return new ExternObjCFile(compdir/c_file, mmodule)
end