revised version of module makefile extraction

"flag" can be used in airframe file to give a global flag or define to a module
This commit is contained in:
Gautier Hattenberger
2010-08-31 13:08:29 +00:00
parent 1a76bdc43c
commit 0948bc036f
4 changed files with 129 additions and 90 deletions
+4 -3
View File
@@ -14,8 +14,9 @@
<!--load name="infrared_i2c.xml"/--> <!--load name="infrared_i2c.xml"/-->
<!--load name="max3100.xml"/> <!--load name="max3100.xml"/>
<load name="gsm.xml"/--> <load name="gsm.xml"/-->
<load name="sys_mon.xml"> <load name="demo_module.xml">
<param name="TEST" value="1"/> <flag name="TEST" value="1"/>
<flag name="TEST_FLAG"/>
</load> </load>
<!--load name="enose.xml"/--> <!--load name="enose.xml"/-->
<load name="light.xml"/> <load name="light.xml"/>
@@ -36,7 +37,7 @@
<subsystem name="radio_control" type="ppm"/> <subsystem name="radio_control" type="ppm"/>
<subsystem name="telemetry" type="xbee_api"/> <subsystem name="telemetry" type="xbee_api"/>
<subsystem name="control_new"/> <subsystem name="control" type="new"/>
<subsystem name="attitude" type="infrared"/> <subsystem name="attitude" type="infrared"/>
<subsystem name="gps" type="ublox_lea5h"/> <subsystem name="gps" type="ublox_lea5h"/>
<subsystem name="navigation"/> <subsystem name="navigation"/>
+6 -1
View File
@@ -21,8 +21,9 @@
<!ELEMENT linear EMPTY> <!ELEMENT linear EMPTY>
<!ELEMENT makefile (#PCDATA)> <!ELEMENT makefile (#PCDATA)>
<!ELEMENT modules (load)*> <!ELEMENT modules (load)*>
<!ELEMENT load (param)*> <!ELEMENT load (param|flag)*>
<!ELEMENT param EMPTY> <!ELEMENT param EMPTY>
<!ELEMENT flag EMPTY>
<!ELEMENT firmware (target|subsystem)*> <!ELEMENT firmware (target|subsystem)*>
<!ELEMENT target (param|define)*> <!ELEMENT target (param|define)*>
<!ELEMENT subsystem (param)*> <!ELEMENT subsystem (param)*>
@@ -95,6 +96,10 @@ value CDATA #IMPLIED
unit CDATA #IMPLIED unit CDATA #IMPLIED
integer CDATA #IMPLIED> integer CDATA #IMPLIED>
<!ATTLIST flag
name CDATA #REQUIRED
value CDATA #IMPLIED>
<!ATTLIST param <!ATTLIST param
name CDATA #REQUIRED name CDATA #REQUIRED
value CDATA #REQUIRED> value CDATA #REQUIRED>
+4
View File
@@ -14,5 +14,9 @@
<flag name="DEMO_MODULE_LED" value="2"/> <flag name="DEMO_MODULE_LED" value="2"/>
<file name="demo_module.c"/> <file name="demo_module.c"/>
</makefile> </makefile>
<makefile target="demo">
<flag name="SOME_FLAG"/>
<define name="SOME_DEFINE" value="bla"/>
</makefile>
</module> </module>
+115 -86
View File
@@ -62,17 +62,61 @@ let check_unique_id_and_name = fun conf ->
let pipe_regexp = Str.regexp "|" let pipe_regexp = Str.regexp "|"
let targets_of_field = fun field -> let targets_of_field = fun field ->
try try
Str.split pipe_regexp (Xml.attrib field "target") Str.split pipe_regexp (ExtXml.attrib_or_default field "target" "ap|sim")
with with
_ -> [] _ -> []
(** singletonize a sorted list *)
let rec singletonize = fun l ->
match l with
[] | [_] -> l
| x :: ((y :: t) as yt) -> if x = y then singletonize yt else x :: singletonize yt
let get_modules = fun dir m -> (** union of two lists *)
match String.lowercase (Xml.tag m) with let union = fun l1 l2 ->
"load" -> (dir // ExtXml.attrib m "name", Xml.children m) let l = l1 @ l2 in
| tag -> failwith (sprintf "Warning: tag load is undefined; found '%s'" tag) let sl = List.sort compare l in
singletonize sl
let union_of_lists = fun l ->
let sl = List.sort compare (List.flatten l) in
singletonize sl
(** [get_modules dir xml]
* [dir] is the conf directory for modules, [xml] is the parsed airframe.xml *)
let get_modules = fun dir xml ->
(* extract all "modules" sections *)
let modules = List.map (fun x ->
match String.lowercase (Xml.tag x) with
"modules" -> Xml.children x
| _ -> []
) (Xml.children xml) in
(* flatten the list (result is a list of "load" xml nodes) *)
let modules = List.flatten modules in
(* build a list (file name, (xml, xml list of flags)) *)
let extract = List.map (fun m ->
match String.lowercase (Xml.tag m) with
"load" -> let file = dir // ExtXml.attrib m "name" in
(file, (ExtXml.parse_file file, Xml.children m))
| tag -> failwith (sprintf "Warning: tag load is undefined; found '%s'" tag)
) modules in
(* return a list of name and a list of pairs (xml, xml list) *)
List.split extract
(** [get_targets_of_module xml] Returns the list of targets of a module *)
let get_targets_of_module = fun m ->
let targets = List.map (fun x ->
match String.lowercase (Xml.tag x) with
"makefile" -> targets_of_field x
| _ -> []
) (Xml.children m) in
(* return a singletonized list *)
singletonize (List.sort compare (List.flatten targets))
(** [get_modules_dir xml] Returns the list of modules directories *)
let get_modules_dir = fun modules ->
let dir = List.map (fun (m, _) -> try Xml.attrib m "dir" with _ -> ExtXml.attrib m "name") modules in
singletonize (List.sort compare dir)
(** (**
Search and dump the module section : Search and dump the module section :
@@ -80,87 +124,72 @@ let get_modules = fun dir m ->
f : makefile.ac f : makefile.ac
**) **)
let dump_module_section = fun xml f -> let dump_module_section = fun xml f ->
let files = ref [] in (* get modules *)
List.iter (fun x -> let (files, modules) = get_modules modules_dir xml in
if ExtXml.tag_is x "modules" then (* print modules directories and includes for all targets *)
let modules_names = List.map (get_modules modules_dir) (Xml.children x) in fprintf f "\n####################################################\n";
List.iter (fun (name,_) -> files := name :: !files) modules_names; fprintf f "# modules makefile section\n";
let modules_list = List.map (fun (m,p) -> (Xml.parse_file m, p)) modules_names in fprintf f "####################################################\n";
(* Print modules directories and includes for all targets *) fprintf f "\n# include modules directory for all targets\n";
fprintf f "\n# include modules directory for all targets\n"; (* get dir and target list *)
let target_list = ref [] in let dir_list = get_modules_dir modules in
let dir_list = ref [] in let target_list = union_of_lists (List.map (fun (m,_) -> get_targets_of_module m) modules) in
List.iter (fun (m,_) -> List.iter (fun target -> fprintf f "%s.CFLAGS += -I modules -I arch/$(ARCH)/modules\n" target) target_list;
let dir = try Xml.attrib m "dir" with _ -> ExtXml.attrib m "name" in List.iter (fun dir -> let dir_name = (String.uppercase dir)^"_DIR" in fprintf f "%s = modules/%s\n" dir_name dir) dir_list;
dir_list := List.merge String.compare !dir_list [dir]; (* parse each module *)
List.iter (fun l -> List.iter (fun (m, flags) ->
if ExtXml.tag_is l "makefile" then let name = ExtXml.attrib m "name" in
target_list := List.merge String.compare !target_list (targets_of_field l); let dir = try Xml.attrib m "dir" with _ -> name in
) (Xml.children m) let dir_name = (String.uppercase dir)^"_DIR" in
) modules_list; (* get the list of all the targes for this module *)
List.iter (fun target -> fprintf f "%s.CFLAGS += -I modules -I arch/$(ARCH)/modules\n" target) !target_list; let module_target_list = get_targets_of_module m in
List.iter (fun dir -> let dir_name = (String.uppercase dir)^"_DIR" in fprintf f "%s = modules/%s\n" dir_name dir) !dir_list; (* print global flags as compilation defines and flags *)
(* Parse each makefile *) fprintf f "\n# makefile for module %s in modules/%s\n" name dir;
List.iter (fun (modul,params) -> List.iter (fun target ->
let name = ExtXml.attrib modul "name" in List.iter (fun flag ->
let dir = try Xml.attrib modul "dir" with _ -> name in let name = ExtXml.attrib flag "name"
let dir_name = (String.uppercase dir)^"_DIR" in and value = try "="^(Xml.attrib flag "value") with _ -> "" in
(* Extract the list of all the targes for this module *) fprintf f "%s.CFLAGS += -D%s%s\n" target name value
let module_target_list = ref [] in ) flags
List.iter (fun l -> ) module_target_list;
if ExtXml.tag_is l "makefile" then module_target_list := List.merge String.compare !module_target_list (targets_of_field l) (* Look for makefile section *)
) (Xml.children modul); List.iter (fun l ->
fprintf f "\n# makefile for module %s\n" name; if ExtXml.tag_is l "makefile" then begin
(* Print parameters as global copilation defines *) let targets = targets_of_field l in
List.iter (fun target -> (* Look for defines, flags, files, ... *)
List.iter (fun param -> try List.iter (fun field ->
let name = Xml.attrib param "name" match String.lowercase (Xml.tag field) with
and value = Xml.attrib param "value" in "flag" ->
fprintf f "%s.CFLAGS += -D%s=%s\n" target name value List.iter (fun target ->
with _ -> () let value = try "="^(Xml.attrib field "value") with _ -> ""
) params and name = Xml.attrib field "name" in
) !module_target_list; let flag_type = match (ExtXml.attrib_or_default field "type" "define") with
(* Look for makefile section *) "define" | "D" -> "D"
List.iter (fun l -> | "include" | "I" -> "I"
if ExtXml.tag_is l "makefile" then begin | _ -> "D" in
let targets = targets_of_field l in fprintf f "%s.CFLAGS += -%s%s%s\n" target flag_type name value
(* Look for defines, flags, files, ... *) ) targets
List.iter (fun field -> | "file" ->
match String.lowercase (Xml.tag field) with let name = Xml.attrib field "name" in
"flag" -> List.iter (fun target -> fprintf f "%s.srcs += $(%s)/%s\n" target dir_name name) targets
List.iter | "file_hw" ->
(fun target -> let name = Xml.attrib field "name" in
let value = try "="^(Xml.attrib field "value") with _ -> "" List.iter (fun target -> fprintf f "%s.srcs += arch/$(ARCH)/$(%s)/%s\n" target dir_name name) targets
and name = Xml.attrib field "name" in | "define" ->
let flag_type = match (ExtXml.attrib_or_default field "type" "define") with let value = Xml.attrib field "value"
"define" | "D" -> "D" and name = Xml.attrib field "name" in
| "include" | "I" -> "I" fprintf f "%s = %s\n" name value
| _ -> "D" in | "raw" ->
fprintf f "%s.CFLAGS += -%s%s%s\n" target flag_type name value) begin match Xml.children field with
targets [Xml.PCData s] -> fprintf f "%s\n" s
| "file" -> | _ -> fprintf stderr "Warning: wrong makefile section in module '%s'\n" name
let name = Xml.attrib field "name" in end
List.iter (fun target -> fprintf f "%s.srcs += $(%s)/%s\n" target dir_name name) targets | _ -> ()
| "file_hw" -> ) (Xml.children l)
let name = Xml.attrib field "name" in end) (Xml.children m)
List.iter (fun target -> fprintf f "%s.srcs += arch/$(ARCH)/$(%s)/%s\n" target dir_name name) targets ) modules;
| "define" -> (** returns a list of modules file name *)
let value = Xml.attrib field "value" files
and name = Xml.attrib field "name" in
fprintf f "%s = %s\n" name value
| "raw" ->
begin match Xml.children field with
[Xml.PCData s] -> fprintf f "%s\n" s
| _ -> fprintf stderr "Warning: wrong makefile section in module '%s'\n" name
end
| _ -> ()
)
(Xml.children l)
end)
(Xml.children modul))
modules_list)
(Xml.children xml);
!files
(** (**
Search and dump the makefile sections Search and dump the makefile sections