ソースを参照

[cs] Add -D unity_std_target

Cauê Waneck 11 年 前
コミット
cc771222b8
3 ファイル変更60 行追加12 行削除
  1. 2 0
      common.ml
  2. 54 8
      gencommon.ml
  3. 4 4
      gencs.ml

+ 2 - 0
common.ml

@@ -228,6 +228,7 @@ module Define = struct
 		| SwfScriptTimeout
 		| SwfUseDoAbc
 		| Sys
+		| UnityStdTarget
 		| Unsafe
 		| UseNekoc
 		| UseRttiDoc
@@ -302,6 +303,7 @@ module Define = struct
 		| SwfScriptTimeout -> ("swf_script_timeout", "Maximum ActionScript processing time before script stuck dialog box displays (in seconds)")
 		| SwfUseDoAbc -> ("swf_use_doabc", "Use DoAbc swf-tag instead of DoAbcDefine")
 		| Sys -> ("sys","Defined for all system platforms")
+		| UnityStdTarget -> ("unity_std_target", "Changes C# sources location so that each generated C# source is relative to the Haxe source location. If the location is outside the current directory, the value set here will be used")
 		| Unsafe -> ("unsafe","Allow unsafe code when targeting C#")
 		| UseNekoc -> ("use_nekoc","Use nekoc compiler instead of internal one")
 		| UseRttiDoc -> ("use_rtti_doc","Allows access to documentation during compilation")

+ 54 - 8
gencommon.ml

@@ -49,6 +49,7 @@ open Type
 open Common
 open Option
 open Printf
+open ExtString
 
 let debug_type_ctor = function
 	| TMono _ -> "TMono"
@@ -779,10 +780,10 @@ let reorder_modules gen =
 	let con = gen.gcon in
 	con.modules <- [];
 	let processed = Hashtbl.create 20 in
-	Hashtbl.iter (fun md_path _ ->
+	Hashtbl.iter (fun md_path md ->
 		if not (Hashtbl.mem processed md_path) then begin
 			Hashtbl.add processed md_path true;
-			con.modules <- { m_id = alloc_mid(); m_path = md_path; m_types = List.rev ( Hashtbl.find_all modules md_path ); m_extra = module_extra "" "" 0. MFake } :: con.modules
+			con.modules <- { m_id = alloc_mid(); m_path = md_path; m_types = List.rev ( Hashtbl.find_all modules md_path ); m_extra = (t_infos md).mt_module.m_extra } :: con.modules
 		end
 	) modules
 
@@ -915,16 +916,16 @@ let run_filters gen =
 
 let write_file gen w source_dir path extension =
 	let t = timer "write file" in
-	let s_path = gen.gcon.file ^ "/" ^	source_dir	^ "/" ^ (String.concat "/" (fst path)) ^ "/" ^ (snd path) ^ "." ^ (extension) in
+	let s_path = source_dir	^ "/" ^ (snd path) ^ "." ^ (extension) in
 	(* create the folders if they don't exist *)
 	let rec create acc = function
 		| [] -> ()
 		| d :: l ->
 				let dir = String.concat "/" (List.rev (d :: acc)) in
-				if not (Sys.file_exists dir) then Unix.mkdir dir 0o755;
+				if dir <> "" && not (Sys.file_exists dir) then Unix.mkdir dir 0o755;
 				create (d :: acc) l
 	in
-	let p = gen.gcon.file :: source_dir :: fst path in
+	let p = (String.nsplit source_dir "/") in
 	create [] p;
 
 	let contents = SourceWriter.contents w in
@@ -1045,32 +1046,77 @@ let dump_descriptor gen name path_s module_s =
 	output_string f contents;
 	close_out f
 
+let path_regex = Str.regexp "[/\\]+"
+
+let normalize path =
+	let rec normalize acc m = match m with
+		| [] ->
+			List.rev acc
+		| Str.Text "." :: Str.Delim _ :: tl when acc = [] ->
+			normalize [] tl
+		| Str.Text ".." :: Str.Delim _ :: tl -> (match acc with
+			| [] -> raise Exit
+			| _ :: acc -> normalize acc tl)
+		| Str.Text t :: Str.Delim _ :: tl ->
+			normalize (t :: acc) tl
+		| Str.Delim _ :: tl ->
+			normalize ("" :: acc) tl
+		| Str.Text t :: [] ->
+			List.rev (t :: acc)
+		| Str.Text _ :: Str.Text  _ :: _ -> assert false
+	in
+	String.concat "/" (normalize [] (Str.full_split path_regex path))
+
+let is_relative cwd rel =
+	try
+		let rel = normalize rel in
+		Filename.is_relative rel || (String.starts_with rel cwd || String.starts_with (Common.get_full_path rel) cwd)
+	with | Exit ->
+		String.starts_with rel cwd || String.starts_with (Common.get_full_path rel) cwd
+
 (*
 	helper function to create the source structure. Will send each module_def to the function passed.
 	If received true, it means that module_gen has generated this content, so the file must be saved.
 	See that it will write a whole module
 *)
 let generate_modules gen extension source_dir (module_gen : SourceWriter.source_writer->module_def->bool) =
+	let cwd = Common.get_full_path (Sys.getcwd()) in
 	List.iter (fun md_def ->
+		let source_dir =
+			if Common.defined gen.gcon Define.UnityStdTarget then
+				let file = md_def.m_extra.m_file in
+				let file = if file = "" then "." else file in
+				if is_relative cwd file then
+					let base_path = try
+							let last = Str.search_backward path_regex file (String.length file - 1) in
+							String.sub file 0 last
+						with | Not_found ->
+							"."
+					in
+					base_path ^ "/" ^ gen.gcon.file
+				else
+					Common.defined_value gen.gcon Define.UnityStdTarget ^ "/" ^ (String.concat "/" (fst md_def.m_path))
+			else
+				gen.gcon.file ^ "/" ^ source_dir ^ "/" ^ (String.concat "/" (fst md_def.m_path))
+		in
 		let w = SourceWriter.new_source_writer () in
 		(*let should_write = List.fold_left (fun should md -> module_gen w md or should) false md_def.m_types in*)
 		let should_write = module_gen w md_def in
 		if should_write then begin
 			let path = md_def.m_path in
 			write_file gen w source_dir path extension;
-
-
 		end
 	) gen.gcon.modules
 
 let generate_modules_t gen extension source_dir change_path (module_gen : SourceWriter.source_writer->module_type->bool) =
+	let source_dir = gen.gcon.file ^ "/" ^ source_dir in
 	List.iter (fun md ->
 		let w = SourceWriter.new_source_writer () in
 		(*let should_write = List.fold_left (fun should md -> module_gen w md or should) false md_def.m_types in*)
 		let should_write = module_gen w md in
 		if should_write then begin
 			let path = change_path (t_path md) in
-			write_file gen w source_dir path extension;
+			write_file gen w (source_dir ^ "/" ^ (String.concat "/" (fst path))) path extension;
 		end
 	) gen.gcon.types
 

+ 4 - 4
gencs.ml

@@ -2649,11 +2649,11 @@ let configure gen =
 	CSharpSpecificESynf.configure gen (CSharpSpecificESynf.traverse gen runtime_cl);
 
 	let mkdir dir = if not (Sys.file_exists dir) then Unix.mkdir dir 0o755 in
-	mkdir gen.gcon.file;
-	mkdir (gen.gcon.file ^ "/src");
 
 	(* copy resource files *)
 	if Hashtbl.length gen.gcon.resources > 0 then begin
+		mkdir gen.gcon.file;
+		mkdir (gen.gcon.file ^ "/src");
 		mkdir (gen.gcon.file ^ "/src/Resources");
 		Hashtbl.iter (fun name v ->
 			let full_path = gen.gcon.file ^ "/src/Resources/" ^ name in
@@ -2718,8 +2718,8 @@ let configure gen =
 
 	generate_modules gen "cs" "src" module_gen;
 
-	dump_descriptor gen ("hxcs_build.txt") path_s module_s;
-	if ( not (Common.defined gen.gcon Define.NoCompilation) ) then begin
+	if ( not (Common.defined gen.gcon Define.NoCompilation || Common.defined gen.gcon Define.UnityStdTarget) ) then begin
+		dump_descriptor gen ("hxcs_build.txt") path_s module_s;
 		let old_dir = Sys.getcwd() in
 		Sys.chdir gen.gcon.file;
 		let cmd = "haxelib run hxcs hxcs_build.txt --haxe-version " ^ (string_of_int gen.gcon.version) in