mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-06-05 15:30:08 +08:00
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:
@@ -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"/>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user