mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-23 21:36:28 +08:00
makefile extraction moved to gen_aircraft. Better handling of modules dependencies
This commit is contained in:
@@ -120,11 +120,6 @@ $(TUNING_H) : $(SETTINGS_XMLS) $(CONF_XML) $(TOOLS)/gen_tuning.out
|
||||
$(Q)cp $@ $(TUNING_INC_H)
|
||||
$(Q)chmod a+r $@ $(TUNING_INC_H)
|
||||
|
||||
$(MAKEFILE_AC) : $(CONF)/$(AIRFRAME_XML)
|
||||
@echo BUILD $@
|
||||
$(Q)mkdir -p $(ACINCLUDE)
|
||||
$(Q)$(TOOLS)/extract_makefile.out $< $(MODULES_DIR) > $@
|
||||
|
||||
$(MODULES_H) : $(CONF)/$(AIRFRAME_XML) $(TOOLS)/gen_modules.out $(CONF)/modules/*.xml
|
||||
@echo BUILD $@
|
||||
$(Q)$(TOOLS)/gen_modules.out $(MODULES_DIR) $(MODULES_C) $< > $@
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ OCAMLNETCMA=$(shell ocamlfind query -r -a-format -predicates byte netstring)
|
||||
OCAMLLEX=ocamllex
|
||||
OCAMLYACC=ocamlyacc
|
||||
|
||||
all: gen_aircraft.out gen_airframe.out gen_messages.out gen_ubx.out gen_flight_plan.out gen_radio.out extract_makefile.out gen_periodic.out gen_settings.out gen_tuning.out gen_xsens.out gen_modules.out
|
||||
all: gen_aircraft.out gen_airframe.out gen_messages.out gen_ubx.out gen_flight_plan.out gen_radio.out gen_periodic.out gen_settings.out gen_tuning.out gen_xsens.out gen_modules.out
|
||||
|
||||
FP_CMO = fp_syntax.cmo fp_parser.cmo fp_lexer.cmo fp_proc.cmo gen_flight_plan.cmo
|
||||
ABS_FP = $(FP_CMO:%=$$PAPARAZZI_SRC/sw/tools/%)
|
||||
|
||||
+123
-8
@@ -30,12 +30,14 @@ let (//) = Filename.concat
|
||||
|
||||
let paparazzi_conf = Env.paparazzi_home // "conf"
|
||||
let conf_xml = paparazzi_conf // "conf.xml"
|
||||
let modules_dir = paparazzi_conf // "modules"
|
||||
|
||||
let mkdir = fun d ->
|
||||
if not (Sys.file_exists d) then
|
||||
Unix.mkdir d 0o755
|
||||
|
||||
let check_unique_id = fun conf ->
|
||||
(** Raises a Failure if an ID or a NAME appears twice in the conf *)
|
||||
let check_unique_id_and_name = fun conf ->
|
||||
let ids = Hashtbl.create 5
|
||||
and names = Hashtbl.create 5 in
|
||||
List.iter
|
||||
@@ -57,20 +59,118 @@ let check_unique_id = fun conf ->
|
||||
|
||||
|
||||
|
||||
let pipe_regexp = Str.regexp "|"
|
||||
let targets_of_field = fun field ->
|
||||
try
|
||||
Str.split pipe_regexp (Xml.attrib field "target")
|
||||
with
|
||||
_ -> []
|
||||
|
||||
|
||||
let get_modules = fun dir m ->
|
||||
match String.lowercase (Xml.tag m) with
|
||||
"load" -> dir // ExtXml.attrib m "name"
|
||||
| tag -> failwith (sprintf "Warning: tag load is undefined; found '%s'" tag)
|
||||
|
||||
|
||||
|
||||
(** Extracts the makefile section of an airframe file *)
|
||||
let extract_makefile = fun airframe_file makefile_ac ->
|
||||
let xml = Xml.parse_file airframe_file in
|
||||
let f = open_out makefile_ac in
|
||||
|
||||
fprintf f "# This file has been generated from %s by %s\n" airframe_file Sys.argv.(0);
|
||||
fprintf f "# Please DO NOT EDIT\n";
|
||||
|
||||
(** Search and dump the makefile sections *)
|
||||
List.iter (fun x ->
|
||||
if ExtXml.tag_is x "makefile" then begin
|
||||
begin try
|
||||
fprintf f "\n# makefile target '%s'\n" (Xml.attrib x "target")
|
||||
with _ -> () end;
|
||||
match Xml.children x with
|
||||
[Xml.PCData s] -> fprintf f "%s\n" s
|
||||
| _ -> failwith (sprintf "Warning: wrong makefile section in '%s': %s\n" airframe_file (Xml.to_string_fmt x))
|
||||
end)
|
||||
(Xml.children xml);
|
||||
|
||||
(** Look for modules *)
|
||||
let modules_exist = ref [] in (* Targets requring modules *)
|
||||
let files = ref [] in
|
||||
List.iter (fun x ->
|
||||
if ExtXml.tag_is x "modules" then
|
||||
let modules_names =List.map (get_modules modules_dir) (Xml.children x) in
|
||||
List.iter (fun name -> files := name :: !files) modules_names;
|
||||
let modules_list = List.map Xml.parse_file modules_names in
|
||||
List.iter (fun modul ->
|
||||
let name = ExtXml.attrib modul "name" in
|
||||
let dir_name = (String.uppercase name)^"_DIR" in
|
||||
fprintf f "\n# makefile for module %s\n" name;
|
||||
fprintf f "%s = $(PAPARAZZI_SRC)/sw/airborne/modules/%s\n" dir_name name;
|
||||
List.iter (fun l ->
|
||||
if ExtXml.tag_is l "makefile" then begin
|
||||
let targets = targets_of_field l in
|
||||
List.iter (fun t ->
|
||||
if not (List.mem t !modules_exist) then begin
|
||||
fprintf f "%s.srcs += $(ACINCLUDE)/modules.c\n" t;
|
||||
modules_exist := t :: !modules_exist
|
||||
end;
|
||||
fprintf f "%s.CFLAGS += -I $(%s)\n" t dir_name
|
||||
) targets;
|
||||
List.iter (fun field ->
|
||||
match String.lowercase (Xml.tag field) with
|
||||
"flag" ->
|
||||
List.iter
|
||||
(fun target ->
|
||||
let value = ExtXml.attrib_or_default field "value" ""
|
||||
and name = Xml.attrib field "name" in
|
||||
fprintf f "%s.CFLAGS += -D%s%s\n" target name value)
|
||||
targets
|
||||
| "file" ->
|
||||
let name = Xml.attrib field "name" in
|
||||
List.iter
|
||||
(fun target -> fprintf f "%s.srcs += $(%s)/%s\n" target dir_name name)
|
||||
targets
|
||||
| _ -> ()
|
||||
)
|
||||
(Xml.children l)
|
||||
end)
|
||||
(Xml.children modul))
|
||||
modules_list)
|
||||
(Xml.children xml);
|
||||
|
||||
close_out f;
|
||||
!files
|
||||
|
||||
|
||||
|
||||
let is_older = fun target_file dep_files ->
|
||||
not (Sys.file_exists target_file) ||
|
||||
let target_file_time = (Unix.stat target_file).Unix.st_mtime in
|
||||
let rec loop = function
|
||||
[] -> false
|
||||
| f::fs ->
|
||||
target_file_time < (Unix.stat f).Unix.st_mtime ||
|
||||
loop fs in
|
||||
loop dep_files
|
||||
|
||||
|
||||
|
||||
(******************************* MAIN ****************************************)
|
||||
let () =
|
||||
if Array.length Sys.argv <> 2 then
|
||||
failwith (sprintf "Usage: %s <A/C ident (conf.xml)>" Sys.argv.(0));
|
||||
let aircraft = Sys.argv.(1) in
|
||||
let conf = Xml.parse_file conf_xml in
|
||||
check_unique_id conf;
|
||||
check_unique_id_and_name conf;
|
||||
let aircraft_xml =
|
||||
try
|
||||
ExtXml.child conf ~select:(fun x -> Xml.attrib x "name" = aircraft) "aircraft"
|
||||
with
|
||||
with
|
||||
Not_found -> failwith (sprintf "Aircraft '%s' not found in '%s'" aircraft conf_xml)
|
||||
in
|
||||
|
||||
in
|
||||
let value = ExtXml.attrib aircraft_xml in
|
||||
let value = fun attrib -> ExtXml.attrib aircraft_xml attrib in
|
||||
|
||||
let aircraft_dir = Env.paparazzi_home // "var" // aircraft in
|
||||
let aircraft_conf_dir = aircraft_dir // "conf" in
|
||||
@@ -93,21 +193,25 @@ let () =
|
||||
fprintf stderr "\nWARNING: No 'settings' attribute specified for A/C '%s', using 'settings/basic.xml'\n\n%!" aircraft;
|
||||
"settings/basic.xml" in
|
||||
|
||||
(** Expands the configuration of the A/C into one single file *)
|
||||
let conf_aircraft = Env.expand_ac_xml aircraft_xml in
|
||||
let conf_aircraft_file = aircraft_conf_dir // "conf_aircraft.xml" in
|
||||
let f = open_out conf_aircraft_file in
|
||||
Printf.fprintf f "%s\n" (ExtXml.to_string_fmt conf_aircraft);
|
||||
close_out f;
|
||||
|
||||
(** Computes and store a signature of the configuration *)
|
||||
let md5sum = Digest.to_hex (Digest.file conf_aircraft_file) in
|
||||
let md5sum_file = aircraft_conf_dir // "aircraft.md5" in
|
||||
let f = open_out md5sum_file in
|
||||
Printf.fprintf f "%s\n" md5sum;
|
||||
close_out f;
|
||||
|
||||
let airframe_file = value "airframe" in
|
||||
|
||||
(** Calls the Makefile with target and options *)
|
||||
let make = fun target options ->
|
||||
let c = sprintf "make -f Makefile.ac AIRCRAFT=%s AC_ID=%s AIRFRAME_XML=%s TELEMETRY=%s SETTINGS=\"%s\" MD5SUM=\"%s\" %s %s" aircraft (value "ac_id") (value "airframe") (value "telemetry") settings md5sum options target in
|
||||
prerr_endline c;
|
||||
let c = sprintf "make -f Makefile.ac AIRCRAFT=%s AC_ID=%s AIRFRAME_XML=%s TELEMETRY=%s SETTINGS=\"%s\" MD5SUM=\"%s\" %s %s" aircraft (value "ac_id") airframe_file (value "telemetry") settings md5sum options target in
|
||||
begin (** Quiet is speficied in the Makefile *)
|
||||
try if Sys.getenv "Q" <> "@" then raise Not_found with
|
||||
Not_found -> prerr_endline c
|
||||
@@ -116,6 +220,7 @@ let () =
|
||||
if returned_code <> 0 then
|
||||
exit returned_code in
|
||||
|
||||
(** Calls the makefile if the optional attribute is available *)
|
||||
let make_opt = fun target var attr ->
|
||||
try
|
||||
let value = Xml.attrib aircraft_xml attr in
|
||||
@@ -123,7 +228,17 @@ let () =
|
||||
with
|
||||
Xml.No_attribute _ -> () in
|
||||
|
||||
make "makefile_ac" "";
|
||||
let temp_makefile_ac = Filename.temp_file "Makefile.ac" "tmp" in
|
||||
let abs_airframe_file = paparazzi_conf // airframe_file in
|
||||
|
||||
let modules_files = extract_makefile abs_airframe_file temp_makefile_ac in
|
||||
|
||||
(* Create Makefile.ac only if needed *)
|
||||
let makefile_ac = aircraft_dir // "Makefile.ac" in
|
||||
if is_older makefile_ac (abs_airframe_file :: modules_files) then begin
|
||||
assert(Sys.command (sprintf "mv %s %s" temp_makefile_ac makefile_ac) = 0)
|
||||
end;
|
||||
|
||||
make "all_ac_h" "";
|
||||
make_opt "radio_ac_h" "RADIO" "radio";
|
||||
make_opt "flight_plan_ac_h" "FLIGHT_PLAN" "flight_plan"
|
||||
|
||||
Reference in New Issue
Block a user